5

我正在尝试使用 Emgu/OpenCV 校准 Kinect 摄像头和外部摄像头。我被困住了,我真的很感激任何帮助。

我选择通过基本矩阵,即极线几何来做到这一点。但结果并不如我所料。结果图像是黑色的,或者根本没有意义。Mapx和mapy点通常都等于infinite或-infinite,或者都等于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。

4

2 回答 2

0

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

于 2012-07-15T19:08:22.930 回答
0

cv::findFundamentalMat如果图像点的内在参数是单位矩阵,则无法工作。换句话说,它不能处理未投影的图像点。

于 2017-08-04T21:47:09.247 回答