勇哥的视觉实验:halcon标定助手自动生成代码的解读


halcon的标定助手完成标定后,是可以自动生成一些代码。它是很好的参考。

image.png



////////////////////标定数据Tuple////////////////

CameraParameters := ['area_scan_division',0.00928003,-1009.07,2.50105e-06,2.5e-06,1236.62,1005.87,2592,1944]
CameraPose := [0.00527608,-0.016633,0.174111,10.3202,3.44142,208.299,0]


///////////////////标定函数////////////////////////

* Calibration 01: Code generated by Calibration 01
open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default', -1, 'false', 'default', '94aab8005ad8_Microvision_MVEM500M', 0, -1, AcqHandle)
TmpCtrl_ReferenceIndex := 0
TmpCtrl_PlateDescription := 'C:/Program Files/MVTec/HALCON-19.11-Progress/calib/calplateHG30.cpd'
StartParameters := ['area_scan_division',0.008,0,2.5e-06,2.5e-06,1296,972,2592,1944]
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 19 by 1
    grab_image (Image, AcqHandle)
    find_calib_object (Image, CalibHandle, 0, 0, Index, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues)
    stop ()
endfor
* Calibration 01: Perform the actual calibration
calibrate_cameras (CalibHandle, TmpCtrl_Errors)
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
set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose)
stop ()
close_framegrabber (AcqHandle)


///////////////////由文件读取标定的内参与位姿////////////////////////

* Calibration 01: Code generated by Calibration 01
open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default', -1, 'false', 'default', '94aab8005ad8_Microvision_MVEM500M', 0, -1, AcqHandle)
read_cam_par ('C:/Users/Administrator/Desktop/左相机8005.cal', CameraParameters)
read_pose ('C:/Users/Administrator/Desktop/左相机8005.dat', CameraPose)
stop ()
close_framegrabber (AcqHandle)


///////////////////将测量结果转到世界坐标系////////////////////////

dev_close_window()
dev_update_off()

* Image Acquisition 01: Code generated by Image Acquisition 01
open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default',\
                   'force_ip=192.168.0.215/00:B0:9D:F5:DD:53/192.168.0.1/255.255.254.0', \
                   'false', 'default', '00b09df5dd53_PointGreyResearch_970230000000', 0, -1, AcqHandle)

read_cam_par ('C:/Users/Administrator.PC8-20191007LRY/Desktop/BFLY_LY_50M.cal', CameraParameters)
read_pose ('C:/Users/Administrator.PC8-20191007LRY/Desktop/BFLY_LY_50M.dat', CameraPose)


grab_image (Image, AcqHandle)
get_image_size(Image, Width, Height)
dev_open_window(0, 0, Width/3, Height/3, 'black', WindowHandle)

dev_display(Image)
TmpCtrl_PlateDescription := 'D:/Program Files/MVTec/HALCON-19.11-Progress/calib/calplateHG30.cpd'
TmpCtrl_FindCalObjParNames := 'sigma'
TmpCtrl_FindCalObjParValues := 1
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)

set_origin_pose (CameraPose, 0.0, 0.0, 0.0032, CameraPose)
*显示世界坐标系坐标轴
disp_3d_coord_system(WindowHandle, CameraParameters, CameraPose, 0.05)
TmpCtrl_ImageRows := [TmpCtrl_MarkRows[0], TmpCtrl_MarkRows[1]]
TmpCtrl_ImageColumns := [TmpCtrl_MarkColumns[0], TmpCtrl_MarkColumns[1]]

gen_contour_polygon_xld (TmpObj_ImageContour, TmpCtrl_ImageRows, TmpCtrl_ImageColumns)
image_points_to_world_plane (CameraParameters, CameraPose, TmpCtrl_ImageRows, TmpCtrl_ImageColumns,\
                             'mm', TmpCtrl_WorldX, TmpCtrl_WorldY)
distance_pp (TmpCtrl_WorldY[0], TmpCtrl_WorldX[0], TmpCtrl_WorldY[1], TmpCtrl_WorldX[1], TmpCtrl_Distance)


close_framegrabber (AcqHandle)

测量的时候,有意把标定板倾斜放置,让它在3D坐标上有变化。

image.png

测量到的两个圆心距离是2.01356mm,标准距离是2.0mm。

image.png


换个方向

image.png

再换个方向

image.png

可以看到,世界坐标系的轴跟着在变化。

也就是说标定块是可以区分3D方向的。

在3D坐标下变化,我们的测量结果基本上是一致的。


另外算子set_origin_pose (CameraPose, 0.0, 0.0, 0.0032, CameraPose) 是平移世界坐标原点,其中0.0032就是标定的时候填写的标定板的厚度。

勇哥发现这个值如果填写为0,则测量结果要更准确一些。(这个有点奇怪)



///////////////////将XLD轮廓变换到世界坐标系中////////////////////////

* 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, please take another calibration plate image
stop ()
grab_image (Image, AcqHandle)
* Calibration 01: Extract plate data from the image
TmpCtrl_PlateDescription := 'C:/Program Files/MVTec/HALCON-19.11-Progress/calib/calplateHG30.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.
set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose)
* Calibration 01: **********************************************************
* Calibration 01: Sample Task: Transform contours into world coordinates
* Calibration 01: **********************************************************
* Calibration 01: First, obtain an XLD in image coordinates which relates to some
* Calibration 01: interesting features in the image. Here, we simply generate a contour
* Calibration 01: connecting the mark center points of the plate
gen_contour_polygon_xld (TmpObj_ImageContour, TmpCtrl_MarkRows, TmpCtrl_MarkColumns)
* Calibration 01: Then, we convert it to world coordinates (using [mm])
contour_to_world_plane_xld (TmpObj_ImageContour, TmpObj_WorldContour, CameraParameters, CameraPose, 'mm')
* Calibration 01: Extract mark center points in world coordinates [mm]
get_contour_xld (TmpObj_WorldContour, TmpCtrl_WorldX, TmpCtrl_WorldY)
stop ()

注意XLD轮廓变换到世界坐标系后位于标块左上角那个红点处。

image.png

这个变换后的轮廓只是单位变了。

image.png


///////////////////从单副图像中评估位姿////////////////////////

* 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, please take another calibration plate image
stop ()
grab_image (Image, AcqHandle)
* Calibration 01: Extract plate data from the image
TmpCtrl_PlateDescription := 'C:/Program Files/MVTec/HALCON-19.11-Progress/calib/calplateHG30.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.
set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose)
* Calibration 01: **********************************************************
* Calibration 01: Sample Task: Pose Estimation
* Calibration 01: **********************************************************
* Calibration 01: With known camera parameters, one image is enough to 
* Calibration 01: determine the new pose
stop ()

下面是标定时的位姿:

[0.00858819, 0.00535895, 0.53037, 358.13, 0.643493, 1.02991, 0]

下面是由一张图片求出的位姿:

[0.00453219, 0.00332088, 0.530478, 358.312, 0.724421, 179.253, 0]

从中可以看到Z轴转了180度。



///////////////////校正图像////////////////////////

* 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, please take another calibration plate image
stop ()
grab_image (Image, AcqHandle)
* Calibration 01: Extract plate data from the image
TmpCtrl_PlateDescription := 'C:/Program Files/MVTec/HALCON-19.11-Progress/calib/calplateHG30.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.
set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose)
* Calibration 01: **********************************************************
* Calibration 01: Sample Task: Image Rectification
* Calibration 01: **********************************************************
* Calibration 01: Choose the desired width of the visible area in world coordinates [mm]
TmpCtrl_RectificationWidth := 40
* Calibration 01: Convert to [m]
TmpCtrl_RectificationWidth := TmpCtrl_RectificationWidth / 1000.0
* Calibration 01: Adjust origin so the plate is roughly centered
set_origin_pose (CameraPose, -0.5*TmpCtrl_RectificationWidth, -0.4*TmpCtrl_RectificationWidth, 0, TmpCtrl_RectificationPose)
* Calibration 01: Generate the rectification map
gen_image_to_world_plane_map (TmpObj_RectificationMap, CameraParameters, TmpCtrl_RectificationPose, 2592, 1944, 2592, 1944, TmpCtrl_RectificationWidth / 2592, 'bilinear')
* Calibration 01: Now, images can be rectified using the rectification map
map_image (Image, TmpObj_RectificationMap, TmpObj_RectifiedImage)
stop ()

原图为某姿式下的标定板。

image.png

gen_image_to_world_plane_map算子生成修正图

image.png

map_image算子进行畸变修正后的效果

image.png

再次调整姿态,更斜一些。

image.png

生成的校正图如下:

image.png

校正之后的效果:

image.png



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864