C++ 在立体校准中,如果我改变立体相机的分辨率,外部矩阵是如何变化的
我的立体相机有不同的分辨率1280x480、640x240和320x120。(相机流是水平粘贴的一对同步图像640X480,这就是为什么是1280x480) 我在下面使用了Opencv3立体校准算法来校准分辨率为1280*480的立体相机C++ 在立体校准中,如果我改变立体相机的分辨率,外部矩阵是如何变化的,c++,opencv,matrix,stereoscopy,C++,Opencv,Matrix,Stereoscopy,我的立体相机有不同的分辨率1280x480、640x240和320x120。(相机流是水平粘贴的一对同步图像640X480,这就是为什么是1280x480) 我在下面使用了Opencv3立体校准算法来校准分辨率为1280*480的立体相机 stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
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);
立体校正计算左右摄像机之间的旋转矩阵R、平移矩阵T。此外,它还计算两个旋转矩阵R1、R2和两个投影矩阵P1 P2。我使用StereoRective的输出作为InitUnderdistortRectiveyMap的输入,然后重新映射以应用投影
下面是一个解释如何做到这一点的答案
现在我得到了左map11,map12和右摄像头map21,map22的两个校正图矩阵
但现在我想使用这些相机矩阵M1和M2,失真矩阵D1和D2,以及外部矩阵R、T、R1、R2、P1和P2,分别以较低的分辨率(320x120)校正相机图像。PS我没有直接校准分辨率为320*120的相机,因为图像太小,Opencv算法找不到棋盘角来执行校准
我知道“失真系数并不取决于观看的场景。因此,它们也属于相机的固有参数。无论捕获的图像分辨率如何,它们都保持不变。例如,如果已在320 x 240分辨率的图像上校准相机,则可对来自同一相机的640 x 480图像使用绝对相同的失真系数,同时需要适当缩放f_x、f_y、c_x和c_y。”
根据(我测试过了,它正在工作)
我想知道:我应该如何修改R、T、R1、R2、P1、P2的矩阵,以便以较低的分辨率从1280x480重新映射到320x120?实际上
我改变了P1和P2的矩阵,它们是相机固有矩阵和相机平移矩阵的组合
使用320x120时,我只需将它们除以4。一般公式为:
fx'=(dimx'/dimx)*fx
fy'=(dimy'/dimy)*fy
fx'是新分辨率的值,fx是原始分辨率的值,dimx'是沿x轴的新分辨率,dimx是原始分辨率。fy也是如此
cx和cy是以类似方式计算的,因为所有这些值都以像素坐标表示。实际上
我改变了P1和P2的矩阵,它们是相机固有矩阵和相机平移矩阵的组合
使用320x120时,我只需将它们除以4。一般公式为:
fx'=(dimx'/dimx)*fx
fy'=(dimy'/dimy)*fy
fx'是新分辨率的值,fx是原始分辨率的值,dimx'是沿x轴的新分辨率,dimx是原始分辨率。fy也是如此
cx和cy是以类似方式计算的,因为所有这些值都是以像素坐标表示的。经过多次尝试后,不仅应缩放P1
和P2
,而且还应缩放M1
和M2
(在OP的代码中)
请记住,缩放只是左缩放矩阵的两个第一对角项,并将第三个保留为1。经过多次反复处理后,不仅应缩放P1
和P2
,而且还应缩放M1
和M2
(在OP的代码中)
记住,缩放只是左缩放矩阵的两个第一对角线项,并将第三个保留为1