Epipolar Geometry
Эпиполярная геометрия связывает два ракурса сцены: точке на одном изображении соответствует линия поиска совпадения на другом. Это основа стереоскопической оценки глубины и построения 3D-карт.
В компьютерном зрении эпиполярная геометрия описывает геометрическую связь между двумя изображениями одной и той же сцены, полученными с разных ракурсов. Пикселю на одном изображении соответствует луч возможных точек в 3D-пространстве, а при проецировании на второе изображение этот луч отображается в виде прямой — эпиполярной линии, на которой должен находиться соответствующий пиксель. Это ограничение зависит только от внутренних параметров камер и их взаимного положения и ориентации, а не от структуры сцены, и превращает поиск соответствия по всему изображению в поиск вдоль одной линии. Поэтому эпиполярная геометрия лежит в основе стереозрения, восстановления структуры по движению и визуального SLAM, который помогает роботам и гарнитурам ориентироваться. Книга Ричарда Хартли и Эндрю Циссермана «Многовидовая геометрия в компьютерном зрении» — стандартный справочник.
Эпиполюсы, эпиполярные линии и эпиполярная плоскость#
Центры двух камер и любая точка сцены задают плоскость — эпиполярную плоскость. Прямая, соединяющая центры камер, называется базовой линией; она пересекает каждую плоскость изображения в эпиполюсе — изображении центра другой камеры, который может оказаться за пределами кадра или на бесконечности. Каждая эпиполярная плоскость пересекает каждое изображение по эпиполярной линии, поэтому все эпиполярные линии изображения проходят через его эпиполюс. Когда точка сцены перемещается вдоль луча зрения первой камеры, её проекция на втором изображении движется вдоль эпиполярной линии.
Фундаментальная и эссенциальная матрицы#
Фундаментальная матрица F размером 3 × 3 и ранга два описывает всю связь в пиксельных координатах. Для соответствующих точек x и x′, записанных в однородной форме (x, y, 1), эпиполярное ограничение имеет вид x′ᵀ F x = 0, а произведение F x задаёт коэффициенты эпиполярной линии точки x на втором изображении. Если камеры откалиброваны с помощью калибровки камер, эссенциальная матрица E = K′ᵀ F K выражает то же ограничение в нормализованных координатах и раскладывается на относительный поворот R и перенос t: E = [t]ₓ R. Кристофер Лонге-Хиггинс ввёл эссенциальную матрицу и восьмиточечный алгоритм в 1981 году, а Оливье Фужера, Куанг-Туан Лыонг и Ричард Хартли разработали фундаментальную матрицу для некалиброванных камер в начале 1990-х. Поскольку E задаёт только направление t, по двум ракурсам можно восстановить форму сцены лишь с точностью до неизвестного масштаба; масштаб определяется известной базовой линией или размером объекта.
Обе матрицы оцениваются по соответствующим ключевым точкам, например признакам SIFT, с помощью робастного оценивателя, такого как RANSAC. Он многократно подбирает матрицу по минимальной выборке соответствий и выбирает модель, с которой согласуется больше всего точек. В этом примере создаются два ракурса со 100 точками, 20 соответствий заменяются случайными ошибочными соответствиями, а матрица F оценивается с помощью варианта RANSAC MAGSAC из OpenCV:
import cv2
import numpy as np
rng = np.random.default_rng(0)
K = np.array([[800.0, 0, 320], [0, 800.0, 240], [0, 0, 1]]) # intrinsics shared by both cameras
# 100 scene points seen by two cameras; the second sits 0.5 m to the right, turned 5 degrees
points = rng.uniform([-2, -1, 4], [2, 1, 8], (100, 3))
rvec = np.array([0.0, np.radians(5), 0.0])
tvec = -cv2.Rodrigues(rvec)[0] @ np.array([0.5, 0.0, 0.0])
x1 = cv2.projectPoints(points, np.zeros(3), np.zeros(3), K, None)[0].reshape(-1, 2) + rng.normal(0, 0.5, (100, 2))
x2 = cv2.projectPoints(points, rvec, tvec, K, None)[0].reshape(-1, 2) + rng.normal(0, 0.5, (100, 2))
x2[:20] = rng.uniform([0, 0], [640, 480], (20, 2)) # replace 20 matches with wrong ones
# Robust estimation keeps the matches that agree with a single fundamental matrix
F, inliers = cv2.findFundamentalMat(x1, x2, cv2.USAC_MAGSAC, 1.0)
kept = inliers.ravel() == 1
print(f"Kept {kept[20:].sum()} of 80 true matches and {kept[:20].sum()} of 20 wrong ones")
# Each point in image 1 defines a line a*x + b*y + c = 0 in image 2 that its match must lie on
lines = cv2.computeCorrespondEpilines(x1, 1, F).reshape(-1, 3)
dist = np.abs((lines[:, :2] * x2).sum(axis=1) + lines[:, 2])
print(f"Median distance to epipolar line: {np.median(dist[20:]):.2f} px (true), {np.median(dist[:20]):.0f} px (wrong)")
print(f"Wrong match that survived: {dist[:20][kept[:20]].round(2)} px from its line")Алгоритм сохраняет 75 из 80 правильных соответствий и отбрасывает 19 из 20 ошибочных. Медианное расстояние правильных соответствий до эпиполярных линий составляет 0,43 пикселя и определяется шумом в полпикселя; для ошибочных соответствий оно составляет 144 пикселя. Одно ошибочное соответствие, прошедшее проверку, случайно оказалось в 0,61 пикселя от своей линии: ограничение привязывает соответствующую точку к линии, но только визуальные признаки позволяют выбрать на ней правильную точку.
При чистом вращении базовой линии нет, а для одной плоскости одинаково хорошо подходят многие фундаментальные матрицы. В обоих случаях используют гомографию — матрицу 3 × 3, которая отображает один ракурс плоскости в другой. ORB-SLAM инициализирует карту, параллельно подбирая гомографию и фундаментальную матрицу, а затем оставляет ту, которая лучше объясняет соответствия.
Выпрямление изображений, диспаритет и глубина#
Выпрямление преобразует стереопару так, чтобы эпиполярные линии стали горизонтальными и выровненными, а все соответствующие точки оказались в одной строке изображения. Затем алгоритмы стереосопоставления ищут соответствия вдоль каждой строки, а смещение между столбцами соответствующих точек — диспаритет d — позволяет вычислить глубину Z = f × B / d, где f — фокусное расстояние, а B — базовая линия. Так стереосистемы строят карты оценки глубины. В стереобенчмарке KITTI такие алгоритмы оцениваются на выпрямленных сценах из задач автономного вождения.
Применение за пределами стереозрения#
При 3D-реконструкции COLMAP проверяет каждую пару изображений, подбирая фундаментальные, эссенциальные матрицы или гомографии, и отбрасывает пары и соответствия без достаточной геометрической поддержки. В конвейерах сопоставления изображений та же проверка помогает отсеивать ложные соответствия, а регистрация изображений использует описанную выше гомографию, если сцена плоская или камера только вращается, например при склейке панорам. Между кадрами движущейся камеры эпиполярное ограничение выполняется только для статичных поверхностей, поэтому векторы оптического потока, которые ему не соответствуют, указывают на независимо движущиеся объекты. При съёмке позы человека несколькими камерами одного и того же человека сопоставляют между ракурсами по тому, насколько близко его суставы располагаются к эпиполярным линиям друг друга, а затем триангулируют 3D-скелет. Для каждого ракурса модель Ultralytics YOLO26 для оценки позы определяет 17 ключевых точек тела COCO на человека.










