为什么张正友的相机标定算法不能够标定鱼眼镜头

不同角度的镜头有不同的畸变模型,比如多项式模型就适合视角比较小的镜头,分式模型或者scaramuzza多项式模型就适合视角比较大的镜头

这些模型都是去逼近实际镜头的畸变,畸变程度比较小的时候用的是传统多项式模型,畸变程度比较大的时候用分式模型或scaramuzza多项式模型

而无论是opencv还是matlab的标定工具箱,都有两种标定工具,一种是传统的视角比较小的相机标定,另外一种fisheye camera calibration。所以从这里也能够看出来区别,就是鱼眼相机不能够用传统的多项式进行标定

为了验证张正友标定工具里面的模型是否能够标定鱼眼镜头,我尝试用该标定方法去标定fov比较大的相机,看一下校正效果是怎么样的

我用matlab里面自带的gopro图片来用camera calibration toolbox标定得到畸变参数再进行校正看一下有什么效果。

在做这个实验之前,你们可以先看一下matlab这个例程,讲述的是一般镜头用张正友的标定算法标定,标定之后用得到的畸变参数来对图像进行校正(https://www.mathworks.com/help/vision/ref/undistortimage.html),从上面这个链接的example可以看出来,实际上张正友的方法中的畸变模型对于小程度的畸变的校正还是挺好的。

 

然后我用gopro图片,用同样的张正友的标定工具箱,得到标定结果之后进行畸变校正,

代码如下

images = imageDatastore(fullfile(toolboxdir('vision'),'visiondata', ...
    'calibration','gopro'));
[imagePoints,boardSize] = detectCheckerboardPoints(images.Files);
squareSize = 29;
worldPoints = generateCheckerboardPoints(boardSize,squareSize);
I = readimage(images,1);
imageSize = [size(I,1),size(I,2)];
cameraParams = estimateCameraParameters(imagePoints,worldPoints, ...
                                  'ImageSize',imageSize);
                              
I = images.readimage(1);
J1 = undistortImage(I,cameraParams);
figure; imshowpair(I,J1,'montage');
title('Original Image (left) vs. Corrected Image (right)');
J2 = undistortImage(I,cameraParams,'OutputView','full');
figure;
imshow(J2);
title('Full Output View');

 

如下图 

 

同样的一组图片,用另外的专用的fisheye camera calibration工具箱(也是matlab自带的)

images = imageDatastore(fullfile(toolboxdir('vision'),'visiondata', ...
    'calibration','gopro'));
[imagePoints,boardSize] = detectCheckerboardPoints(images.Files);
squareSize = 29; % millimeters
worldPoints = generateCheckerboardPoints(boardSize,squareSize);
I = readimage(images,1);
imageSize = [size(I,1) size(I,2)];
params = estimateFisheyeParameters(imagePoints,worldPoints,imageSize);
J1 = undistortFisheyeImage(I,params.Intrinsics);
figure
imshowpair(I,J1,'montage')
title('Original Image (left) vs. Corrected Image (right)')

J2 = undistortFisheyeImage(I,params.Intrinsics,'OutputView','full');
figure
imshow(J2)
title('Full Output View')

 

标定得到结果试一试

显然这个才是正常的结果

在这里还推荐scaramuzza的畸变校正toolbox(https://sites.google.com/site/scarabotix/ocamcalib-toolbox),是专门有两篇iros论文介绍这个工具箱,值得注意的是,该工具箱需求的matlab版本比较低,亲测matlab2016b是work的,高版本的matlab会出现长时间的卡顿现象,这个问题在作者提供的论坛里面有详细的描述。

 

用该标定工具箱对棋盘格图像进行标定,标定的step也是非常简单,仔细看官网介绍就好,标定结束之后会得到一个txt文件,包含畸变参数以及畸变中心等

作者开放了用于镜头校正的cpp文件,利用标定得到的txt文件,就可以对镜头进行快速进行校正。

前提是要求opencv,我在ubuntu上配置了opencv,cmakelist也比较好写

先贴上

project( visualize )
find_package( OpenCV REQUIRED )
add_executable( main main ocam_functions)
target_link_libraries( main ${OpenCV_LIBS} )

 

posted on 2020-12-19 01:00  YongjieShi  阅读(1001)  评论(0编辑  收藏  举报

导航