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

相关推荐
SoraLuna3 分钟前
「Mac玩转仓颉内测版32」基础篇12 - Cangjie中的变量操作与类型管理
开发语言·算法·macos·cangjie
daiyang123...21 分钟前
Java 复习 【知识改变命运】第九章
java·开发语言·算法
小彭努力中41 分钟前
141. Sprite标签(Canvas作为贴图)
前端·深度学习·3d·webgl·three.js
田梓燊1 小时前
湘潭大学软件工程算法设计与分析考试复习笔记(六)
笔记·算法·软件工程
重生之Java开发工程师1 小时前
算法笔记:前缀和
笔记·算法
sweetheart7-72 小时前
LeetCode155. 最小栈(2024冬季每日一题 12)
算法··模拟栈·最小元素
藏鹤虞渊2 小时前
【ONE·基础算法 || 动态规划(二)】
算法·动态规划
kcwqxx2 小时前
day23|leetCode 39. 组合总和 , 40.组合总和II , 131.分割回文串
c++·算法·leetcode
kitesxian2 小时前
Leetcode155. 最小栈(HOT100)
算法
一颗青果2 小时前
【Linux】详解shell代码实现(上)
linux·运维·服务器·前端·chrome·算法·1024程序员节