Перейти к основному содержанию
EDU-MMCS
Вы используете гостевой доступ (Вход)

Компьютерное зрение

  1. В начало
  2. Курсы
  3. Осенний семестр
  4. Магистратура
  5. КЗ
  6. 13 декабря - 19 декабря
  7. Лабораторная работа 8. Основы фотограмметрии

Лабораторная работа 8. Основы фотограмметрии

Требуемые условия завершения
Открыто с: вторник, 16 декабря 2025, 00:00
Срок сдачи: вторник, 30 декабря 2025, 20:00

Лабораторная работа: Построение 3D-модели по фотографиям (Structure-from-Motion)

Цель: Реализовать инкрементальный алгоритм SfM (Structure-from-Motion) на Python.

Формат: Google Colab / Jupyter Notebook.

Входные данные: Серия из 15–40 фотографий объекта.

Результат: 3D-меш объекта в формате .obj или .ply.


1. Теоретическое введение

Алгоритм Structure-from-Motion (SfM) позволяет восстановить трехмерную структуру сцены по набору двумерных изображений. Процесс состоит из двух этапов:

  1. Инициализация: Восстановление 3D-точек из первой пары изображений (стерео-пара).

  2. Инкрементальное расширение: Добавление новых камер по одной, используя уже найденные 3D-точки для определения положения новой камеры.

В этой работе вам предоставлен код для этапа 1. Ваша задача — реализовать этап 2 (цикл добавления камер) и финальное построение поверхности.


2. Подготовка данных

Сделайте 5–10 фотографий объекта (стул, коробка, статуя) со всех сторон.

  • Важно: Объект должен быть текстурным (не белая стена, не стекло).

  • Важно: Между соседними кадрами должно быть перекрытие ~60-70%.

  • Загрузите фото в папку data/ в вашем проекте.


3. Часть 1: Инициализация (Демонстрация)

Вставьте этот код в ноутбук. Он реализует реконструкцию для первых двух изображений. Разберитесь, как он работает.

Установка библиотек:

!pip install opencv-python opencv-contrib-python open3d plotly

Базовый код (2 изображения):

import cv2
import numpy as np
import open3d as o3d

# --- 1. Настройки ---
# Аппроксимация матрицы камеры K (если нет калибровки)
def get_K(img):
    h, w = img.shape[:2]
    f = 1.2 * max(w, h) # Эвристика для смартфонов
    K = np.array([[f, 0, w/2], [0, f, h/2], [0, 0, 1]])
    return K

# --- 2. Загрузка первых двух фото ---
img1 = cv2.imread('data/img1.jpg')
img2 = cv2.imread('data/img2.jpg')
K = get_K(img1)

# --- 3. Поиск соответствий (SIFT) ---
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# Сопоставление
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

# Фильтрация Lowe's ratio test
good = []
pts1 = []
pts2 = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good.append(m)
        pts1.append(kp1[m.queryIdx].pt)
        pts2.append(kp2[m.trainIdx].pt)

pts1 = np.float32(pts1)
pts2 = np.float32(pts2)

# --- 4. Геометрия двух видов ---
# Находим Essential Matrix и позу второй камеры
E, mask = cv2.findEssentialMat(pts1, pts2, K, method=cv2.RANSAC, prob=0.999, threshold=1.0)
pts1 = pts1[mask.ravel() == 1]
pts2 = pts2[mask.ravel() == 1]

# recoverPose возвращает R и t для второй камеры (первая в 0,0,0)
_, R, t, mask = cv2.recoverPose(E, pts1, pts2, K)

# --- 5. Триангуляция ---
# Матрицы проекции: P = K *
P1 = K @ np.hstack((np.eye(3), np.zeros((3, 1))))
P2 = K @ np.hstack((R, t))

# Триангулируем точки
points4D = cv2.triangulatePoints(P1, P2, pts1.T, pts2.T)
points3D = (points4D[:3] / points4D[1]).T # Нормализация

print(f"Инициализация завершена. Восстановлено {len(points3D)} точек.")

4. Часть 2: Инкрементальное добавление (Основное задание)

На данный момент у вас есть облако точек от двух камер. Однако для модели стула двух ракурсов недостаточно. Вам нужно написать цикл, который обработает оставшиеся изображения (3, 4, 5...).

Алгоритм действий (реализуйте это в коде):

  1. Загрузите следующее изображение (img3).

  2. Найдите ключевые точки на img3 и сопоставьте их с точками img2.

  3. Ключевой момент (PnP):

    У вас есть связи: Точки 3D (из шага 5) <-> Точки 2D на img2 <-> Точки 2D на img3.

    Вам нужно найти набор пар: {Существующая 3D точка} — {Ее проекция на img3}.

  4. Используйте функцию cv2.solvePnPRansac для найденных пар.

    • Вход: список 3D точек и список их 2D проекций на новом кадре.

    • Выход: Поза новой камеры ($R_{new}, t_{new}$).

  5. Триангуляция новых точек:

    Используя новую позу P_new и позу предыдущей камеры P_old, триангулируйте те точки, которые появились на новом кадре, но еще не были в 3D облаке.

  6. Добавьте новые точки в общий массив points3D.

  7. Повторите для всех оставшихся фото.

Подсказка по PnP:

$$\text{cv2.solvePnPRansac}( \text{objectPoints}, \text{imagePoints}, K, \text{distCoeffs} )$$

5. Часть 3: Построение поверхности (Meshing)

В результате Части 2 вы получите разреженное облако точек. Чтобы превратить его в модель для Блендера, нужно "натянуть" на него сетку.

Используйте библиотеку Open3D и метод Alpha Shapes. Это простой способ создать геометрию из точек.

import open3d as o3d

# 1. Создаем объект облака точек Open3D
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points3D) # Ваше итоговое облако

# 2. Очистка от шума (опционально)
cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
pcd = pcd.select_by_index(ind)

# 3. Создание меша (Alpha shapes)
# alpha - параметр "плотности" обтягивания. Поэкспериментируйте (напр. 0.1, 0.5, 1.0)
alpha = 0.1 
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha)
mesh.compute_vertex_normals()

# 4. Сохранение
o3d.io.write_triangle_mesh("chair_model.obj", mesh)
print("Модель сохранена как chair_model.obj")

Требования к отчету

  1. Код: Ссылка на Colab ноутбук с работающим циклом обработки N изображений.

  2. Скриншоты:

    • Визуализация облака точек после 2-х фото.

    • Визуализация финального облака точек (после всех фото).

    • Скриншот полученного меша (.obj), открытого в стандартном 3D-просмотрщике Windows/Mac или в Blender.

  3. Анализ:

    • Как меняется количество точек при добавлении новых кадров?

    • Почему параметр alpha при создании меша сильно влияет на результат? (Что происходит, если alpha слишком большой или слишком маленький?)


◄ Обзор нейронок для CV. Часть 3
Лекция 12 ►
Пропустить Навигация
Навигация
  • В начало

    • Страницы сайта

      • Мои курсы

      • Теги

    • Мои курсы

    • Курсы

      • Осенний семестр

        • Прикладная математика и информатика

        • Фундаментальная информатика и ИТ

        • Математика, механика

        • Педагогическое образование

        • Магистратура

          • Разработка мобильных приложений и компьютерных игр

          • MDA

          • DS & ИАД 2025

          • ТОИ маг

          • Modern computer technology

          • ТОИ магистры

          • Математика и её приложения в науке и инженерии

          • MUDP

          • ОНС-Н

          • RL

          • ИИ_НС

          • КрПр

          • КЗ

            • Общее

            • 6 сентября - 12 сентября

            • 13 сентября - 19 сентября

            • 20 сентября - 26 сентября

            • 27 сентября - 3 октября

            • 4 октября - 10 октября

            • 11 октября - 17 октября

            • 18 октября - 24 октября

            • 25 октября - 31 октября

            • 1 ноября - 7 ноября

            • 8 ноября - 14 ноября

            • 15 ноября - 21 ноября

            • 22 ноября - 28 ноября

            • 13 декабря - 19 декабря

              • ЗаданиеЛабораторная работа 8. Основы фотограмметрии

              • ФайлЛекция 12

              • ФайлЛекция 11. Распознавание лиц

        • Аспирантура

        • Вечернее отделение

        • Другое

        • Экзамен ИКТ

        • ТестИИ

        • Информатика-Осень-ПМИ-2

        • Информатика-осень-ПМИ-1

        • ИММвс

      • Весенний семестр

        • Прикладная математика и информатика

        • Фундаментальная информатика и ИТ

        • Математика, механика

        • Педагогическое образование

        • Магистратура

          • Разработка мобильных приложений и компьютерных игр

        • Аспирантура

        • Вечернее отделение

        • Другое

      • Воскресная компьютерная школа

        • Пользователь компьютера плюс

        • Пользователь прикладных программ

        • Программирование I ступень

        • Программирование II ступень

        • Программирование III ступень

        • Архив

      • Воскресная математическая школа

        • Открытое тестирование РНОМЦ и мехмата ЮФУ - 2025

        • Олимпиадная математическая школа

        • Повышение квалификации

        • Доступная математика

        • Лаборатория математического онлайн-образования мех...

        • Осенняя универсиада

        • Научно-практическая конференция

        • ВМШ

          • ВМШ -2025

        • Летняя олимпиадная математическая школа РНОМЦ и ме...

      • Государственная итоговая аттестация

      • Дополнительное образование

      • Олимпиады

      • Видеолекции

      • Разное

      • Архив курсов

      • Заочная школа мехмата ЮФУ

Вы используете гостевой доступ (Вход)
КЗ
Сводка хранения данных
Скачать мобильное приложение Яндекс.Метрика