HALCON 2D高精密测量项目全流程解析

1.标定相关的任务–>>解决畸变和坐标系的转换

1.1 描述和查找标定对象

1.2 补偿透视和径向变形,径向畸变包括枕形畸变和桶形畸变

1.3 相机参数(内外参)

1.4 图像坐标到世界坐标的转换

1.5 自标定:不用标定板用图像四周包含直线特征进行标定

1.6 其他标定:一台相机标定、多台相机标定、手眼标定

2.分割模型(Division)

分割模型使用一个参数(k)对径向变形进行建模,光学中心就在图像中心

【k>0枕形畸变】 【k=0没有畸变】 【k<0桶形畸变】

[‘area_scan_division’,Focus,Kappa,Sx,Sy*,Cx,Cy,ImageWidth,ImageHeight]

Focus:焦距

Kappa:k值,初始值为0

Sx,Sy*:中心缩放比例

Cx,Cy:图像中心

ImageWidth,ImageHeight:图像大小

3.多项式模型(polynomial):光学中心可能不在图像中心

多项式模型使用三个参数(K1,K2,K3)对径向变形进行建模,并使用两个参数(P1,P2)对偏心变形进行建模

[‘area_scan_polynomial’,Focus,K1 ,K2,K3,P1,P2,Sx,Sy*,Cx,Cy,ImageWidth,ImageHeight]

Focus:焦距

K1 ,K2,K3,P1,P2:多项式模型参数,初始值为0

Sx,Sy*:中心缩放比例

Cx,Cy:图像中心

ImageWidth,ImageHeight:图像大小

4.透视畸变

被摄物越远,显得越小;镜头离被摄体越远,被摄体外观上的大小变化越小

透视畸变术语三维畸变的范畴,同意姿态可以看作为透视变化的特殊形式。单相机无法解决透视畸变

单相机和四轴机器人标定的主要误差也是透视畸变

5.倾斜镜头:旋转描述旋转轴的方向,倾斜度描述了镜头的实际倾斜度

area_scan_tilt_ * 普通FA镜头倾斜

area_scan_tilt_image_side_telecentric_* 像方倾斜

area_scan_tilt_object_side_telecentric_* 物方倾斜

area_scan_tilt_bilateral_telecentric_* 双远心倾斜

【tilt 倾斜】【bilateral 双边】【telecentric 远心】

6.相机标定内参

CameraType:摄像机类型

Focus:镜头焦距(仅适用于在镜头物侧执行透视投影的镜头,远心镜头设置0)初始值为所用镜头的标称焦距,例如0.008mm

Magnification:镜头的放大倍率(仅用于物侧远心镜头)

Kappa(K):变形系数,用于建模镜头的径向和偏心变形(仅用于多项式模型),将0.0用作所有五个系数的初始值

ImagePlaneDist:镜头出瞳(小孔)到像平面(Sensor)的距离

Tilt,Rot:旋转轴是广州相对于传感器平面法线倾斜的角度。旋转角度是围绕光轴(z轴)的旋转。这些角度通常基于导致使用倾斜透镜的考虑因素而大致已知,或者可以从倾斜透镜的机构中读取

Sx,Sy:比例因子

Cx,Cy:径向畸变的中心,使用图像的半宽和半高作为初始值

ImageWidth,ImageHeight:采样图像的宽度和高度

Vx,Vy,Vz:运行矢量的X,Y和Z分量(先扫模型)

在这里插入图片描述

7.六边形标定板

7.1 至少看到一种取景器图案才能找到校准板。为了确保印版没有倒转,至少需要看到二个。
  7.2 坐标系的起点位于第一个取景器图案的中心标记的中心。坐标系的z轴指向校准板, x轴指向右侧, y轴指向下方,沿z轴方向观察。
  7.3 优点:标定板不必在图像中完全可见

对应算子:create_caltab

在这里插入图片描述
在这里插入图片描述
Halcon标定程序,使用标定助手会更简单

*create_caltab生成六边形标定板
*标定的Marks点,13行每行15个Mark,相邻Mark相距0.0015m
*五组六边形坐标,其行列坐标是[6,2,2,10,10], [7,2,12,2,12]
*.cpd为描述文件,.ps是可以直接打印的文件
create_caltab (13, 15, 0.0015, [6,2,2,10,10], [7,2,12,2,12], ‘dark_on_light’, ‘calplate.cpd’, ‘calplate.ps’)

  • Calibration 01: Code generated by Calibration 01
    ImageFiles := []
    ImageFiles[0] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161013501.bmp’
    ImageFiles[1] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161023237.bmp’
    ImageFiles[2] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161038073.bmp’
    ImageFiles[3] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161105778.bmp’
    ImageFiles[4] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161126403.bmp’
    ImageFiles[5] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161137323.bmp’
    ImageFiles[6] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161143684.bmp’
    ImageFiles[7] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161149840.bmp’
    ImageFiles[8] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161157518.bmp’
    ImageFiles[9] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161201848.bmp’
    ImageFiles[10] := ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161229559.bmp’
    TmpCtrl_ReferenceIndex := 0
    TmpCtrl_PlateDescription := ‘D:/标定/calplate.cpd’
    选择分割模型 0.458是放大倍率(投影模型选择圆心) 单个像元的宽高是4.5μm 图像大小是51205120
    StartParameters := [‘area_scan_telecentric_division’,0.458,0,0.0000045,0.0000045,2560,2560,5120,5120]
    TmpCtrl_FindCalObjParNames := ‘sigma’
    TmpCtrl_FindCalObjParValues := 1

  • Calibration 01: Create calibration model for managing calibration data
    create_calib_data (‘calibration_object’, 1, 1, CalibHandle)
    set_calib_data_cam_param (CalibHandle, 0, [], StartParameters)
    set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription)

  • Calibration 01: Collect mark positions and estimated poses for all plates
    for Index := 0 to |ImageFiles|-1 by 1
    read_image (Image, ImageFiles[Index])
    find_calib_object (Image, CalibHandle, 0, 0, Index, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues)
    endfor

  • Calibration 01: Perform the actual calibration
    set_calib_data (CalibHandle, ‘camera’, 0, ‘excluded_settings’, [])
    calibrate_cameras (CalibHandle, TmpCtrl_Errors)
    *CameraParameters内参
    get_calib_data (CalibHandle, ‘camera’, 0, ‘params’, CameraParameters)
    get_calib_data (CalibHandle, ‘calib_obj_pose’, [0, TmpCtrl_ReferenceIndex], ‘pose’, CameraPose)

  • Calibration 01: Adjust origin for plate thickness
    *CameraPose外参
    set_origin_pose (CameraPose, 0.0, 0.0, 0.003, CameraPose)
    stop ()

  • Calibration 01: Sample code generated by Calibration 01

  • Calibration 01: For demonstration purposes, we use the calibration

  • Calibration 01: plate itself as sample object.

  • Calibration 01: Therefore, we load the reference image
    read_image (Image, ‘D:/001-Projects/0003-H21直径测量/4-15/标定/DownLeft/Image_20210415161013501.bmp’)

  • Calibration 01: Extract plate data from the image
    TmpCtrl_PlateDescription := ‘D:/标定/calplate.cpd’
    TmpCtrl_FindCalObjParNames := ‘sigma’
    TmpCtrl_FindCalObjParValues := 1

  • Calibration 01: Create calibration model for managing calibration data
    create_calib_data (‘calibration_object’, 1, 1, CalibHandle)
    set_calib_data_cam_param (CalibHandle, 0, [], CameraParameters)
    set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription)
    find_calib_object (Image, CalibHandle, 0, 0, 0, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues)
    get_calib_data_observ_points (CalibHandle, 0, 0, 0, TmpCtrl_MarkRows, TmpCtrl_MarkColumns, TmpCtrl_Ind, CameraPose)

  • Calibration 01: Using the calibration plate as test object, the marks actually

  • Calibration 01: lie above the corrected measurement plane. Therefore, we ‘uncorrect’

  • Calibration 01: the plane of measurement by the plate thickness here.
    *0.003是标定板的厚度
    set_origin_pose (CameraPose, 0.0, 0.0, 0.003, CameraPose)

  • Calibration 01: **********************************************************

  • Calibration 01: Sample Task: Transform measurements into world coordinates

  • Calibration 01: **********************************************************

  • Calibration 01: First, obtain the image coordinates of some points of interest

  • Calibration 01: lying in the reference plane. Here, we simply take the first

  • Calibration 01: two mark center points of the plate
    TmpCtrl_ImageRows := [TmpCtrl_MarkRows[0], TmpCtrl_MarkRows[12]]
    TmpCtrl_ImageColumns := [TmpCtrl_MarkColumns[0], TmpCtrl_MarkColumns[12]]

  • Calibration 01: A line between the two points, just for visualization
    gen_contour_polygon_xld (TmpObj_ImageContour, TmpCtrl_ImageRows, TmpCtrl_ImageColumns)

  • Calibration 01: Convert image coordinate to world coordinates (using [mm])

  • Calibration 01: The Z coordinates will be 0 by definition (on reference plane)
    image_points_to_world_plane (CameraParameters, CameraPose, TmpCtrl_ImageRows, TmpCtrl_ImageColumns, ‘mm’, TmpCtrl_WorldX, TmpCtrl_WorldY)

  • Calibration 01: Determine the distance in world coordinate [mm]
    distance_pp (TmpCtrl_WorldY[0], TmpCtrl_WorldX[0], TmpCtrl_WorldY[1], TmpCtrl_WorldX[1], TmpCtrl_Distance)
    *pixel距离
    distance_pp (TmpCtrl_MarkRows[0], TmpCtrl_MarkColumns[0], TmpCtrl_MarkRows[12], TmpCtrl_MarkColumns[12], Distance)
    *一个像素多少毫米
    cali:=TmpCtrl_Distance/Distance
    stop ()

8.三角形标定板

该板必须在图像中完全可见。原点位于校准板表面的中间。坐标系的z轴指向校准板, x轴指向右侧, y轴指向下方,沿z轴方向观察。

对应算子:gen_caltab

在这里插入图片描述

9.Halcon的标定步骤

9.1 准备校准输入数据 StartCamParam
  9.2 执行与实际校准 calibrate_cameras
  9.3 检查校准是否成功 (RMSE)
  9.4 相机参数CamParam(内参)
  9.5 校准过程的其他信息:
    获得合适的校准板
    拍摄一组合适的图像
    使用哪种失真模型
    可用的3D相机模型以及3D点如何转换为图像坐标系

标定过程
1.准备标定板 标定板参数
2.相机内参初始化、标定模型
3.准备标定图像
4.标定内参、外参(外参是用其中一张标定板标定出基于此标定板的位姿)
5.评估标定结果(Error=RMSE)

Halcon示例
ImgPath := ‘3d_machine_vision/calib/’
dev_close_window ()
dev_open_window (0, 0, 652, 494, ‘black’, WindowHandle)
dev_update_off ()
dev_set_draw (‘margin’)
dev_set_line_width (3)
set_display_font (WindowHandle, 14, ‘mono’, ‘true’, ‘false’)
*

  • Calibrate the camera.

*初始化标定板参数
*0.016 焦距
*0 Kappa初始值
*0.0000074, 0.0000074 X和Y像素当量
*326, 247 图像中心
*652, 494 图像大小
gen_cam_par_area_scan_division (0.016, 0, 0.0000074, 0.0000074, 326, 247, 652, 494, StartCamPar)
create_calib_data (‘calibration_object’, 1, 1, CalibDataID)
set_calib_data_cam_param (CalibDataID, 0, [], StartCamPar)
*设置描述信息
set_calib_data_calib_object (CalibDataID, 0, ‘caltab_30mm.descr’)
*描述一个X和Y方向黑点个数为7、间距为0.0125、标定比例0.5、caltab.descr:生成的标定板文件

  • gen_caltab (7, 7, 0.0125, 0.5, ‘caltab.descr’, ‘caltab.ps’)
    NumImages := 10
  • Note, we do not use the image from which the pose of the measurement plane can be derived
    for I := 1 to NumImages by 1
    read_image (Image, ImgPath + ‘calib_’ + I$‘02d’)
    dev_display (Image)
    *寻找标定板
    find_calib_object (Image, CalibDataID, 0, 0, I, [], [])
    get_calib_data_observ_contours (Caltab, CalibDataID, ‘caltab’, 0, 0, I)
    dev_set_color (‘green’)
    dev_display (Caltab)
    endfor
    *执行标定
    *Error:成功校准后,以像素为单位返回优化的反投影的均方根误差(RMSE),如果与0.1相差较大,则校准效果不佳
    calibrate_cameras (CalibDataID, Error)
    curIndex:=10
    *获取内参
    get_calib_data (CalibDataID, ‘camera’, 0, ‘params’, CamParam)
    *获取外参:位姿
    *先读取一个标定板,读取基于此标定板下的相机的位姿
    *所以只需要一张标定板图像就可以获取相机的外参(基于此标定板的外参),Index是索引为10的标定板图像
    get_calib_data (CalibDataID, ‘calib_obj_pose’, [0,curIndex], ‘pose’, CameraPose)
    disp_3d_coord_system (WindowHandle, CamParam, CameraPose, 0.01)
    CalTabThickness:=0.5
    *重新设置原点,Z方向偏移0.5
    set_origin_pose (CameraPose, 0, 0, CalTabThickness, PoseNewOrigin)
    disp_3d_coord_system (WindowHandle, CamParam, PoseNewOrigin, 0.01)
  • Write the internal camera parameters to a file
    write_cam_par (CamParam, ‘camera_parameters.dat’)
    Message := ‘Interior camera parameters have’
    Message[1] := ‘been written to file’
    disp_message (WindowHandle, Message, ‘window’, 12, 12, ‘red’, ‘false’)
  • clear_calib_data (CalibDataID)

10.标定过程中注意事项

10.1 标定过程中请勿更改相机设置 位置、光圈、焦距

10.2 标定板的放置
    标定板的每个部分均应至少被图像覆盖一次。校准板也可以填充整个图像
    倾斜角度, 校准图像集还应包含带有倾斜校准板的图像。大约30-45°的角度沿不同方向倾斜,如果景深而无法实现推荐的角度,则应至少在设置时使板倾斜得尽可能陡。
    图像数量/校准板姿势,六边形的最少6张,至少4张带有倾斜,三角形最少15张。
  10.3 不允许倒置
  10.4 标记直径应至少为20个像素,建议40个像素左右,即一个黑点的直径为40
  10.5 校准板的明暗区域之间的对比度应至少为100灰度值,亮区域不要设置为255,不要过曝(不要超过240)
  10.6 避免过曝,浅色部分的灰度值不超过240
  10.7 校准板应均匀照明,并应避免反射,相同颜色区域灰度值范围不应超过45

11.两种标定模型对比

11.1 分割模型使用一个参数来建模径向变形,而多项式模型使用五个参数来建模径向变形和偏心变形

11.2 校准图像少,或者没有充分覆盖视野, 则分割模型通常会比多项式模型产生更稳定的结果。

11.3 项式模型的主要优点是它可以更精确地对变形进行建模,并且还对偏心变形进行了建模,缺点是计算慢
  11.4 通常,应使用分割模型进行校准。如果校准的准确性不够高,则可以使用多项式模型

  1. 获取相机姿态

TransX:相机沿坐标系的x轴平移。
  TransY:相机沿坐标系的y轴平移。
  TransZ:相机沿坐标系的z轴平移。
  RotX:相机绕坐标系的x轴旋转。
  RotY:相机绕坐标系的y轴旋转。
  RotZ:相机绕坐标系的z轴旋转
  Order:旋转链 ,先旋转那个后旋转那个,其结果不一样

  1. image_points_to_world_plane

在这里插入图片描述

gen_image_to_world_plane_map

在这里插入图片描述

14.通用标定模型在精密检测中缺点

14.1 要求多张图片拟合,实际项目中不好操作,特别是现场需要重新标定的时候很麻烦
  14.2 视野中标定板区域不能有遮挡,但是很多项目视野中有夹具遮挡的

14.3 主要受标定条件影响是精度不高

思考:能否用一张图标定畸变、标定大小区域不变的无畸变图? 答案:可以

15.面补:每一个mark点的坐标是真实无畸变的坐标,二次元坐标去找最近的Mark点坐标

在标定过程中对所有的mark点都走一遍,记录下真实无畸变的Mark坐标,只有Offset才有畸变,前提是Mark点足够密

在这里插入图片描述

16.面补的计算步骤

16.1 得到标定板点间距pix,计算初始像素当量scale
  16.2 行列排序,像素坐标和标定板坐标映射[row,col][x,y]
  16.3 优化像素当量
  16.4 计算标定板偏移位置和角度
  16.5 标定板左上角0点对齐
  16.6 更新映射关系[row,col][x,y]

  1. 网格矫正 gen_grid_rectification_map

网格整流的基本原理是,从畸变的图像到对齐图像的映射是根据对齐网格的畸变图像确定的

18.自定义网格

要使用自定义网格,则网格点必须由您自己定义gen_arbitrary_distortion_map、 可用于确定映射

问题: 1、遮挡的网格重新的Map会有黑洞——虚拟填充孔洞数据
      2、网格点位置不同,裁剪出来的图像大小和起点不同——左上角对其,裁剪图像
19. EasyVision的思路:GenArbitraryDistortionMap 精密测量的自定义网格标定

19.1 计算像素当量(参考上面)
  19.2 左上角为0点虚拟构造所有标准点
  19.3 提取角点和标准点坐标对齐
  19.4 使用构建点补充空白对齐提取点
  19.5 创建Map
  19.6 使用Map图,得到1: 1图像

在这里插入图片描述

20.至此径向畸变都已解决,唯有透视畸变还未解决。透视畸变是硬件的问题,使用远新镜头可很好消除透视畸变。

远心镜头,远心度越小越好
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值