上篇文章中讲述了如何利用opencv 自带源码进行摄像头标定,本篇讲一下如何利用标定结果进行图像矫正
1、使用的函数
可以使用caUndistort2()函数一次性完成畸变映射计算和图像矫正,但对于同一个摄像头拍摄出来的图像,进行一次畸变映射即可,不需要每帧图像都进行畸变映射。因此caUndistort2()运行效率不高,聪明的方法是使用畸变映射计算和图像矫正运算两个函数替代caUndistort2()。
畸变映射函数:initUndistortRectifyMap()
矫正函数:remap()
2、示例
CvCapture * capture=cvCreateCameraCapture();
IplImage *image=cvQueryFrame(capture);
initUndistortRectifyMap(/****输入你的参数****/)
while(image){
cvRemap(/****输入你的参数****/)
image=cvQueryFrame(capture);
}
3、效果
矫正前
校正后
4、注意
进行矫正前必须先进行定标,获取摄像头的参数,定标过程见上面,定标之后可以通过
FileStorage fs2("%path%/\\cameral2.yml", FileStorage::READ); 来读取定标参数矩阵。定标过程中,尽量将图片占满全屏,或者向屏幕边缘处靠近,因为屏幕边缘处的畸变最大,这样才能更真实的测出摄像头的畸变参数。
下面是我实际使用的代码:
CvCapture * capture=cvCreateCameraCapture();
IplImage *image=cvQueryFrame(capture);
//读取摄像头参数
FileStorage fs2("D:\\work\\车牌识别\\车牌识别_佟兴宇\\Debug\\cameral2.yml", FileStorage::READ);
int frameCount = (int)fs2["nframes"];
std::string date;
fs2["calibration_time"] >> date;
Mat cameraMatrix, distCoeffs;
fs2["camera_matrix"] >> cameraMatrix;
fs2["distortion_coefficients"] >> distCoeffs;
cout << "frameCount: " << frameCount << endl
<< "calibration date: " << date << endl
<< "camera matrix: " << cameraMatrix << endl
<< "distortion coeffs: " << distCoeffs << endl;
Mat view,rview, map1, map2;
initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
imageSize, CV_16SC2, map1, map2);
while(image){
remap(view, rview, map1, map2, INTER_LINEAR);
imshow("view",view);
waitKey(15);
imshow("rview",rview);
waitKey(15);
image=cvQueryFrame(capture);
}