Opencv双目标定及图片校正

写在前面...

    原本以为很简单的东西,从早上10点卡到晚上12点,所以不记录以下有点对不住,言归正传...

一  双目标定

1.准备工作

从Opencv官方例子中找出clib文件,在Opencv/samples/cpp里面,有个stereo_calib.cpp文件,以及在Opencv/samples/data(本人用的是Opencv3.x)找出stereo_calib.xml文件.这个xml文件可以根据自己图片序列的图片文件名生成,也可以将自己的图片文件名改成stereo_calib.xml里面的那种格式.

https://github.com/opencv/opencv/blob/master/samples/cpp/stereo_calib.cpp

2.编译好代码,来看看运行参数

"Usage:\n ./stereo_calib -w=<board_width default=9> -h=<board_height default=6> -s=<square_size default=1.0> <image list XML/YML file default=../data/stereo_calib.xml>\n"

-w -h -s默认参数是9 6 1.0,坑就在这里,习惯地以为这是棋盘格的格子数目,但是仔细去查阅代码里面的这个函数

findChessboardCorners(timg, boardSize, corners,
    CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);

之前打log发现是这个函数找不到角点,但是确认自己格子是12*9的,格子大小是3cm(也就是这个s的单位,根据自己标定板的每个小格子大小来改).而w h(对于函数里面的boardsize),它并不是格子数目!而是格子内的交点数目!比如说下面这个棋盘格,在这个函数里面的参数应该就是-w=11,-h=8.

Opencv双目标定及图片校正

其他没有什么要修改的,相比matlab而言,opencv标的步骤稍微繁琐了点.

二 图像畸变校正

对极几何的概念在这就不阐述了,双目校正的目的就是让两个相机的极线处于同一水平线上,校正后一幅图上面点跟另一幅图像上与其对应的点有了相同的行号,那么做搜索的时候就是一维上面的搜索了,可以做双目匹配来求得两个相机之间的外参.

1.按照OpenCV官方给的例子(未调参),来看看一组校正后的图片

Opencv双目标定及图片校正

图像被严重阉割了(有点用词不雅哈).来看看代码里面双目校正这个函数

Opencv双目标定及图片校正

参数这里就不一一说明了,可以参考:

https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

注意下alpha这个参数,这是个*缩放的参数,默认值为-1,自己设置的话可以在0到1之间,如果设置为0的话,图像被放大  平移,校正后只有有效的像素可以看到,也就是去除了边缘黑色边框的图.如果将这个参数设置为1,则校正后整个图像的所有像素都会被保留下来(从原理上来将,这个时候图像的边缘是变形的).

alpha设置为0,实验效果如下,可见校正后将所有无效的像素(黑框)都去除了

Opencv双目标定及图片校正

alpha设置为0.5,可以看见有部分黑框存在,损失了部分像素

Opencv双目标定及图片校正

alpha设置为1,实验效果就是前面给的未调参时候的.

Opencv双目标定及图片校正

2.newImageSize这个参数,校正后图像的分辨率.默认参数为(0,0),也就是和原图像保持相同的分辨率,但是对应径向畸变比较大的情况下,最好把这个值设的大一点,这样可以保留原始图像中更多的细节.