【笔记】Opencv张正友相机标定傻瓜教程

Q1:

        Size square_size = Size(10,10); /* 实际测量得到的标定板上每个棋盘格的大小 */ 如果单位是毫米的话,博客中的棋盘格也就5cm*7cm的样子,肯定没这么小;10cm的话又太大了。

Q2:

程序运行到第41行的findChessboardCorners函数中就出不来了?设置断点跟踪了一段后直接就没有下一步的箭头了,程序也没有退出,也没有报错,就一直停在这里,棋盘格的内点数量也改了。

Q3:

你好,这个对图像源有什么要求吗?我拿几组图像数据做测试,结果有的可以跑出来,有的就不可以。图像和棋盘格的大小之间有什么联系吗?

答:Size board_size = Size(6, 9); /* 标定板上每行、列的角点数 */

Q4:

运行程序出现如下错误:opencv Error: Bad flag in cvGetMat, file..\..\..\..\opencv\modules\core\src\array.cpp,line 2482 请问是怎么回事?

答:好像跟溢出有关,你的这个calibdata.txt文件中chess14(我的最后一个图片的文件名)下方有没有多余的回车,有的话应该都删掉。多余的空格回车会造成getline()函数的溢出。或许还有其他可能

Q5:

我跑这个程序的时候有下边的错误OpenCV Error: Assertion failed (nimages > 0) in calibrateCamera, file /home/zhanghaoxin/slambook/ch5/imageBasics/opencv-3.1.0/modules/calib3d/src/calibration.cpp, line 3314 terminate called after throwing an instance of 'cv::Exception' what(): /home/zhanghaoxin/slambook/ch5/imageBasics/opencv-3.1.0/modules/calib3d/src/calibration.cpp:3314: error: (-215) nimages > 0 in function calibrateCamera 怎么解决?

答:这个是在opencv2下跑的,opencv3下的calibrateCamera函数应该有改动,opencv3的可以参考这篇文章: 【OpenCV3学习笔记 】相机标定函数 calibrateCamera( ) 使用详解(附相机标定程序和数据)_把岁月化成歌 留在博客-CSDN博客_calibratecamera

Q6:

Size square_size = Size(10,10); /* 实际测量得到的标定板上每个棋盘格的大小 */ 请问上述代码中的10是什么单位呀?

答:mm

Q7:

成功运行了您的程序,但是发现去畸变之后的图片比原图畸变更大了。。可能是才疏学浅,找了好几天问题所在都没看出来,所以才不好意思来请教您。

答:你用的原图质量非常好,矫正后效果会变差。如果你用的是有径向畸变的那种筒形照片,效果就很明显了。

正文:

注: 程序所用的OpenCV版本是 2.4.10 ,3.0以上的版本可能会有不同

先贴一下完整的工程代码:

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include 
#include 
 
using namespace cv;
using namespace std;
 
void 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 image_points_buf;  /* 缓存每幅图像上检测到的角点 */
	vector> image_points_seq; /* 保存检测到的所有角点 */
	string filename;
	int count= -1 ;//用于存储角点个数。
	while (getline(fin,filename))
	{
		image_count++;		
		// 用于观察检验输出
		cout<<"image_count = "<count = "< 第 "< : "<"<"<> object_points; /* 保存标定板上角点的三维坐标 */
	/*内外参数*/
	Mat cameraMatrix=Mat(3,3,CV_32FC1,Scalar::all(0)); /* 摄像机内参数矩阵 */
	vector point_counts;  // 每幅图像中角点的数量
	Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0)); /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */
	vector tvecsMat;  /* 每幅图像的旋转向量 */
	vector rvecsMat; /* 每幅图像的平移向量 */
	/* 初始化标定板上角点的三维坐标 */
	int i,j,t;
	for (t=0;t tempPointSet;
		for (i=0;i image_points2; /* 保存重新计算得到的投影点 */
	cout<<"\t每幅图像的标定误差:\n";
	fout<<"每幅图像的标定误差:\n";
	for (i=0;i tempPointSet=object_points[i];
		/* 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 */
		projectPoints(tempPointSet,rvecsMat[i],tvecsMat[i],cameraMatrix,distCoeffs,image_points2);
		/* 计算新的投影点和旧的投影点之间的误差*/
		vector 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(0,j) = Vec2f(image_points2[j].x, image_points2[j].y);
			tempImagePointMat.at(0,j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y);
		}
		err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
		total_err += err/=  point_counts[i];   
		std::cout<<"第"<

运行前需要先准备标定图片和记录标定图片列表的文本文件,并放入程序所在目录下,如下图所示:

【笔记】Opencv张正友相机标定傻瓜教程_第1张图片

文本文件的内容如下: 

【笔记】Opencv张正友相机标定傻瓜教程_第2张图片

 运行效果图1:

【笔记】Opencv张正友相机标定傻瓜教程_第3张图片

 图2:

【笔记】Opencv张正友相机标定傻瓜教程_第4张图片

图3:

【笔记】Opencv张正友相机标定傻瓜教程_第5张图片 图4:

【笔记】Opencv张正友相机标定傻瓜教程_第6张图片

 最后在程序所在目录下生成“caliberation_result.txt”文件,记录了标定的误差、相机内外参数信息:

【笔记】Opencv张正友相机标定傻瓜教程_第7张图片

你可能感兴趣的:(opencv,计算机视觉,人工智能)