Halcon实现3维点云平面拟合
go
function main()
WindowHandle = open_window()
ObjectModel3D = load_3D_model("1.om3")
ObjectModel3DSelected = remove_noise(ObjectModel3D)
[X, Y, Z] = extract_coordinates(ObjectModel3DSelected)
[NX, NY, NZ, C] = fit_plane(X, Y, Z)
visualize(ObjectModel3DSelected, NX, NY, NZ, C, WindowHandle)
打开并配置窗口
go
function open_window()
dev_open_window(0, 0, 512, 512, 'black', WindowHandle)
set_display_font(WindowHandle, 14, 'mono', 'true', 'false')
return WindowHandle
加载3D模型
go
function load_3D_model(filename)
read_object_model_3d(filename, 'm', [], [], ObjectModel3D, Status)
check_status(Status)
return ObjectModel3D
去除3D模型中的噪点
go
function remove_noise(ObjectModel3D)
connection_object_model_3d(ObjectModel3D, 'distance_3d', 1, ObjectModel3DConnected)
select_object_model_3d(ObjectModel3DConnected, 'num_points', 'and', 1000, 99999, ObjectModel3DSelected)
return ObjectModel3DSelected
提取3D模型的坐标信息
go
function extract_coordinates(ObjectModel3D)
get_object_model_3d_params(ObjectModel3D, 'point_coord_x', X)
get_object_model_3d_params(ObjectModel3D, 'point_coord_y', Y)
get_object_model_3d_params(ObjectModel3D, 'point_coord_z', Z)
return [X, Y, Z]
拟合平面
function fit_plane(X, Y, Z)
计算点的重心
XM = mean(X)
YM = mean(Y)
ZM = mean(Z)
# 计算对称矩阵M(A)
DX = X - XM
DY = Y - YM
DZ = Z - ZM
MA11 = sum(DX * DX)
MA22 = sum(DY * DY)
MA33 = sum(DZ * DZ)
MA12 = sum(DX * DY)
MA13 = sum(DX * DZ)
MA23 = sum(DY * DZ)
create_matrix(3, 3, [MA11,MA12,MA13,MA12,MA22,MA23,MA13,MA23,MA33], MatrixID)
# 求取特征值和特征向量
eigenvalues_symmetric_matrix(MatrixID, 'true', EigenvaluesID, EigenvectorsID)
# 获取法向量
get_value_matrix(EigenvectorsID, 0, 0, NX)
get_value_matrix(EigenvectorsID, 1, 0, NY)
get_value_matrix(EigenvectorsID, 2, 0, NZ)
# 计算平面的常数C
C = NX * XM + NY * YM + NZ * ZM
if C < 0.0
NX = -NX
NY = -NY
NZ = -NZ
C = -C
endif
return [NX, NY, NZ, C]
可视化函数
go
# 可视化函数
function visualize(ObjectModel3DSelected, NX, NY, NZ, C, WindowHandle)
# 设置可视化参数
VisualizationPlaneSize = 40
GenParamName = ['lut','color_attrib','light_position','alpha']
GenParamValue = ['color1','coord_z','0.0 0.0 -0.3 1.0', 0.9]
# 获取3D对象的主要轴(可选)
moments_object_model_3d(ObjectModel3DSelected, 'principal_axes', Pose)
# 生成拟合平面的3D对象模型
gen_plane_object_model_3d(Pose, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane)
# 设置可视化窗口的角度和位置
create_pose(-65, -40, 2400, 150, 0, -60, 'Rp+T', 'gba', 'point', PoseIn)
# 设置标题和操作说明
Title = '3D object & fitplane'
Instructions[0] = 'Rotate: Left button'
Instructions[1] = 'Zoom: Shift + left button'
Instructions[2] = 'Move: Ctrl + left button'
# 在窗口中可视化3D对象和拟合平面
visualize_object_model_3d(WindowHandle, [ObjectModel3DSelected, IntersectionPlane], [], PoseIn, GenParamName, GenParamValue, Title, [], Instructions, Pose)
end function
状态检查
go
function check_status(Status)
if Status != "OK"
# Handle the error here