联合zed双目相机进行双目相机标定

1.获取左右相机拍摄的图片

我是用zed双目相机自带的sdk拍摄的图片,左右相机一共拍摄了20张,对获取的图片根据自己的halcon程序需要进行重命名

opencv双目测量_数码相机

2.打开halcon 软件

在放置左右相机的图片文件夹下创建halcon程序(这里是为了方便后面对图片进行读取)

3.写程序

3.1 读取左右相机拍摄的第一张图片

* 1.读取第一幅图片以获取他们的尺寸大小
read_image (ImageL, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_l_01.png')
read_image (ImageR, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_r_01.png')

3.2 打开两个适合图片大小的窗口

* 2.打开一个适合图片大小的窗口
dev_close_window ()
dev_update_off ()
get_image_size (ImageL, WidthL, HeightL)
dev_open_window (0, 0, WidthL/4, HeightL/3, 'black', WindowHandle1)
dev_set_draw ('margin')
dev_set_color ('green')
dev_set_window (WindowHandle1)
dev_display (ImageL)
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
get_image_size (ImageR, WidthR, HeightR)
dev_open_window (0, WidthL/4 + 12, WidthL/4, HeightL/3, 'black', WindowHandle2)
dev_set_draw ('margin')
dev_set_color ('green')
dev_set_window (WindowHandle2)
dev_display (ImageR)

显示效果如下图:

opencv双目测量_描述文件_02

3.3 写标定板的程序并且获取标定板中心点的位置:

其中caltab.descr是我提前创建好的标定板描述文件(也放在和该双目标定文件夹下)

* 3.读取标定板的描述文件(一般放到与此代码的同文件夹下)
CaltabFile := 'caltab.descr'
*从标定板的描述文件中读取每个点的中心坐标
caltab_points (CaltabFile, X, Y, Z)

3.4 创建两个相机内参的参数

我自己购买的ZED双目相机是有它自己的内参,输入进去就可以

* 4.给内部相机设置初始的参数(且左右相机一样)
gen_cam_par_area_scan_division (0.0000214726, -75.7052, 2.00213e-005, 2e-005, WidthL / 2.0, HeightL / 2.0, WidthL, HeightL, StartCamParL)
gen_cam_par_area_scan_division (0.0000214051, -58.1469, 2.00197e-005, 2e-005, WidthR / 2.0, HeightR / 2.0, WidthR, HeightR, StartCamParR)

下面是对后面要用到的参数进行一个设置,可以根据自己跑程序的时候报错而进行一个相应的调整,我一般都是先用它帮助文档自带的默认值,后面在进行调整3

* 给 find_caltab 和 find_marks_and_pose两个算子设置参数
SizeGauss := 3
MarkThresh := 120
MinDiamMarks := 5
StartThresh := 128
DeltaThresh := 10
MinThresh := 18
Alpha := 0.3
MinContLength := 15
MaxDiamMarks := 100

3.5 设置数组储存后面标定得到的相机参数

* 给左右两个相机创建相应的元组,来储存标定过程中所用到的行列坐标以及位姿
RowsL := []
ColsL := []
StartPosesL := []
RowsR := []
ColsR := []
StartPosesR := []

3.6 进行标定

前面的准备工作已经完成,现在可以进行循环读取图片进行标定

3.6.1 循环读取左右相机拍摄的那20张标定图片
for Index := 1 to 10 by 1
    * 5.1 读取标定的图片
    read_image (ImageL, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_l_'+ Index$'02d')
    read_image (ImageR, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_r_'+ Index$'02d')
3.6.2 对左右两个相机寻找标定板
* 5.2 寻找标定板(两个相机)
    find_caltab (ImageL, CaltabL, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)
    find_caltab (ImageR, CaltabR, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)
3.6.3 显示标定板的图片

 

* 5.3 显示标定板的标定图片
    dev_set_window (WindowHandle1)
    dev_display (ImageL)
    dev_display (CaltabL)
    dev_set_window (WindowHandle2)
    dev_display (ImageR)
    dev_display (CaltabR)

显示效果图:

opencv双目测量_相机标定_03

3.6.4 对左右两个相机拍摄的图片进行可视化和提取标点和姿态

 

* 5.4.1 提取标记和姿态,并对第二张图像的结果进行可视化(第一个相机)
    find_marks_and_pose (ImageL, CaltabL, CaltabFile, StartCamParL, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoordL, CCoordL, StartPoseL)
    disp_caltab (WindowHandle1, CaltabFile, StartCamParL, StartPoseL, 1)
    * 5.4.2 提取标记和姿态,并对第二张图像的结果进行可视化(第二个相机)
    find_marks_and_pose (ImageR, CaltabR, CaltabFile, StartCamParR, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoordR, CCoordR, StartPoseR)
    disp_caltab (WindowHandle2, CaltabFile, StartCamParR, StartPoseR, 1)

显示效果图:

opencv双目测量_opencv双目测量_04

3.6.5 将标定后得到的左右相机位姿储存到前面创建的元组中 
* 5.5 将标定好得到的点的行列坐标以及位姿参数放到前面所创建的元组中
    RowsL := [RowsL,RCoordL]
    ColsL := [ColsL,CCoordL]
    StartPosesL := [StartPosesL,StartPoseL]
    RowsR := [RowsR,RCoordR]
    ColsR := [ColsR,CCoordR]
    StartPosesR := [StartPosesR,StartPoseR]
endfor
stop ()

3.7 进行级线校正

到此处,双目左右相机的标定已经完成了,接下来是进行级线校正

* 6.标定完成后进行校正
binocular_calibration (X, Y, Z, RowsL, ColsL, RowsR, ColsR, StartCamParL, StartCamParR, StartPosesL, StartPosesR, 'all', CamParamL, CamParamR, NFinalPoseL, NFinalPoseR, cLPcR, Errors)

3.8 可以根据自己的需要将得到的校正后的数据进行保存 方便后面使用(我因为要做三维重建,所以我后面还会需要这数据) 

* 6.1 将得到的级线校正后的数据保存
 write_cam_par (CamParamL, 'cam_left-125.dat')
 write_cam_par (CamParamR, 'cam_right-125.dat')
 write_pose (cLPcR, 'pos_right2left.dat')

3.9 生成级线校正后的图

到此处就已经对级线校正完成,所需要得到的两个数据是MapL和MapR,后面进行效果展示的时候用得到 

* 7. 生成级线校正后的图
gen_binocular_rectification_map (MapL, MapR, CamParamL, CamParamR, cLPcR, 1, 'viewing_direction', 'bilinear', RectCamParL, RectCamParR, CamPoseRectL, CamPoseRectR, RectLPosRectR)

3.10 读取前面拍摄的一组图片进行级线校正验证

* 8. 获取之前获取的双目相机标定后的图片进行级线校正验证
read_image (ImageL, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_l_01.png')
read_image (ImageR, 'D:/graduate student/halcon/halcon study/example/2024-1-21日开始halcon学习/第九章 相机标定/calib_r_01.png')
* 9. 进行双目相机拍摄图片进行级线校正
map_image (ImageL, MapL, ImageRectifiedL)
map_image (ImageR, MapR, ImageRectifiedR)
* 10. 检查校正图像上的极线约束,
* 10.1 特征点行坐标之间的差异应该很小
* 10.2 并可视化结果(包括一些对应的极线)
check_epipolar_constraint (ImageRectifiedL, ImageRectifiedR, RectCamParL, RectCamParR, WindowHandle1, WindowHandle2, CaltabFile, EpipolarError)

 效果图如下:

opencv双目测量_相机标定_05