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。先将物体转换到相机坐标系下,再对相机坐标系下的物体进行投影

相关推荐
倒头就睡的小比特4 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark4 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集
码流子4 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven4 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark4 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218614 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法