Исправление неоткалиброванных камер с помощью основной матрицы

Я пытаюсь выполнить калибровку камеры Kinect и внешней камеры с помощью Emgu/OpenCV. Я застрял, и я был бы очень признателен за любую помощь.

Я решил сделать это с помощью фундаментальной матрицы, то есть эпиполярной геометрии. Но результат не такой, как я ожидал. Результирующие изображения черные или вообще не имеют смысла. Точки Mapx и mapy обычно все равны бесконечным или - бесконечным, или все равны 0.00, и редко имеют обычные значения.

Вот как я пытался сделать исправление:

1.) Найти точки изображения получить два массива точек изображения (по одному для каждой камеры) из набора изображений. Я сделал это с помощью функции chessboard и FindChessboardCorners.

2.) Найти фундаментальную матрицу

 CvInvoke.cvFindFundamentalMat(points1Matrix, points2Matrix, 
_fundamentalMatrix.Ptr, CV_FM.CV_FM_RANSAC,1.0, 0.99, IntPtr.Zero);

Я передаю все собранные точки из всего набора изображений или только из двух изображений, пытающихся исправить?

3.) Найти матрицы гомографии

 CvInvoke.cvStereoRectifyUncalibrated(points11Matrix, points21Matrix, 
_fundamentalMatrix.Ptr, Size, h1.Ptr, h2.Ptr, threshold);

4.) Скачать mapx и mapy

double scale = 0.02;
CvInvoke.cvInvert(_M1.Ptr, _iM.Ptr, SOLVE_METHOD.CV_LU);

CvInvoke.cvMul(_H1.Ptr, _M1.Ptr, _R1.Ptr,scale);
CvInvoke.cvMul(_iM.Ptr, _R1.Ptr, _R1.Ptr, scale);
CvInvoke.cvInvert(_M2.Ptr, _iM.Ptr, SOLVE_METHOD.CV_LU);
CvInvoke.cvMul(_H2.Ptr, _M2.Ptr, _R2.Ptr, scale);
CvInvoke.cvMul(_iM.Ptr, _R2.Ptr, _R2.Ptr, scale);

CvInvoke.cvInitUndistortRectifyMap(_M1.Ptr,_D1.Ptr, _R1.Ptr, _M1.Ptr, 
mapxLeft.Ptr, mapyLeft.Ptr) ;

У меня есть проблема... поскольку я не использую калиброванные изображения, какова матрица моей камеры и коэффициенты искажения? Как я могу получить его из фундаментальной матрицы или матрицы гомографии?

5.) Переназначить

CvInvoke.cvRemap(src.Ptr, destRight.Ptr, mapxRight, mapyRight, 
(int)INTER.CV_INTER_LINEAR, new MCvScalar(255));

И это не дает хорошего результата. Я был бы признателен, если бы кто-нибудь сказал мне, что я делаю неправильно.

У меня есть набор из 25 пар изображений и размер шахматной доски 9x6.


person user1326511    schedule 17.04.2012    source источник


Ответы (2)


В книге «Learning OpenCV» издательства O'Reilly есть две полные главы, посвященные этой конкретной теме. Оба активно используют включенные в OpenCV подпрограммы cvCalibrateCamera2() и cvStereoCalibrate(); Эти подпрограммы являются оболочками для кода, который очень похож на то, что вы написали здесь, с дополнительным преимуществом, заключающимся в том, что они были более тщательно отлажены людьми, которые поддерживают библиотеки OpenCV. в то время как они удобны, оба требуют некоторой предварительной обработки для получения необходимых входных данных для подпрограмм. На самом деле может быть образец программы, где-то глубоко в каталоге примеров дистрибутива OpenCV, который использует эти процедуры, с примерами того, как перейти от изображения шахматной доски к матрице калибровки/внутренностей. Если вы внимательно изучите любое из этих мест, я уверен, вы увидите, как вы можете достичь своей цели с помощью советов экспертов.

person gankoji    schedule 15.07.2012

cv::findFundamentalMat не может работать, если внутренним параметром ваших точек изображения является единичная матрица. Другими словами, он не может работать с непроецируемыми точками изображения.

person Derza Arsad    schedule 04.08.2017