3D Reconstruction from Photos (Photogrammetry)

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
3D Reconstruction from Photos (Photogrammetry)
Complex
~1-2 weeks
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    848

System Development 3D-реконструкции по фотографиям (Photogrammetry)

Фотограмметрия — реконструкция трёхмерной геометрии объекта по серии перекрывающихся фотографий с разных ракурсов. Результат: плотное 3D облако точек, mesh (полигональная сетка), текстурированная 3D модель. Applications: цифровые двойники объектов, архитектурная документация, судебная криминалистика, 3D-активы для игр и кино.

SfM + MVS пайплайн

Классический photogrammetry пайплайн состоит из двух этапов:

SfM (Structure from Motion): определение положения камер и разреженного облака точек по ключевым точкам (SIFT, SuperPoint):

import pycolmap
from pathlib import Path

def run_sfm_reconstruction(images_dir: str,
                            output_dir: str) -> dict:
    """Полный SfM пайплайн через COLMAP"""
    image_path = Path(images_dir)
    output_path = Path(output_dir)
    output_path.mkdir(exist_ok=True)

    database_path = output_path / 'database.db'

    # Извлечение признаков
    pycolmap.extract_features(database_path, image_path,
                               sift_options={'max_num_features': 8192})

    # Сопоставление признаков
    pycolmap.match_exhaustive(database_path)

    # Инкрементальная реконструкция
    maps = pycolmap.incremental_mapping(
        database_path=database_path,
        image_path=image_path,
        output_path=output_path
    )

    reconstruction = maps[0]  # largest map
    return {
        'num_cameras': len(reconstruction.cameras),
        'num_images': len(reconstruction.images),
        'num_3d_points': len(reconstruction.points3D)
    }

MVS (Multi-View Stereo): плотное облако точек по позициям камер из SfM. OpenMVS или COLMAP dense:

import subprocess

def run_dense_reconstruction(sfm_output: str, output_dir: str):
    """Плотная реконструкция через OpenMVS"""
    # Конвертация COLMAP → OpenMVS формат
    subprocess.run([
        'InterfaceCOLMAP',
        '-i', sfm_output,
        '-o', f'{output_dir}/scene.mvs'
    ], check=True)

    # Плотная реконструкция
    subprocess.run([
        'DensifyPointCloud',
        '-i', f'{output_dir}/scene.mvs',
        '--resolution-level', '1',
        '--number-views', '5'
    ], check=True)

    # Построение mesh
    subprocess.run([
        'ReconstructMesh',
        '-i', f'{output_dir}/scene_dense.mvs',
        '--quality', '3'
    ], check=True)

    # Текстурирование
    subprocess.run([
        'TextureMesh',
        '-i', f'{output_dir}/scene_dense_mesh.mvs'
    ], check=True)

Open3D для обработки облаков точек

import open3d as o3d
import numpy as np

def process_point_cloud(pcd_path: str) -> dict:
    pcd = o3d.io.read_point_cloud(pcd_path)

    # Удаление выбросов
    pcd_clean, _ = pcd.remove_statistical_outlier(nb_neighbors=20,
                                                    std_ratio=2.0)

    # Нормализация
    pcd_clean.estimate_normals(
        o3d.geometry.KDTreeSearchParamHybrid(radius=0.05, max_nn=30)
    )

    # Poisson Surface Reconstruction
    mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
        pcd_clean, depth=9
    )

    # Удаление низкоплотных вершин (края)
    density_threshold = np.quantile(densities, 0.05)
    mesh = mesh.select_by_index(np.where(densities > density_threshold)[0])

    return {
        'num_vertices': len(mesh.vertices),
        'num_triangles': len(mesh.triangles),
        'bounding_box': mesh.get_axis_aligned_bounding_box()
    }

Требования к фотографиям

Качество реконструкции напрямую зависит от качества входных фото:

Параметр Рекомендация
Перекрытие кадров 70–80%
Минимальное количество фото 30–50
Оптимальное количество 100–300
Угол между снимками 15–30°
Освещение Равномерное, без резких теней
Разрешение 12 MP+
Глубина резкости Максимальная (f/8–f/16)

Точность и время обработки

Метод Точность (мм) Время (100 фото, CPU)
COLMAP + OpenMVS 1–3 30–120 мин
Meshroom (AliceVision) 1–5 45–90 мин
Reality Capture 0.5–2 15–30 мин
Metashape (Agisoft) 0.5–2 20–60 мин

Applications и выходные форматы

Поддерживаемые форматы: PLY, OBJ+MTL, FBX, GLTF/GLB, USD. Integration с: Blender, Unity, Unreal Engine, Autodesk, trimble.

Применение Срок проекта
Пайплайн обработки фотосессий 3–5 недель
Автоматическая фотостудия с роботом 8–14 недель
Система для инспекции/документации 6–10 недель