(1)提取特征点并匹配,参考http://blog.sina.com.cn/s/blog_4298002e01013w4z.html
(2)计算基本矩阵F,参考http://blog.sina.com.cn/s/blog_4298002e01013w9a.html
(3)极线矫正。
//! computes the rectification transformation for an uncalibrated stereo camera (zero distortion is assumed)
CV_EXPORTS_W bool stereoRectifyUncalibrate
该函数输入参数为两幅图像的匹配特征点,基本矩阵F以及图像的尺寸,返回的参数是两幅图像各自对应的单应变换矩阵H1和H2。只需要对两幅图像按照H1和H2做单应变换,即可得到矫正后图像。假设I为图像,变换如下:
I_recty = H*I
// 假设前面我们已经得到两幅图像的匹配特征点,并计算出了基本矩阵F,同时得到了匹配特征点的inlier
// Mat m_matLeftImage;
//
// vector<Point2f> m_LeftInlier;
//
// Mat m_Fundamental;
// 计算图像矫正的单应变换矩阵
Mat m_LeftH;
Mat m_RightH;
stereoRectifyUncalibrate
// 任意指定一个内参数矩阵K,不会影响计算结果,此处设为单位阵。
Mat K = Mat::eye(3, 3, CV_64F); // 注意一定是double类型
Mat invK = K.inv(DECOMP_SVD);
Mat LeftR = invK*m_LeftH*K;
Mat RightR = invK*m_RightH*K;
Mat LeftMap1, LeftMap2;
Mat RightMap1, RightMap2;
Mat Distort;
Size UndistSize(m_matLeftImage.cols, m_matLeftImage.rows);
// 计算左右两幅图像的映射矩阵
initUndistortRectifyMap(K, Distort, LeftR, K, UndistSize, CV_32FC1, LeftMap1, LeftMap2);
initUndistortRectifyMap(K, Distort, RightR, K, UndistSize, CV_32FC1, RightMap1, RightMap2);
// 把原始图像投影到新图像上,得到矫正图像
Mat m_LeftRectyImage;
Mat m_RightRectyImage;
remap(m_matLeftImage, m_LeftRectyImage, LeftMap1, LeftMap2, INTER_LINEAR);
remap(m_matRightImage, m_RightRectyImage, RightMap1, RightMap2, INTER_LINEAR);
// 显示结果
cvNamedWindow( "left image", 1);
cvShowImage("left image", &(IplImage(m_LeftRectyImage)));
cvNamedWindow( "right image", 1);
cvShowImage("right image", &(IplImage(m_RightRectyImage)));
cvWaitKey( 0 );
cvDestroyWindow( "left image" );
cvDestroyWindow( "right image" );
程序计算的结果如下图所示:
原始图像对:
极线矫正后的图像:
SGBM算法: