我通常会把想要旋转的点云投影到指定平面,然后利用边缘提取提取出边缘,选取边缘两点,创建线段。计算斜率。
斜率:通常用直线(或曲线的切线)与(横)坐标轴夹角的正切,或两点的纵坐标之差与横坐标之差的比来表示。
注意:该方法我觉得还有点问题,例如无法控制顺时针还是逆时针转,但是目前测试下来能够应付我的要求。如果你们使用遇到效果不好,可以根据第二部分代码进行更改
第一部分
import math
import numpy as np
import open3d as o3d
def rotation(pcd,x1,y1,x2,y2,axi=2):
"""
:param pcd:未投影的点云
:param x1:点A x1坐标
:param y1:点A y1坐标
:param x2:点B x2坐标
:param y2:点B y2坐标
:param axi:绕指定轴旋转
:return: 旋转以后的点云数据
"""
k = (y2 - y1) / (x2 - x1)
b = y1 - k * x1
angle_radians = math.atan(k)#弧度
angle = math.degrees(angle_radians)#弧度转角度
if axi ==2:
axis = np.array([0, 0, 1]) # 旋转轴(x、y、z)
elif axi ==0:
axis = np.array([1, 0, 0]) # 旋转轴(x、y、z)
else:
axis = np.array([0, 1, 0]) # 旋转轴(x、y、z)
rotation_vector = axis * -angle
# 创建变换矩阵
transformation = np.eye(4)
transformation[:3, :3] = o3d.geometry.get_rotation_matrix_from_axis_angle(rotation_vector)
rotation_pcd = pcd.transform(transformation)
return rotation_pcd
第二部分
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud('鞍座_1.pcd')
pcd1 = o3d.t.io.read_point_cloud('鞍座_1.pcd')
# 执行旋转操作
angle = -0.2618 # 旋转角度(弧度)
axis = np.array([0, 0, 1]) # 旋转轴(x、y、z)
rotation_vector = axis * angle
# 创建变换矩阵
transformation = np.eye(4)
transformation[:3, :3] = o3d.geometry.get_rotation_matrix_from_axis_angle(rotation_vector)
# 应用变换矩阵到点云
rotationpcd = pcd.transform(transformation)
# 可以执行其他处理操作,例如保存旋转后的点云数据、可视化等
o3d.io.write_point_cloud("鞍座_1_旋转.pcd", rotationpcd)
#
vis = o3d.visualization.Visualizer()
vis.create_window(window_name='三维点云边界提取', width=1200, height=800)
opt = vis.get_render_option()
opt.background_color = np.asarray([1, 1, 1]) # 设置背景色
opt.point_size = 3 # 设置点的大小
vis.add_geometry(rotationpcd) # 加载边界点云到可视化窗口
vis.add_geometry(pcd1.to_legacy()) # 加载原始点云到可视化窗口
vis.run() # 激活显示窗口,这个函数将阻塞当前线程,直到窗口关闭。
vis.destroy_window() # 销毁窗口,这个函数必须从主线程调用。