operator get_circle_pose 的使用
//* 此示例程序展示了如何使用运算符 get_circle_pose。
//* 首先,提取轮辋钻孔的轮廓。
//* 然后,这些轮廓中心的 3D 位置由算子 get_circle_pose 确定。
//*
//* 读取图像并初始化程序。
dev_update_off ()
//Read an image with different file formats
read_image (Image, 'rim')
//返回图像的大小
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
//Displays image objects in the current graphics window.
dev_display (Image)
//定义区域轮廓输出的线宽
dev_set_line_width (3)
//*
//* 确定钻孔的椭圆轮廓
p_determine_ellipse_contours (Image, EllipseContoursLarge, EllipseContoursSmall, false, NumberLarge, NumberSmall)
//连接两个标志性对象元组
concat_obj (EllipseContoursLarge, EllipseContoursSmall, EllipseContours)
//*
//* 设置钻孔半径和相机参数(来自相机校准的结果)
//*
RadiusLarge := 10.25 / 1000.0
RadiusSmall := 5.91 / 1000.0
CamParam := [0.0122,-261.04,7.39e-6,7.4e-6,303.12,234.17,652,494]
//*
//* 应用运算符 get_circle_pos 来确定圆圈的位置和方向。
//* 请注意,在这种情况下,运算符 get_circle_pose 被调用两次:
//* 首先确定圆的姿态,然后确定 3D 圆的法向量。
//* 对于每个圆,两个可能的 3D 位置和方向由操作符 get_circle_pose 确定。
//* 3D 圆的法向量用于对结果进行聚类,
//* 以便将位于一个平面内的所有圆组合在一起。
//* 该聚类由过程 p_cluster_normals 执行。
//*
//从其透视 2D 投影确定圆的 3D 姿态
get_circle_pose (EllipseContours, CamParam, [gen_tuple_const(NumberLarge,RadiusLarge),gen_tuple_const(NumberSmall,RadiusSmall)], 'pose', Pose1, Pose2)
get_circle_pose (EllipseContours, CamParam, [gen_tuple_const(NumberLarge,RadiusLarge),gen_tuple_const(NumberSmall,RadiusSmall)], 'center_normal', CenterNormal1, CenterNormal2)
p_cluster_normals (Pose1, Pose2, CenterNormal1, CenterNormal2, ClusterP1, ClusterP2, ClusterCN1, ClusterCN2)
//*
//* 可视化结果
dev_display (Image) //Displays image objects in the current graphics window.
dev_set_colored (12)
dev_display (EllipseContours)
for i := 0 to NumberLarge + NumberSmall - 1 by 1
//将 3D 姿势转换为齐次变换矩阵。
pose_to_hom_mat3d (ClusterP1[i * 7:i * 7 + 6], HomMat3D)
//对点应用任意仿射 3D 变换
affine_trans_point_3d (HomMat3D, 0, 0, 0, Qx, Qy, Qz)
//将 3D 点投影到(子)像素图像坐标中
project_3d_point (Qx, Qy, Qz, CamParam, Row, Column)
Row := Row - 95
Column := Column - 60
disp_message (WindowHandle, ['X=' + ClusterCN1[i * 6]$'6.3f','Y=' + ClusterCN1[i * 6 + 1]$'6.3f','Z=' + ClusterCN1[i * 6 + 2]$'6.3f'], 'window', Row, Column, 'black', 'true')
endfor
get_circle_pose — 从圆的 2D 透视投影确定圆的 3D 姿态
get_circle_pose(Contour : : CameraParam, Radius, OutputType : Pose1, Pose2)
//参数
Contour (input_object) ---待检查的轮廓
CameraParam (input_control) ---Internal camera parameters.
Radius (input_control) ---对象空间中圆的半径
Number of elements: (((CameraParam == 8) || (CameraParam == 10)) || (CameraParam == 12)) || (CameraParam == 14)
OutputType (input_control) ---输出参数的类型
Default value: 'pose'
List of values: 'center_normal', 'pose'
Pose1 (output_control)
3D pose of the first circle.
Number of elements: (Pose1 == (7 * Contour)) || (Pose1 == (6 * Contour))
Pose2 (output_control) 3D pose of the second circle.
Number of elements: (Pose2 == (7 * Contour)) || (Pose2 == (6 * Contour))
图像中的每个椭圆都可以解释为圆在图像中的透视投影。事实上,对于给定的圆半径,在 3D 中存在两个不同方向的圆,它们导致相同的投影。 get_circle_pose 确定这两个圆的 3D 位置和方向。首先,每个 Contour 都由一个椭圆近似。然后,基于相机内部参数(CameraParam)和3D中圆的半径(Radius),在相机坐标中确定3D位置和方向(Pose1,Pose2)。
根据参数 OutputType 的值,位置和方向以 3D 姿势(OutputType = ‘pose’)或以 3D 圆的中心和圆所在平面的法向量的形式返回(输出类型 = ‘center_normal’)。在前一种情况下,绕 z 轴旋转的角度设置为零,因为它无法确定。在后一种情况下,输出参数 Pose1 和 Pose2 的前三个元素包含圆心的位置。以下三个元素包含法线向量。法向量被归一化和定向,使得它们指向远离作为相机坐标系原点的光学中心。如果 OutputType 设置为“center_normal”,则输出参数 Pose1 和 Pose2 仅包含六个描述圆位置和方向的元素,而不是在 OutputType 设置为“pose”时返回的 3D 姿势的七个元素。
如果在 Contour 中传递了多个轮廓,Radius 必须包含一个元组,该元组包含每个轮廓的值,或者仅包含一个值,然后用于所有轮廓。生成的位置和方向依次存储在 Pose1 和 Pose2 中,即 Pose1 和 Pose2 首先包含第一个轮廓的姿势或位置和法向量,然后是第二个轮廓的相应值,依此类推。
pose_to_hom_mat3d — 将 3D 姿势转换为齐次变换矩阵。
pose_to_hom_mat3d( : : Pose : HomMat3D)
//参数
Pose (input_control) ---3D pose.
Number of elements: 7
HomMat3D (output_control) ---等效齐次变换矩阵