相机标定,vs2010下调试错误:Microsoft C++ 异常: 内存位置 0x0019df44 处的 cv::Exception,另外附加源码
调试源码如下:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
int main()
{
ifstream fin("calibdata.txt");//标定所用图文件路径,输入文件
ofstream fout("caliberation_result.txt");//保存标定结果的文件,输出文件
//读取每一幅图像,从中提取角点,然后对角点进行亚像素精确化
cout<<"开始提取角点......";//图片数量
int image_count = 0;
Size image_size;//图片尺寸
Size board_size = Size(4,6);//标定板上每行、每列的角点数
vector<Point2f> image_points_buf;//缓存每幅图像上检测到的角点
vector<vector<Point2f>> image_points_seq;//保存检测到的所有角点
string filename;
int count = -1;//用于存储角点数
while(getline(fin,filename))//获取文件夹中的每行数据信息
{
image_count++;
//用于观察检测输出
cout<<"image_count = "<<image_count<<endl;
//输出检验
cout<<"-->count == 1"<<count;
Mat imageInput = imread(filename);
if(image_count == 1)
{
image_size.width = imageInput.cols;
image_size.height = imageInput.rows;
cout<<"image_size.width = "<<image_size.width<<endl;
cout<<"image_size.height = "<<image_size.height<<endl;
}
//提取角点
if(0 == findChessboardCorners(imageInput,board_size,image_points_buf))
{
cout<<"can not find chessboard corners!\n";
exit(1);
}
else
{
Mat view_gray;
cvtColor(imageInput,view_gray,CV_BGR2GRAY);
find4QuadCornerSubpix(view_gray,image_points_buf,Size(5,5));//亚像素精确化
image_points_seq.push_back(image_points_buf);//保存亚像素点
//图像上显示角点位置
drawChessboardCorners(view_gray,board_size,image_points_buf,false);
imshow("Canmera Calibration",view_gray);
waitKey(500);
}
}
int total = image_points_seq.size();
cout<<"total = "<<total<<endl;
int CornerNum = board_size.width*board_size.height;//每张图片上总的角点数
for(int ii=0;ii<total;ii++)
{
if(0 == ii%CornerNum)
{
int i = -1;
i = ii / CornerNum;
int j = i + i;
cout<<"-->第"<< j <<"图片的数据-->: "<<endl;
}
if(0 == ii % 3)
{
cout<<endl;
}
else
{
cout.width(10);
}
cout<<" -->"<<image_points_seq[ii][0].x;
cout<<" -->"<<image_points_seq[ii][0].y;
}
cout<<"\n角点提取完成!\n";
//以下是摄像机标定
cout<<"开始标定....."<<endl;
//棋盘三维信息
Size square_size = Size(10,10);//实际测量得到的标定板上每个棋盘格的大小
vector<vector<Point3f>> object_points;
//内外参数
Mat cameraMatrix = Mat(3,3,CV_32FC1,Scalar::all(0));//相机内参
vector<int> point_counts;//每幅图像中角点的数量
Mat distCoeffs = Mat(1,5,CV_32FC1,Scalar::all(0));//摄像机的5个畸变系数k1,k2,p1,p2,k3
vector<Mat> tvecsMat;//每幅图像的旋转向量
vector<Mat> rvecsMat;//每幅图像的平移向量
//初始化标定板上角点的三维坐标
int i,j,t;
for(t=0;t<image_count;t++)
{
vector<Point3f> tempPointSet;
for(i=0;i<board_size.height;i++)
{
for(j=0;j<board_size.width;j++)
{
Point3f realPoint;
//假设标定板放在世界坐标系中Z=0的平面上
realPoint.x = i*square_size.width;
realPoint.y = j*square_size.height;
realPoint.z = 0;
tempPointSet.push_back(realPoint);
}
}
object_points.push_back(tempPointSet);
}
//初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板
for(i=0;i<image_count;i++)
{
point_counts.push_back(board_size.width*board_size.height);
}
//开始标定
calibrateCamera(object_points,image_points_seq,image_size,cameraMatrix,distCoeffs,rvecsMat,tvecsMat,0);//调用opencv自带的库函数进行相关的标定
cout<<"标定完成~!"<<endl;
//对标定结果进行评价
cout<<"开始评价标定结果......"<<endl;
double total_error = 0.0;//所有图像的平均误差的总和
double dError = 0.0;//每幅图像的平均误差
vector<Point2f> image_points2;//保存重新计算得到的投影点
cout<<"\t每幅图像的标定误差:"<<endl;
fout<<"每幅图像的标定误差:"<<endl;
for(i=0;i<image_count;i++)
{
vector<Point3f> tempPointSet = object_points[i];
//通过得到的摄像机内外参数,对空间的三维点进行重新投影计算
projectPoints(tempPointSet,rvecsMat[i],tvecsMat[i],cameraMatrix,distCoeffs,image_points2);
//计算心得投影点和旧的投影点之间的误差
vector<Point2f> tempImagePoint = image_points_seq[i];
Mat tempImagePointMat = Mat(1,tempImagePoint.size(),CV_32FC2);
Mat image_points2Mat = Mat(1,image_points2.size(),CV_32FC2);
for(int j=0;j<tempImagePoint.size();j++)
{
image_points2Mat.at<Vec2f>(0,j) = Vec2f(image_points2[j].x,image_points2[j].y);
tempImagePointMat.at<Vec2f>(0,j) = Vec2f(tempImagePoint[j].x,tempImagePoint[j].y);
}
dError = norm(image_points2Mat,tempImagePointMat,NORM_L2);
total_error += dError /= point_counts[i];
cout<<"第"<<i+1<<"幅图像的平均误差为:"<<dError<<"像素"<<endl;//总误差记为total_error
fout<<"第"<<i+1<<"幅图像的平均误差为:"<<dError<<"像素"<<endl;
}
cout<<"总体平均误差:"<<total_error/image_count<<"像素"<<endl;
fout<<"总体平均误差:"<<total_error/image_count<<"像素"<<endl<<endl;
cout<<"评价完成!"<<endl;
//保存标定结果
cout<<"开始保存标定结果......."<<endl;
Mat rotation_matrix = Mat(3,3,CV_32FC1,Scalar::all(0));//保存每幅图像的旋转矩阵
fout<<"相机内参数矩阵:"<<endl;
fout<<cameraMatrix<<endl<<endl;
fout<<"畸变系数:"<<endl;
fout<<distCoeffs<<endl<<endl<<endl;
for(int i=0;i<image_count;i++)
{
fout<<"第"<<i+1<<"幅图像的旋转向量:"<<endl;
fout<<tvecsMat[i]<<endl;
//将旋转向量转换为相对应的旋转矩阵
Rodrigues(tvecsMat[i],rotation_matrix);
fout<<"第"<<i+1<<"幅图像的旋转矩阵:"<<endl;
fout<<rotation_matrix<<endl;
fout<<"第"<<i+1<<"幅图像的平移向量:"<<endl;
fout<<rvecsMat[i]<<endl<<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;
string imageFileName;
stringstream StrStm;
for(int i=0;i!=image_count;i++)
{
cout<<"Frame #"<<i+1<<"..."<<endl;
initUndistortRectifyMap(cameraMatrix,distCoeffs,R,cameraMatrix,image_size,CV_32FC1,mapx,mapy);
StrStm.clear();
imageFileName.clear();
string filePath = "chess";
StrStm<<i+1;
StrStm>>imageFileName;
filePath += imageFileName;
filePath += ".bmp";
Mat imageSource = imread(filePath);
Mat newimage = imageSource.clone();
if(!imageSource.data)
{
cout<<"读取图片错误"<<endl;
}
remap(imageSource,newimage,mapx,mapy,CV_INTER_LINEAR);
StrStm.clear();
filePath.clear();
StrStm<<i+1;
StrStm>>imageFileName;
imageFileName += "_d.jpg";
imwrite(imageFileName,newimage);
}
cout<<"保存结束"<<endl;
return 0;
}
断点追踪提示错误的段位:
calibrateCamera(object_points,image_points_seq,image_size,cameraMatrix,distCoeffs,rvecsMat,tvecsMat,0);//调用opencv自带的库函数进行相关的标定
错误截图:
解决方法:
方法1:修改配置的opencv库使得其为最新版本
方法2:放到高一点的编译库中进行相关的调试即可。
如您需要更多的信息,欢迎一起咨询,一起学习
温馨提示:微信扫码关注我们:跟着数理化走天下
获得更多的信息哦,一起交流,一起成长哦:微信号:跟着数理化走天下,纯属个人的交流,无盈利目的