基于OpenCV单目相机的快速标定--源码、工程、实现过程

  相机的标定是所有人走进视觉世界需要做的第一件事,辣么多的视觉标定原理解释你可以随便在网上找到,这里只讲到底如何去实现,也算是给刚入门的朋友做个简单的分享。

1.单目相机标定的工程源码

  首先请到同性交友网站Github上下载工程源码(https://github.com/Zhanggx0102/Camera_Calibration),注意以下几点:

1).这是一个MS Visual Studio 2010的工程源码(版本是201x都可以)。

2).在编译运行之前请先在VS中配置好OpenCV(网上搜索有很多图文并茂的教程),OpenCV的各个版本应该都兼容,我使用的是2.4.6。

3).这个工程源码不是个人编写,而是我直接从OpenCV中拷贝出来的。

  完成上述配置之后你会发现项目中的源文件有以下几项:

  camera_calibration.cpp----相机标定的源码

  in_Arlco_Camera_data.xml----某款相机的标定参数配置文件

  Arlco_Camera.xml----某款相机的标定用图片索引文件

  in_Logitech_C170.xml----另一款相机的标定参数配置文件

  Logitech_C170.xml----另一款相机的标定用图片索引文件

此时如果点击运行则标定的是Arlco相机,且标定使用的是预先拍好的图片。

2.相机标定的配置过程。

  经过第一部分的介绍,下面你要做的就是更改配置来标定你自己的相机(注意:这个时候你已经打印了一张自己的标定黑白棋盘),请紧跟下列步骤:

1).在工程目录中找到文件in_Arlco_Camera_data.xml,复制一份改个名字如:in_YourCam_Camera_data.xml 放置在同样的文件夹下,表示这是你自己的相机标定配置文件。

2).修改camera_calibration.cpp源代码中的217行

    const string inputSettingsFile = argc > 1 ? argv[1] : "in_Arlco_Camera_data.xml";

改为你刚才复制的自己的配置文件,例如:

    const string inputSettingsFile = argc > 1 ? argv[1] : "in_YourCam_Camera_data.xml";

3).修改你自己的相机标定配置文件in_YourCam_Camera_data.xml,具体如下:

<!-- Number of inner corners per a item row and column. (square, circle) -->
<BoardSize_Width>7</BoardSize_Width>
<BoardSize_Height>5</BoardSize_Height>

这一步配置你的横向和纵向角点(黑白相交的点)数,如下图所示。我的是横向7个,纵向5个,请根据自己的标定棋盘更改相应的数目。

1 <!-- The size of a square in some user defined metric system (pixel, millimeter)-->
2   <Square_Size>30</Square_Size>

这个定义的是你的棋盘格的尺寸,我的是30mm,请根据自己的做更改。

  <!-- The type of input used for camera calibration. One of: CHESSBOARD CIRCLES_GRID ASYMMETRIC_CIRCLES_GRID -->
  <Calibrate_Pattern>"CHESSBOARD"</Calibrate_Pattern>

这个定义的是你标定用的棋盘类型,如果你用的是黑白棋盘,不用修改。

 <Input>"Arlco_Camera.xml"</Input>
  <!--  If true (non-zero) we flip the input images around the horizontal axis.-->
  <Input_FlipAroundHorizontalAxis>0</Input_FlipAroundHorizontalAxis>

这个指定的是你标定的时候采用的方式,支持一下三种:

a. 用预先拍好的带有标定棋盘的照片进行标定。(本文采用的标定方式,下面将具体介绍方法)

b.用预先录制好的视频进行标定(支持AVI格式)。用"/tmp/x.avi"代替源码中的"Arlco_Camera.xml"即可,其中x.avi是你录制好的带有棋盘的视频。

c.打开相机边录制边标定。用“1”代替源码中的"Arlco_Camera.xml"即可。

如果采用a方法,需要工程目录中找到文件Arlco_Camera.xml,复制一份改个名字如:YourCam_Camera.xml 放置在同样的文件夹下。这个里面指定了标定用的照片的存放位置和名称,具体代码如下:

<?xml version="1.0"?>
<opencv_storage>
<images>
imges/1.jpg
imges/2.jpg
imges/3.jpg
imges/4.jpg
imges/5.jpg
imges/6.jpg
imges/7.jpg
imges/8.jpg
imges/9.jpg
imges/10.jpg
imges/11.jpg
imges/12.jpg
imges/13.jpg
imges/14.jpg
imges/15.jpg
imges/16.jpg
imges/17.jpg
imges/18.jpg
imges/19.jpg
imges/20.jpg
imges/21.jpg
imges/22.jpg
imges/23.jpg
imges/24.jpg
imges/25.jpg
imges/26.jpg
imges/27.jpg
</images>
</opencv_storage>

你不需要修改,只需要把工程目录下的imges文件夹里的图片换成你自己的就可以了,图片名称还是用1~27的数字。

继续回到in_YourCam_Camera_data.xml文件修改参数:

  <!-- How many frames to use, for calibration. -->
  <Calibrate_NrOfFrameToUse>27</Calibrate_NrOfFrameToUse>

这里27指定了你预先拍照的数量,可以修改,但是需要相应的修改YourCam_Camera.xml文件。

  <!-- The name of the output log file. -->
  <Write_outputFileName>"out_Arlco_Camera_data.yml"</Write_outputFileName>

这里指定的是你的标定参数保存的文件名称,用自己的名字如:out_YourCam_Camera_data.yml 代替:out_Arlco_Camera_data.yml 即可。

ok,其余的参数用默认即可,这个时候请把你修改好的文件:in_YourCam_Camera_data.xml 和 YourCam_Camera.xml 添加到工程项目的源码中。

  此时点击运行口可以标定你自己的相机了,最后的结果会保存在工程目录下,名字就是上一步你自己设置的out_YourCam_Camera_data.yml。

标定过程如下图所示:

完成后你就可以看到相机内参、外参以及畸变系数了,部分数据如下:

%YAML:1.0
calibration_Time: "09/02/17 14:27:10"
nrOfFrames: 27
image_Width: 1280
image_Height: 720
board_Width: 7
board_Height: 5
square_Size: 30.
FixAspectRatio: 1.
# flags:  +fix_aspectRatio +fix_principal_point +zero_tangent_dist
flagValue: 14
Camera_Matrix: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 1.0078520005023535e+003, 0., 6.3950000000000000e+002, 0.,
       1.0078520005023535e+003, 3.5950000000000000e+002, 0., 0., 1. ]
Distortion_Coefficients: !!opencv-matrix
   rows: 5
   cols: 1
   dt: d
   data: [ -4.9694653328469340e-002, 2.3886698343464000e-001, 0., 0.,
       -2.1783942538569392e-001 ]
Avg_Reprojection_Error: 6.4271522441441153e-001
Per_View_Reprojection_Errors: !!opencv-matrix
   rows: 27
   cols: 1
   dt: f
   data: [ 3.89407665e-001, 4.69866753e-001, 3.74819994e-001,
       4.79580641e-001, 2.85050988e-001, 3.93756509e-001,
       9.21430171e-001, 7.79153645e-001, 6.87648296e-001,
       6.19106829e-001, 6.83992207e-001, 6.41160131e-001,
       2.52024829e-001, 2.94729859e-001, 4.55538809e-001,
       7.44070828e-001, 4.21751559e-001, 5.13929784e-001,
       6.03685081e-001, 1.09411442e+000, 1.20731401e+000,
       8.70341241e-001, 3.22936684e-001, 4.73881990e-001,
       8.06841075e-001, 6.78049505e-001 ]

我用的图片是1280x720的,这个数据是根据你用的标定图片得出的。

3.总结

  本文是为视觉入门者准备的,后续我会陆续介绍在linux下的标定过程,包括用其他开源库如ArUco等的标定方法。

作者:Shawn

时间: 2024-10-24 11:20:45

基于OpenCV单目相机的快速标定--源码、工程、实现过程的相关文章

单目相机测距

单目测距的小项目,大概需要就是用单目相机,对一个特定的目标进行识别并测算相机与该目标的距离.所以便去网上找了一堆教程,这里给大家总结一下,希望给小白们一个参考. 首先是基本需求了 opencv自然要会的,这咱就不多说了,会一点就行 需要一个摄像头,我用的是一个畸变很大的鱼眼免驱动摄像头,大家用电脑上的那个自带摄像头也可以的,就是不方便. 需要MATLAB进行相机标定 其实上面都是废话,下面进入正题吧. 网上的方法大概有两种,这里主要介绍一个我身边的大哥们都称做PnP问题的一个方法,但会另外简单介

基于Linux平台下网络病毒Caem.c源码及解析

Came.c型病毒在这里主要修改了用户的密码,同时对用户的终端设备进行了监视.希望与大家共同交流 转载请注明出处:http://blog.csdn.net/u010484477     O(∩_∩)O谢谢 #define HOME "/" #define TIOCSCTTY 0x540E #define TIOCGWINSZ 0x5413 #define TIOCSWINSZ 0x5414 #define ECHAR 0x1d #define PORT 39617 #define BU

基于Windows Socket的安全通信(C++实现,附源码)

先了解一下Socket的相关函数原型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //加载套接字库 int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData); //释放套接字库资源 int PASCAL FAR WSACleanup(void); //创建套接字 SOCKET PASCAL FAR socket (int af,int type,int pr

Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现

如果Spark的部署方式选择Standalone,一个采用Master/Slaves的典型架构,那么Master是有SPOF(单点故障,Single Point of Failure).Spark可以选用ZooKeeper来实现HA. ZooKeeper提供了一个Leader Election机制,利用这个机制可以保证虽然集群存在多个Master但是只有一个是Active的,其他的都是Standby,当Active的Master出现故障时,另外的一个Standby Master会被选举出来.由于

iOS 滚动label(LED,跑马灯等) 快速实现源码

ios  滚动label  快速实现源码.这里使用的两个label,挪动frame实现.简单使用,这里仅抛砖引玉而已 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSString *str = @"I love you,IOS-文字滚动的Label!"; self.scrollLabel = [[UI

【开源下载】基于winform的xml菜单编辑器(c#源码)

xml编辑器源码 最近帮朋友做了一个档案管理系统,客户端能够把文件上传到服务器,也能够从服务器下载,支持多用户.通讯框架使用的networkcomms v3框架. 这个档案管理系统中用到了树形目录,使用人员需要随时调整左侧的目录,考虑到使用数据库的比较繁琐,就想到了一个方法,即可以在客户端编辑左侧的那个目录,保存成一个xml文件.修改完成后需要的话可以把这个xml文件上传到服务器,其他人员可以从服务器加载这个xml文件.虽然简单,但也比较好的满足了朋友的需求.今天刚好有时间,把左侧目录的编辑页面

根据MATLAB的histeq函数改写的运行在OpenCV下的直方图规定化C源码!

据说,图像的直方图规定化比直方图均衡化用得更多,但是很奇怪的是OpenCV居然没有图像直方图规定化的源码!所以,我就有必要在OpenCV下写一个图像直方图规定化处理的函数,以方便将来使用. 我在网上找了几个直方图均稀化的源码,并基于OpenCV来改写这些源码,效果都不如MATLAB的histeq函数,这其中改写的艰辛与繁琐就不细说了.最后,没办法,只好学习MATALB的histeq函数源码,并对其进行基于OpenCV的改写. 虽然我最终改写成功了,但是对算法还是不太理解,只能按照MATLAB的帮

Spring 4 MVC 表单校验资源处理(带源码)

[本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看] [翻译 by 明明如月 QQ 605283073] 上一篇:Spring 4 MVC HelloWorld 纯注解方式(带源码) 下一篇文章:Spring 4 MVC 视图解析器(XML JSON PDF等) 纯注解 #项目下载地址:http://websystique.com/?smd_process_download=1&download_id=1258# 本文我们将学习使用Spring 表单标签( Spring

如何快速阅读源码

本文探讨在需要了解一个开源项目时,如何快速的理清开源项目的代码逻辑! 以下是个人认为行之有效的方法: 先「跑起来」 自顶向下拆解 深入细节 延伸改进 本文以Mybatis为例来进行演示! 先"跑起来" 程序界有个老传统,学习新技术时都是从「Hello World」开始的!无论是学习新语言时,打印「Hello World」:还是学习新框架时编写个demo!那为什么这里的「跑起来」要打个引号呢? 实际上,当你想要阅读一个开源项目的源码时,绝大部分情况下,你已经能够使用这个开源项目了!所以这