使用MALTAB标定实践记录
记录一下整个相机的标定矫正过程,希望能够帮助到刚学习标定的童鞋们~
首先下载matlab calibration toolbox,百度搜索第一条就是了(http://www.vision.caltech.edu/bouguetj/calib_doc/)。下载到本地后,需要在MATLAB中更改主路径:
Set Path->Add with Subfolders->选定你刚下载的toolbox所在目录。
在command Window中敲calib加载图像,此时会弹出一个框框。注意你的Current Folder是标定图像所在的目录。
选择Standard(all the images are stored in memory)->Read images.
command 窗口中会显示当前目录下的所有文件,并要求你输入要矫正的相机图像的basename.我一般对需要矫正的图像会这样命名,方便后期的操作:左图(left_%d.jpg)右图(right_%d.jpg)。而这里要求的basename则是前缀中除开数字的部分,以矫正左图为例,那么就是输入left_
接下来会问你图像格式,注意这里能够接受的图像格式有(ras,bmp,tif,pgm,jpg,ppm),你根据你图像的实际格式输入,我这边是jpg格式。
回到那个toolbox中,选择Extract grid corners,提取角点。
它会问你是否处理所有图像,这个根据你自己的需求设定,默认是全部。包括后面会问到选择的框框的大小,默认值是长宽个15个像素。一般我是用默认值,但是注意一点就是如果你在扣角点的过程中框框已经太大将其他角点也包含进来,那么你就可以适当的调整这个框框的尺寸。所有的图像按照一定的方向(我习惯是顺时针)扣四个角点。如图中绿色圈圈的位置。第一张图会问你关于棋格的尺寸,你根据你的实际情况来填就好,我这里是100mm。
所有的图像都抠完角点后,选择Calibration,进行标定,如果标定参数正常,则保存下来。因为我会标定左右摄像头得到的图像,因此后面还需要进行双目标定。因此这里得到标定的参数文件后我会先改它的命名,为了后面双目标定做准备。
提醒一点。在标定完左相机需要标定右相机的时候,先clear all 一下,再重新开始。
双目标定:
clear all 后,输入 stereo_gui->Load left and right calibration files->Run stereo calibration->Save stereo calib results
双目标定便结束了。
标定后我们就得到了左右摄像机的内外参数。Focal Length是焦距,我们一般在立体视觉中基于左图来计算,故需要的fx fy就是左摄像机的Focal Length参数。Principal point是主点,常用cu,cv表示。Skew这里指的是图像中U轴和V轴的夹角与90°的差值,一般来说数值是接近于0的。Distortion则是畸变参数。在立体匹配中我们常常看见的一个baseline参数,就在这里Translation vector中的x值。获取了相机内外参数后,我们需要对这对相机获取的图像进行矫正。具体的矫正程序放在github上了有兴趣的可以下载来看看。将刚刚标定得到的参数放上去运行就能得到矫正后的图像了。
https://github.com/RebeccaTsang/Rectify
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
分割线
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在实践过程中遇到了一些问题,也借这个机会在这里做一下笔记。
用MATLAB读取图像的时候,对图像的命名要求比较高,建议像我这样命名即(basename+id.jpg)比较方便。可问题是我们得到数据时命名往往不是按照我们想的那样命名,这时候就需要批量命名。在Windows下和Ubuntu下的方法各异,我是在Ubuntu下做的实践,那我介绍一下Ubuntu下的批量命名方式吧。
这里我就不讲具体的原理和语法,百度Ubuntu 批量重命名/批量改后缀名 都介绍了很多方法和语法在里面。我这里只讲我是怎么做的。
最开始我得到的图像命名是这样的,首先我要改图像的后缀名,注意的是png格式是可以改成jpg格式的,而jpg格式不能直接改为png格式。
在该目录下打开终端:
mogrify -format jpg *.png rm *.png
上面两步的意思是将所有png格式的图像生成一个jpg格式的,再把所有png图像删掉。
rename -n 's/^/left_/' *l.jpg rename -f 's/^/left_/' *l.jpg rename -n 's/_l//' *l.jpg rename -f 's/_l//' *l.jpg
这里-n是显示你即将要重命名的文件以及重命名后的结果,但是仅仅是显示,而非真正的改动。-f则是真正的执行重命名的命令。
头两句的意思是指在文件名最前面,“^"指的是最前面,添加left_。这样我们得到的命名是left_xxxx_l.jpg。
后面的_l是我们不需要的,则需要后面的两句话执行,将命名中的”_l"替换为空。
值得注意的是这里的1,3句我们是仅用作显示,看看这个结果是不是我们想要的,不打也可以。最后结果为:
注意到尽管现在的命名格式已经符合规范,但是数字编号不是按顺序的,就需要对这个数字进行重新编号。
新建一个文档,命名为ren.sh。内容为一下这段代码,可以将所有right_xxxx.jpg的文件重新从0开始编号。同理,这是针对右图的,左图的话更改right为left就可以了。
#!/bin/bash j=0; for i in `seq -f "right_%04g.jpg" 0 5000`; do #echo $i if [ -f $i ]; then echo $i "exist"; mv $i right_$j.jpg let j+=1; fi done
在相应目录下打开终端,执行
./ren.sh
便得到以下结果: