首先说做个什么事儿
对一个物体的横截面进行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。先将物体转换到相机坐标系下,再对相机坐标系下的物体进行投影