Многокамерная калибровка с opencv: две камеры обращены друг к другу

Я хочу вычислить внешнюю калибровку двух камер относительно друг друга и использую для этого функцию cv::stereoCalibrate(). Однако результат не соответствует действительности. Что может быть не так?

Установка: две камеры, установленные на высоте 7 метров, обращенные друг к другу и смотрящие вниз. У них много пересечений полей зрения, и я сделал снимки шахматной доски, которые использовал при калибровке.

Я не переворачиваю ни одно из изображений.

Нужно ли переворачивать изображения? или мне нужно сделать что-то еще, чтобы сказать, что камеры на самом деле обращены друг к другу?

Примечание. Эта же функция отлично калибрует камеры, расположенные рядом друг с другом и смотрящие в одном направлении (как любая обычная стереокамера).

Спасибо


person user3755683    schedule 31.01.2017    source источник
comment
Сколько изображений вы использовали для калибровки? Достаточно ли у них вариаций вращения?   -  person hiroki    schedule 01.02.2017
comment
Я использую 50 изображений с приличным вращением и наклоном.   -  person user3755683    schedule 01.02.2017
comment
Что бы я сделал: откалибровал каждую камеру независимо, используя cv::calibrateCamera(). Оцените трансформацию между кадрами двух камер после того, как они были окончательно зафиксированы: для каждой камеры виден шахматный узор + cv::solvePnP(). Преобразование c1Mc2 можно оценить как c1Mo x (c2Mo)^-1.   -  person Catree    schedule 01.02.2017
comment
Спасибо. Не могли бы вы уточнить, что такое c1, c2 и Mo. Я предполагаю, что c1 и c2 — это центры камеры, а Mo — трансформация? solvePnP() производит вращение и перевод по отношению к каждой камерой для каждого изображения узора. Например, для данного шаблона, скажем, мы получаем R1, T1 (для первой камеры) и R2, T2 (для второй камеры) через функцию solvePnP(). Как мы можем вычислить Mo из этих пар вращения-перемещения?   -  person user3755683    schedule 02.02.2017
comment
Обозначение c1Mo соответствует однородному преобразованию между кадром объекта и кадром camera1: матрица 4x4 с (R | T). Вам нужно будет создать c1Mo, так как R1 — это вектор вращения Родригеса, но в основном c1Mo — это то же самое, что R1, T1, просто другое обозначение.   -  person Catree    schedule 02.02.2017
comment
Также обратите внимание, что (c2Mo)^-1 является обратной матрицей, но ее проще вычислить как (стр. 72): www-lar.deis.unibo.it/people/cmelchiorri/Files_Robotica/   -  person Catree    schedule 02.02.2017
comment
Применил это преобразование. Результат, который я получил, был очень похож на тот, что я получил с cv::stereoCalibrate(). Результат не совсем соответствует действительности, особенно по координате z перевода. Есть ли что-то очевидное, что я упускаю? Спасибо   -  person user3755683    schedule 03.02.2017


Ответы (1)


Чтобы «сказать, что камеры на самом деле обращены друг к другу», вы должны правильно указать imagePoints1 и imagePoints2, чтобы точки с совпадающими индексами соответствовали одной и той же физической точке.

Если в вашем случае функция работает идеально, когда камеры ориентированы в одном направлении, и не работает с вашей конфигурацией - вероятной причиной может быть несоответствие индексации точек (скорее всего, точки перевернуты как по вертикали, так и по горизонтали).

Один из способов отладки — либо нарисовать индексы рядом с точками на каждом из кадров, либо закодировать их цветом и убедиться, что они совпадают между изображениями.

Однако один вопрос - почему вы используете cv::stereoCalibrate()? Описанная вами настройка, похоже, не подходит для этого. Если вы хотите оценить внешние параметры камер, вы можете использовать cv::calibrateCamera(). Единственным недостатком является то, что он предполагает, что внутренние параметры одинаковы для всех предоставленных видов (все изображения были сделаны одинаковыми или очень похожими камерами). Если это не так - действительно, cv::stereoCalibrate() подойдет лучше (но в руководстве предлагается все же оценивать внутренние параметры каждой камеры индивидуально, используя cv::calibrateCamera())

person alexisrozhkov    schedule 01.02.2017
comment
Я проверил точки, и точки соответствия выглядят хорошо. Это не предполагает необходимости перелистывания. Я хотел бы найти вращение и перевод между первой и второй камерами, которые обеспечивает cv::stereoCalibrate(). И да, я использую cv::calibrateCamera() для калибровки отдельных камер и предоставляю матрицы камер cv::stereoCalibrate(). Как вы предлагаете мне использовать результаты cv::calibrateCamera(), чтобы найти преобразование между камерами? - person user3755683; 01.02.2017
comment
В значительной степени в соответствии с документом - objectPoints будет вектором векторов трехмерных координат точки маркера, imagePoints будет вектором векторов обнаруженных двухмерных координат точки, rvecs и tvecs будут содержать внешние элементы для каждого вида (поворот и перевод). Если можете - предоставьте образцы изображений с показанными соответствиями - это поможет прояснить ситуацию. - person alexisrozhkov; 02.02.2017