使用calibrateCamera后,我可以从单眼设置中获取投影矩阵。
This stackoverflow answer explains how.
现在,我遵循立体声校准样本,我想在进行立体声校正(openCV - stereo rectify)之后对两个相机做同样的事情。该方法给出了Q,R1,R2,P1和P2矩阵。
void stereoRectify(InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, Size imageSize, InputArray R, InputArray T, OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags=CALIB_ZERO_DISPARITY, double alpha=-1, Size newImageSize=Size(), Rect* validPixROI1=0, Rect* validPixROI2=0 )
我认为我必须以某种方式将它们组合在一起,但我不明白如何将这些输出矩阵与相机的内在函数和外在函数联系起来。
提前致谢!
编辑:我们假设我的相机没有失真。我知道我可以使用initUndistorRectifyMap重新映射图像并重新映射。但是,我只是想通过使用投影矩阵编写我自己的代码,即如果它只是一个摄像机校准,我得到摄像机矩阵C,旋转和平移矢量,我将它们组合到投影矩阵由C * [R | t]。我想做同样的事情,但是对于经过纠正的相机位置。
答案 0 :(得分:2)
您需要什么样的投影矩阵?
stereoRectify
仅计算将两个图像平面转换为公共图像平面的每个摄像机的旋转矩阵。这使得所有的极线都平行,因此每个栅格线都有一个寻找点对应关系。即如果在摄像机#1的图像平面上有一个2D点X1 = (x1, y1)
,那么摄像机#2上的相应点将位于具有相同y1
分量的栅格线上。因此,搜索简化为一维。
如果您对计算联合失真和整改转换感兴趣,则应使用stereoRectify
的输出作为initUndistortRectifyMap
的输入,然后使用remap
来应用投影。即:
stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
Mat map11, map12, map21, map22;
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
Mat img1r, img2r;
remap(img1, img1r, map11, map12, INTER_LINEAR);
remap(img2, img2r, map21, map22, INTER_LINEAR);
更新#1:
假设您在世界坐标系中有一个点:P_W
。它可以通过将其与外在参数相乘来转换为相机坐标系,即P_C = R*P_W + T
或P_C = [R|T] * P_W
。
整改后,每台摄像机将有两个矩阵:
R1
,R2
)的旋转矩阵,使两个相机图像平面成为同一平面,P1
,P2
)的新(整流)坐标系中的投影矩阵,如您所见,P1
的前三列和{{1将有效地成为新修正的相机矩阵。可以通过简单的矩阵乘法将点转换为经过校正的摄像机坐标系:P2
。
转换到经过校正的图像平面与上面的相似:P_R = R1*P_C
答案 1 :(得分:1)
这里的答案有点明显,虽然当时并非如此。我正在寻找的投影矩阵是P1和P2。我想知道如何用失真参数构造它们。实际上,这不是必需的,因为整个重映射过程不会对图像产生影响,因此我们可以直接使用P1和P2作为投影。希望这有助于某人。