欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用Halcon从SmartRay激光3D传感器获取数据

最编程 2024-08-06 21:42:07
...
  • 作者: 丶布布


文章预览:

  • 一. 前言
  • 二. Halcon仿真采集(电脑需连接SmartRay传感器设备)
  • 三. 总结



一. 前言

采集SmartRay激光3D传感器的Z—Map图(深度图)的方式

  • 利用厂家提供的SDKC#/C++),并联合我们的软件框架去调用其对应的功能接口;
  • 利用Halcon/OpenCV等视觉库去调用传感器对应的采集函数;

本文将介绍第二种利用Halcon去调用传感器对应的采集函数的方式(最好Halcon18以上版本)。

PS:实际项目建议还是第一种使用SDK调用传感器采集等接口,它更稳定一些。第二种方式会偶发连接不稳定、掉线等情况。


二. Halcon仿真采集(电脑需连接SmartRay传感器设备)

Halcon参考案例:

[3D&Halcon] SmartRay激光3D传感器Halcon采集_SmartRay

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点云模型

[3D&Halcon] SmartRay激光3D传感器Halcon采集_3D视觉_02

*截取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,获取高度信息

[3D&Halcon] SmartRay激光3D传感器Halcon采集_求高度信息_03

[3D&Halcon] SmartRay激光3D传感器Halcon采集_3d_04

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的处理手法,这里不在赘述。


三. 总结

本文涉及到的内容主要有如下三点:

  1. Halcon采集SmartRay形成Z-Map图;
  2. 根据X图、Y图和Z-Map图形成3D点云模型,核心算子 —— xyz_to_object_model_3d(Operater);
  3. 获取台阶高度信息的两种方式:①直接处理Halcon采集SmartRay得到的Z-Map图,获取台阶高度信息;②当获取到三维点云模型后,可以获取一个其交平面,将交平面与点云模型的交线转换成二维XLD,使用二维知识获取台阶高度信息。

需要注意的是三维点云转换成二维XLD可能会存在精度损失,需要根据实际情况选择


下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。