最近在搞,uvc鱼眼相机畸变矫正标定、透视图变换为IPM图(鸟瞰图/俯视图),可给恶心坏了,先说说两个畸变矫正的函数吧,如下:fisheye::initUndistortRectifyMap(), (注意我用的是鱼眼相机,你的如果是普通uvc相机,就用initUndistortRectifyMap()这个函数,前边没有fisheye::)和 getOptimalNewCameraMatrix();
fisheye::initUndistortRectifyMap()函数的使用方法:
fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,intrinsic_matrix,image_size,CV_32FC1,mapx,mapy);
或者:
fisheye::initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R,getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs, image_size, 0, image_size, 0), image_size, CV_32FC1, mapx, mapy);
两者的差别在哪里呢?就在fisheye::initUndistortRectifyMap()函数的第四个参数,第一种调用方法的第四个参数直接将原相机内参intrinsic_matrix作为输入参数,第二种方法的第四个参数的输入是 getOptimalNewCameraMatrix(),这个函数的作用是算出一个新的内参矩阵,通过调整他的第四个参数(0~1),可以调整畸变裁剪后的图像视野大小,0视野最小,1视野最大。
这两个函数在这里搜索,查看每个参数的意思。
后续在更新~~~
2019.7.9
都快忘了这茬,今天把坑补上,
完整的代码在https://github.com/LixinLu42/PerspectiveTransform,另欢迎骚扰我的github
下面简单介绍下大体思路,github上的代码很多注释掉的代码,可以忽略注释的代码,那是我自己调试的过程哈`~~~
相机内参和畸变系数需要畸变矫正得到,我会找时间上一下畸变矫正的代码。回来啦:标定的方法在这里:https://blog.csdn.net/weixin_39608351/article/details/95178269
单应矩阵H 的代码也需要计算,有时间我也会单独提交下,代码来啦:https://github.com/LixinLu42/Get_H
//相机的内参矩阵:intrinsic_matrix
cv::Mat intrinsic_matrix(3, 3, cv::DataType<float>::type); // Intrisic matrix
intrinsic_matrix.at<float>(0, 0) = 526.0460621686325;
intrinsic_matrix.at<float>(1, 0) = 0;
intrinsic_matrix.at<float>(2, 0) = 0;intrinsic_matrix.at<float>(0, 1) = 0;
intrinsic_matrix.at<float>(1, 1) = 527.7225009042863;
intrinsic_matrix.at<float>(2, 1) = 0;intrinsic_matrix.at<float>(0, 2) = 654.1771804245265;
intrinsic_matrix.at<float>(1, 2) = 320.8740042532168;
intrinsic_matrix.at<float>(2, 2) = 1;//相机的畸变参数 :distortion_coeffs
cv::Mat distortion_coeffs(4, 1, cv::DataType<float>::type); // Distortion vector
distortion_coeffs.at<float>(0) = -0.0467926;
distortion_coeffs.at<float>(1) = 0.00453962;
distortion_coeffs.at<float>(2) = 0.000105393;
distortion_coeffs.at<float>(3) = -0.00195177;//相机经过畸变矫正后设置的新的内参:new_intrinsic_mat
Mat intrinsic_mat(intrinsic_matrix), new_intrinsic_mat;intrinsic_mat.copyTo(new_intrinsic_mat);//通过调节新的内参系数,调节视场大小,乘的系数越小视场越大
new_intrinsic_mat.at<float>(0, 0) *= 0.35*mul;
new_intrinsic_mat.at<float>(1, 1) *= 0.35*mul;
//通过调节新的内参系数,调节校正图中心,建议置于校正图中心
new_intrinsic_mat.at<float>(0, 2) = 0.5 *mul * src.cols;
new_intrinsic_mat.at<float>(1, 2) = 0.5 *mul * src.rows;Mat src1;
//fisheye::undistortImage的功能 = fisheye::initUndistortRectifyMap + remap的功能
//fisheye::undistortImage(src, src1, intrinsic_matrix, distortion_coeffs, new_intrinsic_mat, size);fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,new_intrinsic_mat, size,CV_32FC1,mapx,mapy);
//fisheye::initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R,
//getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs, //image_size, 1, size, 0), image_size, CV_32FC1, mapx, mapy);
imshow("src", src);cv::remap(src, src1, mapx, mapy, INTER_LINEAR);
imshow("remap", src1);
imwrite("remap.jpg", src1);
//Mat srcImage = src1.clone();
Mat grayImage;
cvtColor(src1, grayImage, CV_BGR2GRAY);//H矩阵的初始化
cv::Mat H(3, 3, cv::DataType<double>::type); // Intrisic matrix
H.at<double>(0, 0) = 104.8203858991843;
H.at<double>(1, 0) = -3.994835860613545;
H.at<double>(2, 0) = -0.0009548304773162318;H.at<double>(0, 1) = -315.3103170020404;
H.at<double>(1, 1) = 14.74016444899316;
H.at<double>(2, 1) = -0.04940749328807874;H.at<double>(0, 2) = 5979.5;
H.at<double>(1, 2) = 1407;H.at<double>(2,2) = 12 * mul;//控制图像大小参数Mat a=H.inv();cout << "..........H.............." << endl;cout << H << endl;cout << "..........a.............." << endl;cout << a << endl;cout << "..........end.............."<< endl;//将畸变矫正图变为IPM图warpAffine(tempBirdImage, birdImage, M, tempBirdImage.size());*/namedWindow("birdImage");imshow("birdImage", birdImage);imwrite("birdImage.jpg", birdImage);//imshow("The undistort image", src1);waitKey(0);return 0;
}