机器视觉学习笔记(5)——基于OpenCV的单目摄像机标定
2015-12-16 14:24
387 查看
机器视觉学习笔记(5)——基于OpenCV的单目摄像机标定
标签(空格分隔): 机器视觉本文
CameraCalibrator类源代码来自于OpenCV2 计算机视觉编程手册(Robert Laganiere 著 张静 译)
强烈建议阅读机器视觉学习笔记(4)——单目摄像机标定参数说明之后再阅读本文
1.单目摄像机标定目的
单目摄像机标定的目的就是使摄像机实际状态无限接近理论推导的理想状态。单目摄像机标定最终将确定9个参数,摄像机内参数有4个,透镜畸变参数5个。2.单目摄像机标定流程
制作标定板使用摄像机拍摄不同角度的标定板
将照片放置于预设的文件夹中
编写程序计算摄像机内参数和透镜畸变参数
保存9个参数
3.关键源代码说明
3.1bool findChessboardCorners((InputArray image, Size patternSize, OutputArray corners)
Finds the positions of internal corners of the chessboard.(寻找棋盘格标定板的角点)
三个参数依次代表输入图像,角点数目,存储角点的变量
检测到角点以后,常常需要用
void drawChessboardCorners()函数将其画出来
如果找到的角点数目和输入的角点数目相同,就会用彩色圆圈画出角点,否则只用红色圆圈画出角点
示例程序如下:
void test() { vector<Point2f> imageCorners; Size boardSize(9, 6); Mat image = imread("left01.jpg"); bool found = findChessboardCorners(image, boardSize, imageCorners); //绘制角点 drawChessboardCorners(image, boardSize, imageCorners, found); namedWindow("test"); imshow("test", image);//角点如未全部检测出来只是红色圆圈画出角点 waitKey(); }
3.2Class CameraCalibrator
class CameraCalibrator{ //输入点 std::vector<std::vector<cv::Point3f>> objectPoints;//世界坐标系下的点 std::vector<std::vector<cv::Point2f>> imagePoints;//像素坐标系下的点 //输出矩阵 cv::Mat cameraMatrix;//摄像机内参数矩阵 cv::Mat distCoeffs;//透镜畸变系数矩阵 //标定方式 int flag; //用于图像去畸变 cv::Mat map1,map2; bool mustInitUndistort; public: CameraCalibrator() : flag(0), mustInitUndistort(true) {}; //导入标定图片提取角点 int addChessboardPoints(const std::vector<std::string>& filelist, cv::Size & boardSize); //添加场景点与对应的图像点 void addPoints(const std::vector<cv::Point2f>& imageCorners, const std::vector<cv::Point3f>& objectCorners); //标定相机 double calibrate(cv::Size &imageSize); //设置标定方式 void setCalibrationFlag(bool radial8CoeffEnabled=false, bool tangentialParamEnabled=false); //消除透镜畸变(标定之后调用有效) cv::Mat CameraCalibrator::remap(const cv::Mat &image); // 获取矩阵 cv::Mat getCameraMatrix() { return cameraMatrix; } cv::Mat getDistCoeffs() { return distCoeffs; } };
4.单目标定实例
源代码:点击下载实例标定图片:点击下载
main函数,说明详见注释
int main() { cv::namedWindow("Image"); cv::Mat image; std::vector<std::string> filelist;//存放标定图片路径 //生成路径,此处表示图片放在工程根目录下的chessboards文件夹 for (int i=1; i<=20; i++) { std::stringstream str; str << "chessboards/chessboard" << std::setw(2) << std::setfill('0') << i << ".jpg";//图片的相对路径 std::cout << str.str() << std::endl; filelist.push_back(str.str()); image= cv::imread(str.str()); cv::imshow("Image",image); cv::waitKey(100); } CameraCalibrator cameraCalibrator; //从棋盘格添加角点 cv::Size boardSize(6, 4); cameraCalibrator.addChessboardPoints( filelist, //图片路径 boardSize); //角点数目 //标定相机 cameraCalibrator.calibrate(image.size()); //选取某张图片,消除透镜畸变 image = cv::imread(filelist[6]); cv::Mat uImage= cameraCalibrator.remap(image); imshow("Original Image", image); imshow("Undistorted Image", uImage); //打印相机内参数矩阵(3*3矩阵) Mat cameraMatrix = cameraCalibrator.getCameraMatrix(); std::cout << " 相机内参数矩阵:" << cameraMatrix.rows << "x" << cameraMatrix.cols << std::endl; for (int i=0; i<cameraMatrix.rows; i++) for (int j=0; j<cameraMatrix.cols; j++) { cout<<setw(10)<<cameraMatrix.at<double>(i, j); if (j==2) cout<<endl; } //打印畸变系数矩阵(1*5矩阵) Mat distCoeffs = cameraCalibrator.getDistCoeffs(); std::cout << "畸变系数矩阵:" << distCoeffs.rows << "x" << distCoeffs.cols << std::endl; for (int i=0; i<distCoeffs.rows; i++) for (int j=0; j<distCoeffs.cols; j++) cout<<distCoeffs.at<double>(i, j)<<"\t"; waitKey(0); }
畸变校正之前
畸变校正之后
相机内参数矩阵为
⎡⎣⎢167.156000178.0970155.89119.3721⎤⎦⎥
透镜畸变系数矩阵(分别表示k1,k2,p1,p2,k3)为
[−0.34560.1319−0.0004−0.0034−0.0227]
5.总结
尽管核心函数都是OpenCV库函数,但是通过面向对象思想把相关函数和变量整合起来定义一个类是非常棒的方式,这样就可以专注于逻辑思考而不是一些变量和语法标定结果是否准确可以通过相机内参数矩阵大致推算出来。笔者自己的1280*720分辨率相机标定的x0,y0分别是622pix,370pix,恰好是分辨率的一半左右,符合其物理意义,可以断定标定正确(精度另说)
本文实例中的x0,y0分别是156pix,119pix,由此我们可以推断作者相机的分辨率是312*234左右,由于视频分辨率常见的也就那几种,所以可以断定实例程序相机的分辨率是320*240
相关文章推荐
- 利用矢量计算快速判定一点在直线的哪一侧
- 大幅面多相机高精度定位及测量解决方案
- 读书计划与交流的期望
- 在机器视觉领域中为何选择基于瑞芯微Rockchip PX2主控芯片?
- Halcon学习之四:有关图像生成的函数
- Halcon学习之二:摄像头获取图像和相关参数
- Halcon学习之五:有关图像的定义域的函数
- Halcon学习之七:改变图像的现实方式和大小
- 分享一些OpenCV实现立体视觉的经验
- 在OpenCV中用cvCalibrateCamera2进行相机标定
- 机器视觉方向的大牛介绍
- 机器人demo
- 机器视觉系统硬件部分
- 普及机器视觉,每日一贴
- 机器视觉的一些链接
- 本人常用资源整理(ing...)
- 图像处理与计算机视觉:基础,经典以及最近发展
- 工业相机和数码相机的六大区别
- 如何选择工业相机?听听专家怎么说
- 远心工业镜头与普通工业镜头的区别