代码如下:
#include
#include
using namespace std;
using namespace cv;
int main()
{
ifstream fin("calibdata.txt"); //标定所用图像文件的路径
ofstream fout("caliberation_result.txt"); //保存定标结果的文件
//读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化
cout << "开始提取角点………………" << endl;
int image_count = 9; //图像数量
Size image_size; //图像的尺寸
Size board_size = Size(6, 7); //定标板上每行、列的角点数
vector corners; //缓存每幅图像上检测到的角点
vector> corners_Seq; //保存检测到的所有角点
vector image_Seq;
int count = 0;
for (int i = 0; i != image_count; i++)
{
cout << "Frame #" << i + 1 << "..." << endl;
string imageFileName;
std::stringstream StrStm;
StrStm << i + 1;
StrStm >> imageFileName;
imageFileName += ".jpg";
cv::Mat image = imread("img" + imageFileName);
image_size = image.size();
//image_size = Size(image.cols , image.rows);
/* 提取角点 */
Mat imageGray;
cvtColor(image, imageGray, CV_RGB2GRAY);
bool patternfound = findChessboardCorners(image, board_size, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE +
CALIB_CB_FAST_CHECK);
if (!patternfound)
{
cout << "can not find chessboard corners!\n";
exit(1);
}
else
{
//亚像素精确化
cornerSubPix(imageGray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
count = count + corners.size();
corners_Seq.push_back(corners);
}
image_Seq.push_back(image);
}
cout << "角点提取完成!\n";
//摄像机定标
cout << "开始定标………………" << endl;
Size square_size = Size(20, 20); //实际测量得到的定标板上每个棋盘格的大小
vector> object_Points; //保存定标板上角点的三维坐标
Mat image_points = Mat(1, count, CV_32FC2, Scalar::all(0)); //保存提取的所有角点
vector point_counts; //每幅图像中角点的数量
Mat intrinsic_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); //摄像机内参数矩阵
Mat distortion_coeffs = Mat(1, 4, CV_32FC1, Scalar::all(0)); //摄像机的4个畸变系数:k1,k2,p1,p2
vector rotation_vectors; //每幅图像的旋转向量
vector translation_vectors; //每幅图像的平移向量
//初始化定标板上角点的三维坐标
for (int t = 0;t tempPointSet;
for (int i = 0;i image_points2; //保存重新计算得到的投影点
cout << "每幅图像的定标误差:" << endl;
cout << "每幅图像的定标误差:" << endl << endl;
for (int i = 0; i tempPointSet = object_Points[i];
//通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点
projectPoints(tempPointSet, rotation_vectors[i], translation_vectors[i], intrinsic_matrix, distortion_coeffs, image_points2);
//计算新的投影点和旧的投影点之间的误差
vector tempImagePoint = corners_Seq[i];
Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2);
Mat image_points2Mat = Mat(1, image_points2.size(), CV_32FC2);
for (size_t i = 0; i != tempImagePoint.size(); i++)
{
image_points2Mat.at(0, i) = Vec2f(image_points2[i].x, image_points2[i].y);
tempImagePointMat.at(0, i) = Vec2f(tempImagePoint[i].x, tempImagePoint[i].y);
}
err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
total_err += err /= point_counts[i];
cout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
fout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
}
cout << "总体平均误差:" << total_err / image_count << "像素" << endl;
fout << "总体平均误差:" << total_err / image_count << "像素" << endl << endl;
cout << "评价完成!" << endl;
//保存定标结果
cout << "开始保存定标结果………………" << endl;
Mat rotation_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); //保存每幅图像的旋转矩阵
fout << "相机内参数矩阵:" << endl;
fout << intrinsic_matrix << endl;
fout << "畸变系数:\n";
fout << distortion_coeffs << endl;
for (int i = 0; i> imageFileName;
imageFileName += "_d.jpg";
imwrite(imageFileName, t);
}
cout << "保存结束" << endl;
//测试一张图片
cout << "TestImage ..." << endl;
Mat newCameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0));
VideoCapture captrue("calibration.avi");
//检测是否正常打开:成功打开时,isOpened返回ture
if (!captrue.isOpened())
cout << "fail to open!" << endl;
//获取整个帧数
long totalFrameNumber = captrue.get(CV_CAP_PROP_FRAME_COUNT);
cout << "整个视频共" << totalFrameNumber << "帧" << endl;
//获取帧率
double rate = captrue.get(CV_CAP_PROP_FPS);
cout << "帧率为:" << rate << endl;
//定义一个用来控制读取视频循环结束的变量
bool stop = false;
//承载每一帧的图像
Mat frame;
//显示每一帧的窗口
namedWindow("Extracted frame");
//两帧间的间隔时间:
//int delay = 1000/rate;
int delay = 1000 / rate;
long currentFrame = 1;
while (!stop)
{
//读取下一帧
if (!captrue.read(frame))
{
cout << "读取视频失败" << endl;
return -1;
}
//矫正
imshow("Extracted frame", frame);
initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, intrinsic_matrix, image_size, CV_32FC1, mapx, mapy);
Mat t = frame.clone();
cv::remap(frame, t, mapx, mapy, INTER_LINEAR);
imshow("after filter", t);
cout << "正在读取第" << currentFrame << "帧" << endl;
int c = waitKey(delay);
//按下ESC或者到达指定的结束帧后退出读取视频
if ((char)c == 27 || currentFrame > totalFrameNumber-1)
{
stop = true;
}
//按下按键后会停留在当前帧,等待下一次按键
if (c >= 0)
{
waitKey(0);
}
VideoWriter write;
string outFlie = "the video of calibration.avi";
write.write(t);
write.write(t);
write.write(t);
currentFrame++;
}
//关闭视频文件
captrue.release();
waitKey(0);
return 0;
}