基于opencv的摄像机标定
2016-03-15 20:21
344 查看
原理简述:
三维世界中的点的位置与其对应的二维投影,遵从以下公式:其中,
M表示三维世界中的点;
[R|T]表示欧氏变换,是一个3*4矩阵
A表示相机参数矩阵,存放相机内部参数
P表示M在二维空间的投影,是一个二维点(文献1)。
相机成像投影图如下所示(文献2):
摄像机标定的过程就是找到相机内参,即:矩阵A
A通常为:
|afsx|
A=|0fy|
|001|
图像平面和照相机中心间的距离为焦距f。当像素数组在传感器上偏斜的时候,需要用到倾斜参数s。在大多数情况下,s可以设置为0。于是上式可变为:
|af 0x|
A= |0 fy|
|0 01|
纵横比例参数a是在像素元素非正方形的情况下使用的。通常情况下,其为1。于是上式可变为:
|f 0x|
A= |0 fy|
|0 01|
除焦距f外,标定矩阵中剩余的唯一参数为光心(有时称为主点)的坐标c=[x y],也就是光线坐标轴和图像平面的交点。因为光心通常在图像的中心,
并且图像的坐标是从左上角开始计算的,所以光心的坐标常常接近于图像宽度和高度的一半,即x=图像宽度/2,y=图像高度/2。
重要的事情说三遍,照相机标定的唯一未知变量是焦距f。
标定步骤:
使用OpenCV进行摄像机标定,在OpenCV例程中有现成的例程程序可以实现,/samples/cpp/tutorial_code/calib3d/camera_calibration里的程序就可以进行单目相机标定。
因为例程代码无需修改即可使用,因此,对于该例程的代码分析,在此不展开讨论,有兴趣的可以到文献[3]中查看,该博客
较详细介绍了其中函数。
在此只简单介绍下若要调用该例程生成标定矩阵,所需要做的最小工作量。
一:
准备棋盘格图标并打印,用准备标定的摄像机从不同角度拍摄10-15幅图片。
二:
在VID.xml中添加拍摄图片的路径,用于程序执行时读入图片,建议在程序当前目录下创建一个文件夹放拍摄图片,且在VID.xml中
输入路径时可用相对路径,而不是绝对路径,即便将标定程序工程拷贝到其它路径下,程序无需修改即可运行。如果图片用相对路径,
则将标定程序拷贝到其它路径下,需要修改图片的路径。如果图片路径输入有误,执行程序会出错,在本人计算机上运行错误如下:
Near the sample file you'll find the configuration file, which has detailed help of how to edit it. It may be any OpenCV supported file format XML/YAML. OpenCV Error: Assertion failed (src.size == dst.size && src.channels() == dst.channels()) in cvConvertScale, file /home/djt/software/opencv-3.0.0/modules/core/src/convert.cpp, line 6213 terminate called after throwing an instance of 'cv::Exception' what(): /home/djt/software/opencv-3.0.0/modules/core/src/convert.cpp:6213: error: (-215) src.size == dst.size && src.channels() == dst.channels() in function cvConvertScale
三:
程序开始会读入配置文件in_VID5.xml,该文件对棋盘格的角点数(由你使用的棋盘格决定),即在水平(BoardSize_Width)和垂直方向(BoardSize_Height)方向各有几个角点,如我用的是7*7的棋盘格,相应参数需修改为7,如果该参数设置与你使用棋盘格图片不一致会出错,错误如下:
Near the sample file you'll find the configuration file, which has detailed help of how to edit it. It may be any OpenCV supported file format XML/YAML. OpenCV Error: Assertion failed (src.size == dst.size && src.channels() == dst.channels()) in cvConvertScale, file /home/djt/software/opencv-3.0.0/modules/core/src/convert.cpp, line 6213 terminate called after throwing an instance of 'cv::Exception' what(): /home/djt/software/opencv-3.0.0/modules/core/src/convert.cpp:6213: error: (-215) src.size == dst.size && src.channels() == dst.channels() in function cvConvertScale四:
配置文件in_VID5.xml还定义了矩阵输出文件"out_camera_data.xml“,当校正完成后,校正矩阵参数就保存到该文件中,对于.xml的读写,opencv中有专门的类进行操作,即
FileStorage类,具体用法自行百度。在校正程序中对校正矩阵的定义为Mat cameraMatrix = Mat::eye(3, 3, CV_64F);其取用方法为cameraMatrix.at<double>(0,0) = 1.0;
重点来了
在之后的程序中(如增强现实中)要是调用该矩阵,一定要将FileStorage类读入数据的校正矩阵定义为Mat cameraMatrix = Mat::eye(3, 3, CV_64F);且取用时用cameraMatrix.at<double>(0,0) = 1.0; 而不能用cameraMatrix.at<float>(0,0) = 1.0;也不能用Mat_<float> camMatrix; camMatrix = Mat::eye(3, 3, CV_64F);否则
会因数据类型不符而导致后续程序计算错误,但却不报错。但可以通过先读到Mat cameraMatrix = Mat::eye(3, 3, CV_64F);定义变量中再逐个赋值给
Mat_<float> camMatrix1;定义矩阵。但赋值时,camMatrix1(i,j)=cameraMatrix.at<double>(i,j); double类型一定不要写错。
程序已上传到http://download.csdn.net/detail/daijuting/9467510需要的请下载。
参考资料:
主要参考以下博客,其链接如下:
[1]:/article/9623275.html
[2]:/article/9623272.html
[3]:/article/9623273.html
以及计算机视觉的两本书(以上几篇博客也主要是参考文献5):
[4]:Python计算机视觉编程 第四章
[5]:深入理解OpenCV实用计算机视觉项目解析 第二章
因为用到程序主要是opencv的一个例程,其中用到的两个官方文档如下
opencv document:
http://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
相关文章推荐
- 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理【转】
- 《Linux内核设计与实现》读书笔记(十)- 内核同步方法【转】
- linux
- nginx window安装
- Linux资源控制-CPU和内存【转】
- cron crontab anacron anacrontab Linux下的计划任务
- About Zsh & Go2Shell & iTerm2
- shell实现trim函数-去除字符串两侧的空格(包括tab,space键)
- Uva10048——Audiophobia
- Nginx + Tomcat 动静分离实现负载均衡(转)
- 浅析三层架构与MVC模式的区别
- 28335学习笔记:asm(" RPT #N || NOP")
- 大型网站技术架构介绍--squid
- hexdump——Linux系统的二进制文件查看工具
- Linux 安装jdk、tomcat,maven
- 《Linux内核设计与实现》读书笔记(七)- 中断处理【转】
- shell之gcc用法汇总
- Linux第一章第二章学习笔记
- 聚内核与微内核
- Linux命令之ln