项目中使用了Matlab程序做相机标定,最终Matlab导出内参矩阵,外参系数,畸变系数等参数。最终控制机器人运动的程序是使用C++和OpenCV开发的,因此涉及到了从Matlab程序转换到OpenCV程序的问题。
矩阵运算有关的程序没什么问题,无缝转换,但是涉及到畸变校正的部分就需要另外实现了。
Matlab中是CamPoints = undistortPoints(distortedCamPoints, params);
Matlab相机标定函数生成的cameraParam即上面的params是一个很大的变量,把相机有关的所有参数都包含在内了。问题是这个函数无法通过Matlab coder导出。
实际使用OpenCV自带的undistortPoints函数导出。比较值得注意的地方是这个函数输出矩阵中的x, y,需要转换一下,才是最终的图像坐标。转换公式是:
pixelX = x * focal length x + principal point x
pixelY = y * focal length y + principal point y
对应的程序如下:
vector<Point2f> distortPoints, unDistortPoints;
distortPoints.push_back(Point2f(711.13, 631.42));
Mat cameraMatrix = Mat::eye(3, 3, CV_32F);
cameraMatrix.at<float>(0, 0) = 7.8818e+03;
cameraMatrix.at<float>(0, 1) = 0;
cameraMatrix.at<float>(0, 2) = 1.3083e+03;
cameraMatrix.at<float>(1, 1) = 7.89e+03;
cameraMatrix.at<float>(1, 2) = 1.1996e+03;
Mat distCoeffs = Mat::zeros(5, 1, CV_32F);
distCoeffs.at<float>(0, 0) = -0.2363; //k1, radial distortion
distCoeffs.at<float>(1, 0) = -0.9046; //k2, radial distortion
distCoeffs.at<float>(2, 0) = 0; //p1, tangential distortion
distCoeffs.at<float>(3, 0) = 0; //p2, tangential distortion
distCoeffs.at<float>(4, 0) = 0; //k3, radial distortion
undistortPoints(distortPoints, unDistortPoints, cameraMatrix, distCoeffs);
unDistortPoints[0].x = unDistortPoints[0].x * cameraMatrix.at<float>(0, 0) + cameraMatrix.at<float>(0, 2);
unDistortPoints[0].y = unDistortPoints[0].y * cameraMatrix.at<float>(1, 1) + cameraMatrix.at<float>(1, 2);