双⽬校正-matlab标定相机+opencv校正1. matlab相机标定
(1)单相机标定
如上图,运⾏calib_gui_normal.m:
进⾏左相机标定,保存标定结果,并将名字修改为 :
Calib_Results_left.mat
进⾏右相机标定,保存标定结果,并将名字修改为 :
Calib_Results_right.mat
(2)双⽬标定
如上图,运⾏stereo_gui.m:
双⽬标定结果如下:
Stereo calibration parameters after optimization:
Intrinsic parameters of left camera:
Focal Length: fc_left = [ 265.53128 265.49126 ] � [ 0.47752 0.48253 ]
Principal point: cc_left = [ 156.44112 118.19951 ] � [ 0.33961 0.27560 ]
Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees
Distortion: kc_left = [ 0.06731 -0.12510 0.00167 0.00104 0.00000 ] � [ 0.00333 0.01100 0.00035 0.00045 0.00000 ] Intrinsic parameters of right camera:
Focal Length: fc_right = [ 265.15642 265.09738 ] � [ 0.48780 0.49072 ]
Principal point: cc_right = [ 156.58104 119.33607 ] � [ 0.33935 0.26903 ]
Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.0000
0 degrees
Distortion: kc_right = [ 0.06789 -0.14533 0.00158 -0.00365 0.00000 ] � [ 0.00321 0.01000 0.00033 0.00047 0.00000 ] Extrinsic parameters (position of right camera wrt left camera):
Rotation vector: om = [ -0.02944 -0.02725 -0.03523 ] � [ 0.00113 0.00156 0.00009 ]
Translation vector: T = [ -28.86386 0.03070 0.04467 ] � [ 0.14327 0.13379 0.45249 ]
Note: The numerical errors are approximately three times the standard deviations (for reference).
Saving the stereo calibration results in Calib_Results_
2. opencv 获取标定结果
好吧。。。我是直接赋值的。。。。
Mat matlab_cameraMatrixL;
Mat matlab_distCoeffL;
Mat matlab_cameraMatrixR;
Mat matlab_distCoeffR;
Mat matlab_Rl, matlab_Rr, matlab_Pl, matlab_Pr, matlab_R, matlab_T;
matlab_cameraMatrixL = (Mat_<double>(3, 3) << 265.53128, 0, 156.44112,
0, 265.49126, 118.19951,
0, 0, 1);
matlab_distCoeffL = (Mat_<double>(5, 1) << 0.06731, -0.12510, 0.00167, 0.00104, 0.00000);
matlab_cameraMatrixR = (Mat_<double>(3, 3) << 265.15642, 0, 156.58105,
0, 265.09738, 119.33607,
0, 0, 1);
matlab_distCoeffR = (Mat_<double>(5, 1) << 0.06789, -0.14533, 0.00158, -0.00365, 0.00000);
matlab_R = (Mat_<double>(3, 3) <<
0, 0, 0,
0, 0, 0,
0, 0, 0);
Mat RV = (Mat_<double>(3, 1) << -0.02944, -0.02725, -0.03523);
cv::Rodrigues(RV, matlab_R);
matlab_T = (Mat_<double>(3, 1) << -28.86386, 0.03070, 0.04467);
3. 计算旋转矩阵和投影矩阵
stereoRectify(matlab_cameraMatrixL, matlab_distCoeffL, matlab_cameraMatrixR, matlab_distCoeffR, imageSize, matlab_R, matlab_T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY, 0, imageSize, &validROIL, &validROIR);
4. 计算映射表
/*
根据stereoRectify 计算出来的R 和 P 来计算图像的映射表 mapx,mapy
mapx,mapy这两个映射表接下来可以给remap()函数调⽤,来校正图像,使得两幅图像共⾯并且⾏对准
ininUndistortRectifyMap()的参数newCameraMatrix就是校正后的摄像机矩阵。在openCV⾥⾯,校正后的计算机矩阵Mrect是跟投影矩阵P⼀起返回的。
所以我们在这⾥传⼊投影矩阵P,此函数可以从投影矩阵P中读出校正后的摄像机矩阵
*/
//摄像机校正映射
initUndistortRectifyMap(matlab_cameraMatrixL, matlab_distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);
initUndistortRectifyMap(matlab_cameraMatrixR, matlab_distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);
5. 执⾏校正
/
*
经过remap之后,左右相机的图像已经共⾯并且⾏对准了
*/
Mat rectifyImageL2, rectifyImageR2;
remap(rectifyImageL, rectifyImageL2, mapLx, mapLy, INTER_LINEAR);
remap(rectifyImageR, rectifyImageR2, mapRx, mapRy, INTER_LINEAR);
显⽰校正结果:
/*
把校正结果显⽰出来
把左右两幅图像显⽰到同⼀个画⾯上
*/
Mat canvas;
double sf;
rectangle函数opencvint w, h;
sf = 600. / MAX(imageSize.width, imageSize.height);
w = cvRound(imageSize.width * sf);
h = cvRound(imageSize.height * sf);
/*左图像画到画布上*/
Mat canvasPart = canvas(Rect(w * 0, 0, w, h)); //得到画布的⼀部分
resize(rectifyImageL2, canvasPart, canvasPart.size(), 0, 0, INTER_AREA); //把图像缩放到跟canvasPart⼀样⼤⼩
Rect vroiL(cvRound(validROIL.x*sf), cvRound(validROIL.y*sf), //获得被截取的区域
cvRound(validROIL.width*sf), cvRound(validROIL.height*sf));
rectangle(canvasPart, vroiL, Scalar(0, 0, 255), 3, 8); //画上⼀个矩形
cout << "Painted ImageL" << endl;
/*右图像画到画布上*/
canvasPart = canvas(Rect(w, 0, w, h)); //获得画布的另⼀部分
resize(rectifyImageR2, canvasPart, canvasPart.size(), 0, 0, INTER_LINEAR);
Rect vroiR(cvRound(validROIR.x * sf), cvRound(validROIR.y*sf),
cvRound(validROIR.width * sf), cvRound(validROIR.height * sf));
rectangle(canvasPart, vroiR, Scalar(0, 255, 0), 3, 8);
cout << "Painted ImageR" << endl;
/*画上对应的线条*/
for (int i = 0; i < ws; i += 16)
line(canvas, Point(0, i), ls, i), Scalar(0, 255, 0), 1, 8);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论