OPENCV 相机标定(Camera Calibration)

在和openCV的camera calibration亲切玩耍了两周后,来和大家分享一下经验:

讨论项目在...\opencv\sources\samples\cpp\tutorial_code\calib3d\camera_calibration

1.我在做啥:

----看到花里胡哨地标定过程逐渐迷失自我.jpg

简而言之,廉价相机”凸眼看人弯“,于是乎我们用神秘的数学方法来修正这个问题。

openCV的教程文件里是这样的: 

OPENCV 相机标定(Camera Calibration)_第1张图片

 看了一眼,看不懂--没关系,这并不重要,重要的是:你知道了这个项目最终给了你九个重要的数字。

畸变参数(distortion coefficients)

相机矩阵 (camera martix)

获得这些参数后,不论我们用这个相机(相同焦距)拍出了多扭曲的N张照片,我们都能通过召唤openCV的这两个函数来initUndistortRectifyMap,remap 来修正我们的图片了。

2. 具体点,咋获得参数

简单,拿出你的国际象棋棋盘,假装这是你臭美的gf,对着她一阵咔擦咔擦,各种姿态咔个二十来张,喂给程序就OK了。

比如这样:

。。。。。。

 3. 项目中止咋回事

如果项目中止,出现interrupt,那多半是你的输入值搞错了。

让我们来讨论三个输入输出文件:

  • in_VID5.xml (在这里输入参数)
  • VID5.xml (在这里保存n张图片的路径)
  • outputs_para.xml (输出的九个参数)

        在in_VID5.xml文件里,有三个至关重要的值:棋盘长(BoardSize_Height)、宽(BoardSize_Width),以及输入取样文件路径的位置(input)。输入错误,项目无法运行。

棋盘长宽是内角格数(如下图,长宽为6*4);文件路径是找到VID5.xml的绝对路径(absolute path)。

OPENCV 相机标定(Camera Calibration)_第2张图片

        VID5.xml里面装的是所有照片的储存路径。如果在标定棋盘中(draw the corner),突然停止,那么就是多半是你取样的文件路径输错了,即VID5.xml中的一串图片地址有误。

        具体数据会保存在一个叫outputs_para.xml的文件里:

OPENCV 相机标定(Camera Calibration)_第3张图片

3.  校正结果

当图像扭曲不是特别明显时,校正图似乎和原图(未校正的失真图)会看起来没多大差别。现在,注意校正图的四边是否有多出黑色边缘,若有则是校正过的表现。这是因为镜头将图像部分边缘拉伸,还原后,边缘没取到像素的位置设成黑色边界。

如果你校正后的图比没矫正还要扭曲,那么必然是矫正用的参数有问题。参数有问题,那就是取样的过程中出了毛病。请注意,校正的范围并不是根据棋盘纸在镜头视野内的相对大小来决定的。整张图片均会被“校正”。

当整张棋盘纸皆在拍摄视野范围内时,都能得出较合理校正结果—问题是校正精度不同。

当棋盘纸格子超过镜头范围,则该照片内角无法被提取。

4. 关于畸变参数的一个问题

 回顾一下畸变参数(distortion coefficients):

 畸变参数分为两种:切向畸变(tangential distortion)和径向畸变(radial distortion)。

切向形变是这样的:

查看源图像

简言之,镜头和物体不平行,长方形拍成梯形。

径向形变是这样的:

 OPENCV 相机标定(Camera Calibration)_第4张图片

就是直线变弯。 

(上两图均来自别处)

然后,k1,k2,k3是负责径向畸变(直线变弯的);p1,p2是负责切向畸变的(镜头不平行的)。

比较坑的是,虽然openCV提到了切向畸变的参数p1,p2,但是整个标定结束后并没有给出他俩的值

--看,是两个零蛋。

 所以,切向实际上是不管的。

有些时候,这个要紧,有时候并不,看你需求。

如果你想修正一下这个,也许你会说,那没事,我把镜头弄放平行就行了。没错,这样也行。但是有些廉价工业摄像机的镜头凸透镜没粘水平,所以可能,镜头看似水平而实非水平。

切向畸变 - 国内版 Bing images(引用图片)

(完)

BTW,有人想知道我是怎么愚蠢地处理切向校正的吗?

你可能感兴趣的:(opencv,c++)