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
答:好像跟溢出有关,你的这个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<<"第"<
运行前需要先准备标定图片和记录标定图片列表的文本文件,并放入程序所在目录下,如下图所示:
文本文件的内容如下:
运行效果图1:
图2:
图3:
最后在程序所在目录下生成“caliberation_result.txt”文件,记录了标定的误差、相机内外参数信息: