halcon3D 1:1切片轮廓投影技术,透过像素距离,知实际物体的尺寸

首先说做个什么事儿

对一个物体的横截面进行1:1或者1:10的投影,也就是说世界物体1mm的话,投影到image中占1个或者10个像素值 ,这样,就可以透过直接计算image中的像素距离,知道实际物体的尺寸

用一张图说明是这样的。物体的实际长度是0.5m

在案例里我用了两种方法来做,欢迎交流

要用到的算子包括

1,**VIS3DOBJ (WindowHandle, ObjectModel3DID, PoseOut)**这个陌生的算子是我自己封装的

visualize_object_model_3d (WindowHandle, ObjectModel3DID, \[\], \[\],

'lut', 'color_attrib', 'disp_pose', 'color1','coord_z','true',

\[\], \[\], \[\], PoseOut)

每次显示基本都是用 'lut', 'color_attrib', 'disp_pose', 'color1','coord_z','true'这几个参数,输入来,输入去,愁人

2,smallest_bounding_box_object_model_3d (ObjectModel3DID, 'axis_aligned', Pose, Length1, Length2, Length3)

重点说明------Length1,最长边的尺寸, Length2, 次长边的尺寸,Length3最短边的尺寸

3,intersect_plane_object_model_3d (ObjectModel3DID, Pose1, ObjectModel3DIntersection)

这个简单,主要是第二个输入参数是一个平面的位姿,而不是平面

4,project_object_model_3d (ModelContours, ObjectModel3DAffineTrans2, CameraParam1, pose, \[\], \[\])

重点说明

1,这个算子是对相机坐标系下的物体进行投影。是相机坐标系下

2,pose代表的是被投影物体相对于被采样时的相机坐标系下物体采样位置的位姿,

这么绕什么意思呢,

就是物体讲过pose,转换到相机坐标系下,再进行投影,这个在实例中可以看的很清楚

按代码流程来走一下

1,生成切片

bash 复制代码
read_object_model_3d ('clamp_sloped', 'mm', [], [], ObjectModel3DID, DxfStatus)
dev_open_window (0, 0, 600,600, 'black', WindowHandle)
****每次都这么一堆输入是不是很愁人 ['lut', 'color_attrib', 'disp_pose'], ['color1','coord_z','true']在这里可以直接对它进行二次封装
VIS3DOBJ (WindowHandle, ObjectModel3DID, PoseOut)
*****做一个切片求一求这个圆的直径
smallest_bounding_box_object_model_3d (ObjectModel3DID, 'axis_aligned', Pose, Length1, Length2, Length3)
create_pose (0, 0, Length3/5, 0, 0, 0, 'Rp+T', 'gba', 'point', Pose1)
intersect_plane_object_model_3d (ObjectModel3DID, Pose1, ObjectModel3DIntersection)
VIS3DOBJ (WindowHandle, ObjectModel3DIntersection, PoseOut1)

2,将切片通过两种方式移动到相机坐标系下

bash 复制代码
*****做一个切片求一求这个圆的直径
smallest_bounding_box_object_model_3d (ObjectModel3DID, 'axis_aligned', Pose, Length1, Length2, Length3)
create_pose (0, 0, Length3/5, 0, 0, 0, 'Rp+T', 'gba', 'point', Pose1)
intersect_plane_object_model_3d (ObjectModel3DID, Pose1, ObjectModel3DIntersection)
VIS3DOBJ (WindowHandle, ObjectModel3DIntersection, PoseOut1)
****求相交面的pose
smallest_bounding_box_object_model_3d (ObjectModel3DIntersection, 'axis_aligned', Pose2, Length11, Length21, Length31)
pose_invert (Pose2, PoseInvert)
pose_to_hom_mat3d (PoseInvert, HomMat3D)
affine_trans_object_model_3d (ObjectModel3DIntersection, HomMat3D, ObjectModel3DAffineTrans)
VIS3DOBJ (WindowHandle, ObjectModel3DAffineTrans, PoseOut1)
*****再将它移动到离摄像机1米远的地方
hom_mat3d_identity (HomMat3DIdentity)
hom_mat3d_translate (HomMat3DIdentity, 0, 0, 1, HomMat3DTranslate)
affine_trans_object_model_3d (ObjectModel3DAffineTrans, HomMat3DTranslate, ObjectModel3DAffineTrans1)
****看一下,跟移到00点的关系
****一个简单的办法
VIS3DOBJ (WindowHandle,[ ObjectModel3DAffineTrans,ObjectModel3DAffineTrans1], PoseOut1)

***可以从切片平面直接过来吗?可以的,两步合一ObjectModel3DIntersection到ObjectModel3DAffineTrans1
hom_mat3d_compose (HomMat3D, HomMat3DTranslate, HomMat3DCompose)
affine_trans_object_model_3d (ObjectModel3DIntersection, HomMat3DCompose, ObjectModel3DAffineTrans2)

*****看一看,ObjectModel3DAffineTrans1和ObjectModel3DAffineTrans2的位置一样吗
b:=[ObjectModel3DAffineTrans2,ObjectModel3DAffineTrans1]


3,计算相机的内参

bash 复制代码
*****开始做投影准备
*****来一个虚拟相机,相机的焦距也是1,当然单位是0.0000001m,在这里来提高精度,定1mm投影过来的精度是10个像素
*****那一个像素的尺寸,根据小孔成像的原理应该是 
*****1000000/1=1000/(10*cx)
cx:=0.0001
*****投影图像的大小,应该是最大边长投影直径的1.2倍
x:=round(max([Length11, Length21])*1000*10*1.2)
*****来做这样一个虚拟相机
gen_cam_par_area_scan_division (1, 0, cx, cx, x/2, x/2, x, x, CameraParam1)
*****物体在相机的什么位置,答案是在距离他z轴1米远的地方,此时的物体就是在相机坐标系下

4,用两种方法进行投影,直接相机坐标系下和物体坐标系下

*****物体在相机的什么位置,答案是在距离他z轴1米远的地方,此时的物体就是在相机坐标系下

pose0:=0,0,0,0,0,0,0

*****为什么是0,0,0,0,0,0,0,这里的pose代表的是物体坐标系相对于世界坐标系的位姿,那现在的ObjectModel3DAffineTrans2就在相机坐标系下,所以是0,0,0000

project_object_model_3d (ModelContours, ObjectModel3DAffineTrans2, CameraParam1, pose0, \[\], \[\])

gen_region_contour_xld (ModelContours, Region, 'filled')

union1 (Region, RegionUnion)

smallest_rectangle1 (RegionUnion, Row1, Column1, Row2, Column2)

gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)

***aa:=500, bb:=150 是切片的长度是0.5和1.5

aa:=Column2-Column1

bb:=Row2-Row1

*****是不是很麻烦,如果要对切片直接投影呢,那pose5应该是什么呢

hom_mat3d_to_pose (HomMat3DCompose, Pose5)

project_object_model_3d (ModelContours, ObjectModel3DIntersection, CameraParam1, Pose5, \[\], \[\])

gen_region_contour_xld (ModelContours, Region, 'filled')

union1 (Region, RegionUnion)

smallest_rectangle1 (RegionUnion, Row1, Column1, Row2, Column2)

gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)

***aa:=500, bb:=150 是切片的长度是0.5和1.5

***依然成立

aa:=Column2-Column1

bb:=Row2-Row1

set_display_font (WindowHandle, 30, 'mono', 'false', 'false')

dev_disp_text ('长度='+aa, 'window', Row1-150, Column1+100, 'green', \[\], \[\])

dev_set_draw ('margin')

dev_display (Rectangle)

***在这里重点想说的是pose,它代表的是被投影物体,相对于相机坐标系的位姿,通过pose。先将物体转换到相机坐标系下,再对相机坐标系下的物体进行投影

相关推荐
古城小栈6 小时前
为啥说:训练用BF16,推理用FP16
人工智能·算法·机器学习
KaMeidebaby6 小时前
卡梅德生物技术快报|蛋白 N 端测序在重组贻贝融合蛋白表征中的应用,解决原核表达序列偏移工艺难题
前端·人工智能·物联网·算法·百度
Turbo正则7 小时前
群论在AI中的应用概述
人工智能·算法·抽象代数
ysa0510307 小时前
【并查集】判环
c++·笔记·算法
Jerry8 小时前
KeetCode 44. 开发商购买土地
算法
Jerry8 小时前
KeetCode 58. 区间和
算法
Jerry9 小时前
LeetCode 209. 长度最小的子数组
算法
彦为君9 小时前
算法思维与经典智力题
java·前端·redis·算法
智能优化与强化学习9 小时前
Gym(Gymnasium)仿真环境详解(二):环境简介、入门算法、调参要点、核心挑战
算法·强化学习·gym·零基础入门·算法评估
mxwin10 小时前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader