//opencv2.4.9 vs2012
#include <opencv2\opencv.hpp>
#include <fstream>
using namespace std;
using namespace cv;
int main()
{
double time0 = static_cast<double>(getTickCount());
ofstream fout("caliberation_result.txt"); /** 保存定标结果的文件 **/
/************************************************************************
读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化
*************************************************************************/
cout<<"开始提取角点………………"<<endl;
int image_count= 21; /**** 图像数量 ****/
Size image_size; /**** 图像的尺寸 ****/
Size board_size = Size(9,6); /**** 定标板上每行、列的角点数 ****/
vector<Point2f> corners; /**** 缓存每幅图像上检测到的角点 ****/
vector<vector<Point2f>> corners_Seq; /**** 保存检测到的所有角点 ****/
vector<Mat> 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";
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";
continue;
exit(1);
}
else
{
/* 亚像素精确化 */
cornerSubPix(imageGray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
/* 绘制检测到的角点并保存 */
Mat imageTemp = image.clone();
for (int j = 0; j < corners.size(); j++)
{
circle( imageTemp, corners[j], 10, Scalar(0,0,255), 2, 8, 0);
}
string imageFileName;
std::stringstream StrStm;
StrStm<<i+1;
StrStm>>imageFileName;
imageFileName += "_corner.jpg";
imwrite(imageFileName,imageTemp);
cout<<"Frame corner#"<<i+1<<"...end"<<endl;
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<vector<Point3f>> object_Points; /**** 保存定标板上角点的三维坐标 ****/
Mat image_points = Mat(1, count , CV_32FC2, Scalar::all(0)); /***** 保存提取的所有角点 *****/
vector<int> 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<cv::Mat> rotation_vectors; /* 每幅图像的旋转向量 */
vector<cv::Mat> translation_vectors; /* 每幅图像的平移向量 */
/* 初始化定标板上角点的三维坐标 */
for (int t=0;t<image_count;t++)
{
vector<Point3f> tempPointSet;
for (int i=0;i<board_size.height;i++)
{
for (int j=0;j<board_size.width;j++)
{
/* 假设定标板放在世界坐标系中z=0的平面上 */
Point3f tempPoint;
tempPoint.x = i*square_size.width;
tempPoint.y = j*square_size.height;
tempPoint.z = 0;
tempPointSet.push_back(tempPoint);
}
}
object_Points.push_back(tempPointSet);
}
/* 初始化每幅图像中的角点数量,这里我们假设每幅图像中都可以看到完整的定标板 */
for (int i=0; i< image_count; i++)
{
point_counts.push_back(board_size.width*board_size.height);
}
/* 开始定标 */
calibrateCamera(object_Points, corners_Seq, image_size, intrinsic_matrix ,distortion_coeffs, rotation_vectors, translation_vectors, 0);
cout<<"定标完成!\n";
/************************************************************************
对定标结果进行评价
*************************************************************************/
cout<<"开始评价定标结果………………"<<endl;
double total_err = 0.0; /* 所有图像的平均误差的总和 */
double err = 0.0; /* 每幅图像的平均误差 */
vector<Point2f> image_points2; /**** 保存重新计算得到的投影点 ****/
cout<<"每幅图像的定标误差:"<<endl;
cout<<"每幅图像的定标误差:"<<endl<<endl;
for (int i=0; i<image_count; i++)
{
vector<Point3f> tempPointSet = object_Points[i];
/**** 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 ****/
projectPoints(tempPointSet, rotation_vectors[i], translation_vectors[i], intrinsic_matrix, distortion_coeffs, image_points2);
/* 计算新的投影点和旧的投影点之间的误差*/
vector<Point2f> 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<Vec2f>(0,i) = Vec2f(image_points2[i].x, image_points2[i].y);
tempImagePointMat.at<Vec2f>(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;
cout<<"相机内参数矩阵:"<<endl;
fout<<intrinsic_matrix<<endl;
cout<<intrinsic_matrix<<endl;
fout<<"畸变系数:\n";
cout<<"畸变系数:\n";
fout<<distortion_coeffs<<endl;
cout<<distortion_coeffs<<endl;
for (int i=0; i<image_count; i++)
{
fout<<"第"<<i+1<<"幅图像的旋转向量:"<<endl;
fout<<rotation_vectors[i]<<endl;
/* 将旋转向量转换为相对应的旋转矩阵 */
Rodrigues(rotation_vectors[i],rotation_matrix);
fout<<"第"<<i+1<<"幅图像的旋转矩阵:"<<endl;
fout<<rotation_matrix<<endl;
fout<<"第"<<i+1<<"幅图像的平移向量:"<<endl;
fout<<translation_vectors[i]<<endl;
}
cout<<"完成保存"<<endl;
fout<<endl;
/************************************************************************
显示定标结果
*************************************************************************/
Mat mapx = Mat(image_size,CV_32FC1);
Mat mapy = Mat(image_size,CV_32FC1);
Mat R = Mat::eye(3,3,CV_32F);
cout<<"保存矫正图像"<<endl;
for (int i = 0 ; i != ima
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
普通相机标定.rar (75个子文件)
普通相机标定
ConsoleApplication1
ConsoleApplication1
img18.jpg 116KB
img9.jpg 107KB
img1.jpg 106KB
img14.jpg 110KB
img17.jpg 98KB
img10.jpg 110KB
img2.jpg 111KB
img20.jpg 102KB
img4.jpg 110KB
img21.jpg 112KB
img13.jpg 98KB
img19.jpg 106KB
img8.jpg 102KB
x64
Debug
link.7684-rc.write.1.tlog 2B
vc110.idb 731KB
CL.write.1.tlog 460B
link.4884-rc.write.1.tlog 2B
CL.read.1.tlog 26KB
link.11460-rc.write.1.tlog 2B
link.6412-cvtres.write.1.tlog 2B
link.11460-rc.read.1.tlog 2B
link.6412.write.1.tlog 2B
link.4884-rc.read.1.tlog 2B
link.11460.write.1.tlog 2B
link.7684-rc.read.1.tlog 2B
link.11460.read.1.tlog 2B
link.7684.write.1.tlog 2B
link.11460-cvtres.read.1.tlog 2B
link.6412-cvtres.read.1.tlog 2B
link.6412-rc.write.1.tlog 2B
cl.command.1.tlog 1KB
link-cvtres.read.1.tlog 2B
link.11460-cvtres.write.1.tlog 2B
link.7684-cvtres.read.1.tlog 2B
link.4884.read.1.tlog 2B
link.write.1.tlog 616B
link.7684.read.1.tlog 2B
link.1564.read.1.tlog 2B
link-rc.write.1.tlog 2B
link-cvtres.write.1.tlog 2B
link.7684-cvtres.write.1.tlog 2B
link.6412.read.1.tlog 2B
link.command.1.tlog 4KB
link.4884.write.1.tlog 2B
link-rc.read.1.tlog 2B
link.read.1.tlog 4KB
vc110.pdb 1.37MB
源.obj 1.26MB
link.1564-cvtres.write.1.tlog 2B
link.1564-rc.read.1.tlog 2B
ConsoleApplication1.log 3KB
link.1564-rc.write.1.tlog 2B
link.4884-cvtres.read.1.tlog 2B
link.6412-rc.read.1.tlog 2B
link.1564.write.1.tlog 2B
link.4884-cvtres.write.1.tlog 2B
link.1564-cvtres.read.1.tlog 2B
ConsoleApplication1.lastbuildstate 100B
ConsoleApplication1.vcxproj 8KB
img11.jpg 114KB
img7.jpg 106KB
img16.jpg 86KB
img12.jpg 102KB
img5.jpg 109KB
img3.jpg 103KB
源.cpp 9KB
ConsoleApplication1.vcxproj.filters 941B
img6.jpg 105KB
img15.jpg 106KB
ConsoleApplication1.sdf 12.75MB
ConsoleApplication1.sln 1KB
x64
Debug
ConsoleApplication1.exe 237KB
ConsoleApplication1.pdb 3.17MB
ConsoleApplication1.ilk 2.82MB
ConsoleApplication1.v11.suo 28KB
共 75 条
- 1
资源评论
- 蓠原草2016-07-04很好的资源
- wodabao1232016-08-31能用,不过好像只是校正了透视畸变,梯形畸变效果一般
BHY_
- 粉丝: 8690
- 资源: 34
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 数据分析-SPSS分析入门与深入
- 李跳跳_真实好友5.0_内测版.apk
- 前端开发中Vue.js模板与指令详解及应用场景
- 题目源码2024年强网杯全国网络安全挑战赛 PWN题目old-fashion-apache源码
- 基于Java 实现的百度图像识别API开发的车型识别APK
- CD python 数据分析代码及数据集(CDNOW-master.txt)
- 【MATLAB代码】二维平面上的TDOA,使用加权最小二乘法,不限制锚点数量(锚点数量>3即可)
- 数据分析-matlab入门
- 基于原生小程序实现的图像智能识别小程序,垃圾智能分类 通过拍照或者上传照片完成智能垃圾分类,服务端为 C#
- 题目源码2024年强网杯全国网络安全挑战赛 PWN题目baby-heap源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功