Перепроецирование пикселей из одного изображения в другое

У меня есть несколько калиброванных камер, делающих снимки плоской сцены. Для простоты предположим, что есть 3 камеры. Эти камеры совершают общее движение, но в основном поступательное движение плюс небольшое вращение. Примеры расположения камер

Задача состоит в том, чтобы сшить их целиком. Я ничего не знаю о 3D-координатах, просто набор изображений, сделанных откалиброванными камерами.

Что я делаю:

Я обнаруживаю функции с реализациями SURF/SIFT в OpenCV, чтобы получить начальные гомографии, используя findHomography между каждой парой изображений (1-> 2, 2-> 3, 1-> 3). Из этих гомографий я получаю начальную оценку поз каждой камеры (аналогичная процедура)

Затем я пытаюсь использовать метод корректировки пакетов, чтобы свести к минимуму ошибку повторного проецирования для каждой совпадающей пары. Оптимизированные параметры — это три значения смещения и три значения вращения (полученные из формулы вращения Родригеса), хотя позже я могу добавить внутренние параметры (фокусы, главные точки и т. д.).

Предполагая, что изображение № 2 будет опорным кадром (имея наибольшее количество совпадений с двумя другими изображениями), его матрицы поворота и перемещения являются тождественными и нулевыми матрицами соответственно.

Я рассчитываю репроекцию ключевой точки (видимой как на изображении № 2, так и на изображении № 1) с изображения № 2 на изображение № 1 как (псевдокод)

[x1_; y1_; z1_] = K1*R1*inv(K2)*[x2; y2; 1] + K1*T1/Z2;
x1 = x1_/z1_;
y1 = y1_/z1_;

or

x1 = ((f1/f2)*r11*x2 + (f1/f2)*r12*y2 + f1*r13 + f1*tx/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + tx/Z2)
y1 = ((f1/f2)*r21*x2 + (f1/f2)*r22*y2 + f1*r23 + f1*ty/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + ty/Z2)

где r__ — элементы матрицы R1, а обе внутренние матрицы имеют вид

[f 0 0]
[0 f 0]
[0 0 1]

Я предполагаю, что координата Z2 системы отсчета равна 1.

Следующим этапом является преобразование изображений №1 и №3 в общую систему координат изображения №2 с использованием полученных матриц камер (K1,R1,T1,K3,R3,T3).

Проблема в том, что я ничего не знаю о Z1 и Z3, необходимых для правильного перепроецирования в опорный кадр изображения №2, потому что обратное перепроецирование из изображения №1->№2 выглядит так:

x2 = ((f2/f1)*R11*x1 + (f2/f1)*R12*y1 + f2*R13 - f0/Z1*(R11*tx + R12*ty + R13*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))
y2 = ((f2/f1)*R21*x1 + (f2/f1)*R22*y1 + f2*R23 - f0/Z1*(R21*tx + R22*ty + R23*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))

где R__ — элементы матрицы inv(R1).

Есть ли лучший способ расчета ошибки перепроецирования для настройки пакета (2d-> 2d), а затем преобразования изображений в общую систему координат? Я заметил, что OpenCV имеет очень похожую структуру в своем модуле сшивания, но он работает в предположении чистого вращательного движения, что здесь не так.


person user2080818    schedule 05.03.2013    source источник
comment
Вы думали о трехмерной триангуляции? Например, вы можете триангулировать точку со всеми камерами, кроме одной, и перепроецировать ее на последнюю.   -  person cedrou    schedule 18.03.2013


Ответы (2)


Я автоматически ответил на этот вопрос в своем сообщении получить точки стереоизображения из внешних параметров

Обратите внимание, что метод, который я использую (протестирован и работает!), действителен только в том случае, если объект в 3D-координатах (реальный мир!) является плоским и находится на Z = 0 (точка, в которой вы откалибровали внешние параметры камер). В этом случае этот метод так же точен, как и ваша калибровка. Примечание: для лучшей калибровки круговой калибровки openCVs она имеет ошибку воспроизведения 0,018 пикселей (проверено аспирантом, работающим в моем университете).

person Ander Biguri    schedule 09.04.2013

Вероятно, вы обнаружили баг с ошибкой повторного проецирования. Это связано с этой строкой:

[x1_; y1_; z1_] = K1*R1*inv(K2)*[x2; y2; 1] + K1*T1/Z2;

Точка [x2; у2; 1] неоднозначен вплоть до постоянной масштаба C*[x2; у2; 1] и здесь вы устанавливаете C=1, когда это вообще неизвестно. Геометрическое место возможностей проявляется как эпиполярная линия в первом представлении. Вы можете использовать триангуляцию по методу наименьших квадратов, чтобы найти наиболее вероятную точку вдоль этой линии, где существует 3D-точка, а затем вычислить перепроецированную точку как:

[x1_; y1_; z1_] = K1*(R1*X + T1);

и действуйте оттуда, как указано выше. Трехмерные координаты каждой такой точки X в вашем облаке точек могут быть вычислены с использованием соответствующих нормализованных координат (x1, y1), (x2, y2),..., а также соответствующих матриц вращения и векторов переноса путем их форматирования. в матричной задаче:

A X = b

а затем решение наименьших квадратов:

min |A X - b|_2

который проиллюстрирован на страницах 3 и 4 здесь.

person willem    schedule 17.07.2013