关于相机校正,opencv自带了程序,隐藏在calibration.cpp文件里,期初没有在意,后来才恍然大悟。我先贴出这段程序;
#include <iostream>
#include <cmath>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
#define threshold_diff 20
int main(int, char**)
{
VideoCapture cap;
cap.open(1);
if( !cap.isOpened() )
return -1;
Mat prevgray, gray, frame;
Mat intrinsic = Mat(3, 3, CV_32FC1);
intrinsic.at<float>(0, 0) = 321.2398;
intrinsic.at<float>(0, 1) = 0;
intrinsic.at<float>(0, 2) = 335.4872;
intrinsic.at<float>(1, 0) = 0;
intrinsic.at<float>(1, 1) = 391.6564;
intrinsic.at<float>(1, 2) = 236.4062;
intrinsic.at<float>(2, 0) = 0;
intrinsic.at<float>(2, 1) = 0;
intrinsic.at<float>(2, 2) = 1;
Mat distcoeffs = Mat(5,1,CV_32FC1);
distcoeffs.at<float>(0,0) = -0.3257;
distcoeffs.at<float>(1,0) = -1.5232;
distcoeffs.at<float>(2,0) = -0.0007;
distcoeffs.at<float>(3,0) = -0.0020;
distcoeffs.at<float>(4,0) = -0.0452;
Mat map1,map2,rview;
Size imageSize,newImageSize;
Mat imgU;
for(;;)
{
double t = (double)cvGetTickCount();
cap >> frame;
imageSize.width = frame.cols;
imageSize.height = frame.rows;
newImageSize.width = imageSize.width;
newImageSize.height = imageSize.height;
imshow("original", frame);
//undistort(frame, imgU, intrinsic, distcoeffs);
initUndistortRectifyMap(intrinsic, distcoeffs, Mat(),
getOptimalNewCameraMatrix(intrinsic, distcoeffs, imageSize, 1, newImageSize, 0),
newImageSize, CV_16SC2, map1, map2);
remap(frame, rview, map1, map2, INTER_LINEAR);
imshow("rview",rview);
cvtColor(rview, gray, CV_BGR2GRAY);
//imshow("undistort", imgU);
Mat flowmap;
Mat diff;
if( prevgray.data )
{
subtract(gray,prevgray,diff);
for(int i=0;i<diff.rows;i++)
for(int j=0;j<diff.cols;j++)
if(abs(diff.at<unsigned char>(i,j))>=threshold_diff)//这里模板参数一定要用unsigned char,否则就一直报错
diff.at<unsigned char>(i,j)=255;
else diff.at<unsigned char>(i,j)=0;
imshow("diff",diff); //直接在判断内显示,imshow才不会出错
}
if(waitKey(10)>=0)
break;
std::swap(prevgray, gray);
t = (double)cvGetTickCount() - t;
cout << "cost time: " << t / ((double)cvGetTickFrequency()*1000) << endl;
}
return 0;
}
一般有两种方法,1种是采用remap进行校正,1种是采用undistort进行校正。在我采用undistort输出的校正图片比较可观,而采用remap却反而比原始图片更糟糕,如下图
期初觉得是没有标定好,然后又选择了一组图片,得到的效果还是一样的。
具体的原因还在调查中…