通过基本矩阵校正未校准的摄像机

时间:2012-04-17 13:49:49

标签: image-processing opencv emgucv camera-calibration

我正在尝试使用Emgu / OpenCV对Kinect相机和外部相机进行校准。 我被困住了,我真的很感激任何帮助。

我选择通过基本矩阵,即极线几何来做到这一点。 但结果并不像我预期的那样。结果图像是黑色的,或根本没有任何意义。 Mapx和mapy点通常都等于无限或 - 无限,或者全部等于0.00,并且很少有常规值。

这就是我试图纠正的方法:

1。)查找图像点从图像集中获取两个图像点阵列(每个摄像头一个)。我用棋盘和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。

2 个答案:

答案 0 :(得分:0)

O'Reilly出版的“学习OpenCV”一书有两章专门讨论这一特定主题。两者都大量使用OpenCV包含的例程cvCalibrateCamera2()和cvStereoCalibrate();这些例程是代码的包装器,与您在此处编写的代码非常相似,并且还有一些额外的好处,即由维护OpenCV库的人员进行了更彻底的调试。虽然它们很方便,但都需要进行相当多的预处理才能实现对例程的必要输入。实际上可能有一个示例程序,在OpenCV发行版的samples目录深处,使用这些例程,以及如何从棋盘图像到校准/内在函数矩阵的示例。如果你深入了解这些地方,我相信你会看到如何通过专家的建议实现你的目标。

答案 1 :(得分:0)

如果图像点的内部参数是单位矩阵,则pv :: findFundamentalMat无法工作,换句话说,它无法与未投影的图像点一起使用