一. 前言
采集SmartRay
激光3D
传感器的Z—Map
图(深度图)的方式:
- 利用厂家提供的
SDK
(C#
/C++
),并联合我们的软件框架去调用其对应的功能接口; - 利用
Halcon
/OpenCV
等视觉库去调用传感器对应的采集函数;
本文将介绍第二种利用Halcon
去调用传感器对应的采集函数的方式(最好Halcon18
以上版本)。
PS:实际项目建议还是第一种使用SDK
调用传感器采集等接口,它更稳定一些。第二种方式会偶发连接不稳定、掉线等情况。
二. Halcon仿真采集(电脑需连接SmartRay传感器设备)
Halcon
参考案例:
Halcon
仿真代码:
1、打开设备并初始化传感器
这里使用的是Halcon
异步采集,所以需要初始化参数。注:同步采集和异步采集的区别
*1打开3D传感器 open_framegrabber ('GenICamTL', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default', -1, 'false', 'default', 'default', 0, -1, AcqHandle) *设置抓取延时(在连接传感器时,超过这个延时会报错) set_framegrabber_param (AcqHandle, 'grab_timeout', 10000) *加载型号(设置传感器型号,不设置的话就用默认参数) get_framegrabber_param (AcqHandle, 'Parameter_Set_values', ParameterSetValues) tuple_regexp_select (ParameterSetValues, '.*_3D_Repeat_Snapshot', ParameterSet) set_framegrabber_param (AcqHandle, 'Parameter_Set', ParameterSet) *设置标定数据 set_framegrabber_param (AcqHandle, 'Activate_Calibration', true) *可以获得中间结果(可以通过下面参数获得传感器相关参数信息,了解即可) get_framegrabber_param (AcqHandle, 'Width', Width) get_framegrabber_param (AcqHandle, 'Height', Height) get_framegrabber_param (AcqHandle, 'Number_of_Profiles_to_Capture', NumberOfZILCaptured) //扫描线数 get_framegrabber_param (AcqHandle, 'ZMap_Lateral_Resolution', ZILLatRes) //Y方向(激光线方向)精度 get_framegrabber_param (AcqHandle, 'ZMap_Vertical_Resolution', ZILVerRes)//Z方向精度 *初始化传感器(异步采集需要初始化) grab_image_start (AcqHandle, -1) *抓取深度图(Z-map —— 相对高度) grab_image_async (PointCloudZ, AcqHandle, -1)
2、形成3D点云模型
*截取Zmap图的大小(保证和X/Y图大小一致,才能形成包含X/Y/Z坐标的3D点云模型) crop_rectangle1 (PointCloudZ, ZMap, 0, 0, NumberOfZILCaptured - 1, Width - 1) *得到X,Y图 TransportRate := 0.1628 *X图:图上每个点代表的都是X坐标。第三个参数手动设置为0.1628的原因是X方向是运动方向,这里默认线线间距为0.1628mm gen_image_surface_first_order (PointCloudX, 'real', TransportRate, 0, 0, NumberOfZILCaptured / 2, Width / 2, Width, NumberOfZILCaptured) *Y图:图上每个点代表的都是Y坐标 gen_image_surface_first_order (ImageYVal, 'real', 0, ZILLatRes, 0, NumberOfZILCaptured / 2, Width / 2, Width, NumberOfZILCaptured) *形成3D点云模型前需要对ZMap图转换下数据类型(保证ZMap图和X/Y图的数据类型范围一致) threshold (ZMap, RegionValidity, 0, 65535) reduce_domain (ZMap, RegionValidity, ImageMeasureValid) convert_image_type (ImageMeasureValid, ImageMeasureReal, 'real') get_image_size (ImageMeasureReal, zMap_Width, zMap_Height) gen_image_const (PointCloudZ, 'real', zMap_Width, zMap_Height) threshold (ImageMeasureReal, Region_Valid, 1, 9999999) tuple_pow (2, 15, hv_offset) *PointCloudZ=ImageMeasureReal*ZILVerRes-hv_offset * ZILVerRes *PointCloudZ=(ImageMeasureReal-hv_offset) * ZILVerRes scale_image (ImageMeasureReal, PointCloudZ, ZILVerRes, -hv_offset * ZILVerRes) reduce_domain (PointCloudZ, Region_Valid, PointCloudZ) *形成3D点云模型(已知X/Y/ZMap图) xyz_to_object_model_3d (PointCloudX, ImageYVal, PointCloudZ, ObjectModel3D) triangulate_object_model_3d (ObjectModel3D, 'greedy', [], [], TriangulatedObjectModel3D, Information) dev_open_window (0, 0, 512, 512, 'black', WindowHandle) visualize_object_model_3d (WindowHandle, TriangulatedObjectModel3D, [], [], ['lut','color_attrib'], ['color1','coord_z'], 'ObjectModel3D', [], [], PoseOut)
3、获取台阶高度信息
法一:直接处理Z-Map图,获取高度信息
gen_rectangle1 (ROI_0, -0.402344, 747.698, 99.207, 1153.76) intensity (ROI_0, PointCloudZ, Mean, Deviation) height:=Mean visualize_object_model_3d (WindowHandle, TriangulatedObjectModel3D, [], [], ['lut','color_attrib','disp_pose'], ['color1','coord_z','true'], '台阶高度'+height, [], [], PoseOut)
法二:变换到二维XLD,获取高度信息
CutPlanePose[0]:=0 CutPlanePose[1]:=0 CutPlanePose[2]:=0 CutPlanePose[3]:=0 CutPlanePose[4]:=90 //平面绕y轴(绿色)旋转90度立起来,切台阶形成上面轮廓 CutPlanePose[5]:=0 CutPlanePose[6]:=0 gen_plane_object_model_3d (CutPlanePose, [-1,-1,1,1] * 20, [-1,1,1,-1] * 20, IntersectionPlane) visualize_object_model_3d (WindowHandle, [TriangulatedObjectModel3D,IntersectionPlane], [], [], ['color_0','color_1','disp_pose'], ['blue','red','true'], [], [], [], PoseOut1) intersect_plane_object_model_3d (TriangulatedObjectModel3D, CutPlanePose, ObjectModel3DIntersection) *visualize_object_model_3d (WindowHandle, ObjectModel3DIntersection, [], [], [], [], [], [], [], PoseOut2) *变换到二维XLD pose_invert (CutPlanePose, PoseInvert) *确定投影平面在前面 get_object_model_3d_params (ObjectModel3DIntersection, 'diameter_axis_aligned_bounding_box', Diameter) PoseInvert[2] := PoseInvert[2] +Diameter *用平行于投影平面的相机(1:1的比例) Scale:=1 CamParam := [0,0,1.0 / Scale,1.0 / Scale,0,0,500,500] *求投影xld project_object_model_3d (IntersectionXld, ObjectModel3DIntersection, CamParam, PoseInvert, 'data', 'lines')
变换到二维XLD
后,后面获取轮廓高度完全是2D
的处理手法,这里不在赘述。
三. 总结
本文涉及到的内容主要有如下三点:
Halcon
采集SmartRay
形成Z-Map图;- 根据
X
图、Y
图和Z-Map
图形成3D
点云模型,核心算子 ——xyz_to_object_model_3d(Operater)
; - 获取台阶高度信息的两种方式:①直接处理
Halcon
采集SmartRay
得到的Z-Map
图,获取台阶高度信息;②当获取到三维点云模型后,可以获取一个其交平面,将交平面与点云模型的交线转换成二维XLD
,使用二维知识获取台阶高度信息。
需要注意的是三维点云转换成二维XLD
可能会存在精度损失,需要根据实际情况选择。
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |