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

Image processing 通过基本矩阵校正未校准摄像机,image-processing,opencv,emgucv,camera-calibration,Image Processing,Opencv,Emgucv,Camera Calibration,我正在尝试使用Emgu/OpenCV对Kinect摄像机和外部摄像机进行校准。 我被困住了,我真的很感激任何帮助 我选择通过基本矩阵,即极线几何来实现这一点。 但结果并不像我预期的那样。结果图像是黑色的,或者根本没有意义。 Mapx和mapy点通常都等于无穷大或-无穷大,或都等于0.00,很少有规则值 这就是我试图纠正的方式: 1.查找图像点从图像集中获取两个图像点阵列(每个摄像头一个)。我用棋盘和FindChessboardCorners函数完成了这项工作 2.查找基本矩阵 CvInvoke

我正在尝试使用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);
 CvInvoke.cvStereoRectifyUncalibrated(points11Matrix, points21Matrix, 
_fundamentalMatrix.Ptr, Size, h1.Ptr, h2.Ptr, threshold);
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) ;
我是通过整个图像集收集的所有点,还是仅通过两个试图校正的图像

3.查找单应矩阵

 CvInvoke.cvFindFundamentalMat(points1Matrix, points2Matrix, 
_fundamentalMatrix.Ptr, CV_FM.CV_FM_RANSAC,1.0, 0.99, IntPtr.Zero);
 CvInvoke.cvStereoRectifyUncalibrated(points11Matrix, points21Matrix, 
_fundamentalMatrix.Ptr, Size, h1.Ptr, h2.Ptr, threshold);
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) ;
4.获取mapx和mapy

 CvInvoke.cvFindFundamentalMat(points1Matrix, points2Matrix, 
_fundamentalMatrix.Ptr, CV_FM.CV_FM_RANSAC,1.0, 0.99, IntPtr.Zero);
 CvInvoke.cvStereoRectifyUncalibrated(points11Matrix, points21Matrix, 
_fundamentalMatrix.Ptr, Size, h1.Ptr, h2.Ptr, threshold);
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

O'Reilly出版社出版的《学习OpenCV》一书有两个完整的章节专门讨论这一特定主题。两者都大量使用OpenCV包含的例程CVcalibleCamera2()和cvStereoCalibrate();这些例程是代码的包装,与您在这里编写的非常相似,还有一个额外的好处,就是维护OpenCV库的人员已经对其进行了更彻底的调试。虽然它们很方便,但都需要相当多的预处理来实现对例程的必要输入。事实上,在OpenCV发行版的samples目录的深处可能有一个示例程序,它使用这些例程,并提供了如何从棋盘图像到校准/本质矩阵的示例。如果你深入研究其中任何一个地方,我相信你会看到如何在专家的建议下实现你的目标

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