/**************************************************************** 转自:http://www./article/p-656561.html ***************************************************************/ 从上一篇文章,我们知道cvStereoRectify()函数只是计算了校正需要的参数,并没有完成图像上实际的校正。 在本节将介绍两个函数: cvInitUndistortRectifyMap()函数来计算左右视图的校正查找映射表mapx,mapy。 cvRemap()函数利用查找映射表和插值算法实现将输入图像的重投影,从而得到校正后图像。 为了理解下面的话,我们将书上图附上:
图12-11:立体校正。对左右摄像机而言,(a)原始图像(b)非畸变化(c)校正(d)最后裁切成两幅图像间的重叠区域。校正实际上是右(c)到(a)的反过程。 对任何图像到图像的映射函数,由于目标位置是浮点型的缘故,正向映射(即根据原始图像上的点计算其到目标图像上的点),不会命中目标图像对应的像素位置。 为了理解上面的话,我们引入OpenCV中cvRemap函数中的解释: 例如,我们可以说像素的位于(20,17)位置,当这些整数位置映射到新的图像中,可能会有一些差异——源图像中像素中的像素位置是整形的而目标图像是浮点型的,就必须将其四舍五入到最相近的整型,因为可能映射后的位置完全就是没有像素的(联想一下通过拉伸图像扩大两倍,其他的每个目标像素将是空白)。这个问题一般被称为正向投影问题。为了解决这些四舍五入和目标差异的问题,实际上我们可以反过来解决:通过目标图像中的每一个像素去问:“哪个像素需要来填充这个目标像素?“这些源像素的位置几乎都是小数(非整数),所以必须对这些像素进行插值以得到目标位置的正确值。
因此我们采用逆向映射:对目标图像上的每一个整形的像素位置,首先查找出其对应源图像上的浮点位置,然后利用周围源像素的每个整形值插值出新的值来。
计算这样映射关系的实现函数cvInitUndistortRectifyMap()被调用两次,即分别求解左右原始图像到校正图像之间的映射查找表,声明如下:
2、disCoeffs,是5×1的摄像机畸变系数。 3、Rrect,是cvStereoRecify()函数输出的Rl或者Rr 4、Mrect是3×3的校正后的摄像机内参数矩阵,该矩阵是cvStereoRectify()计算得到投影矩阵P的前三列。 5、mapx,mapy,是函数返回的输出查找映射表。 (个人对查找表的理解:我们知道查找表的大小和目标图像一样,那么我们对于目标图像的每一个位置如(12,8),那么mapx和mapy存储着位于该处(即在mapx和mapy矩阵中也是(12,8)位置处)的源图像对应的x和y坐标位置,此时的在源图像中的坐标为浮点型,我们利用插值算法求解出该位置的像素值,然后将该像素值给目标图像的(12,8)位置的像素,要像正确理解,还需要深入的了解算法的操作流程,这里理解不免有误)。 利用计算得到查找映射表重投影图像的cvRemap()函数声明如下:
cvRemap函数将一幅图像中一个位置的像素平滑的重映射到另一个位置。
1、src源图像 2、dst目标图像,源图像和目标图像必须大小和通道一致,数据类型可以任意。 3、mapx,mapy,为单通道,通常为IPL_DEPTH_32F浮点型数据,和源图像、目标图像有同样的大小,指明具体像素重新分别的位置。 4、flags,插值方法,默认采用双线性插值。 插值方法: CV_INTER_NN 最邻近插值 CV_INTER_LINEAR 双线性插值(默认) CV_INTER_AREA 像素区域重新采样 CV_INTER_CUBIC 双三次插值
CV_WARP_FILL_OUTLIERS,其效果是可以用最后一个变量fillval设置的值填充目标图像的像素,而这些像素在原始输入图像中没有任意像素与之对应。
如果使用cvStereoRectifyUncalibrated()函数,即不使用摄像机内参数来校正视觉时,关于讲解请看Learning OpenCV中文版 475页倒数第二段以及阅读OpenCV自带的stereo_calib.cpp程序来详细了解具体的操作。 |
|