matlab boundary()函数不是严格的凸包,用python中的ConvexHull不好替代。
其原理都是基于alphashape寻找边缘点,可以考虑python的alphashape库:
import numpy as np
import alphashape
import matplotlib.pyplot as plt
# 生成一些随机的3D点云数据(你可以替换为实际数据)
np.random.seed(42)
points = np.random.rand(100, 3)
# 创建alpha形状,alpha的值决定了边界的精度,越小,边界越紧凑
alpha_shape = alphashape.alphashape(points,3)
# 获取边界点('vertices' 是边界的顶点)
boundary_points = np.array(alpha_shape.vertices)
print(boundary_points.shape[0])
# 获取alpha形状中的三角形索引
triangles = alpha_shape.faces
print(triangles.shape[0])
# 可视化
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制原始点云
ax.scatter(points[:, 0], points[:, 1], points[:, 2], c='b', marker='o', label='Points')
# 绘制边界面
for triangle in triangles:
x = boundary_points[triangle, 0]
y = boundary_points[triangle, 1]
z = boundary_points[triangle, 2]
ax.plot_trisurf(x, y, z, color='cyan', alpha=0.5, linewidth=0.2)
# 绘制边界点
ax.scatter(boundary_points[:, 0], boundary_points[:, 1], boundary_points[:, 2], c='r', marker='^', label='Boundary Points')
ax.legend()
# 显示图形
plt.show()
注意:通过取消pycharm设置中的在工具窗显示绘图可以实现鼠标拖动旋转图像:
可以看到matlab的boundary函数中的shrink factor 是0.5,shrink factor用来调整生成的边界的大小。具体来说,它会缩放外部凸包边界(convex hull),让边界向内部收缩或者扩展,通常取值范围在 0到 1之间

而python的alphashape的alpha参数需要指定大于0的一个参数。alpha 在 alphashape 中控制的是生成的 alpha形状 的精度或细节程度。与 shrink_factor 不同,alpha 的作用是控制包围点云的边界的“精确度”。
怎么把两者对应起来呢。我的一个想法是可以找两个函数生成的边界点的个数和三角形面的个数来确定,例如,matlab中可以用和python生成的点进行对比:
clc;
clear;
% 读取点云数据
points = csvread("points.csv");
% 获取点云的边界
k = boundary(points);
% 计算边界的顶点个数
boundary_points = unique(k(:)); % 获取唯一的点索引
num_boundary_points = length(boundary_points); % 计算边界顶点数
% 显示边界顶点个数
disp(['Boundary points count: ', num2str(num_boundary_points)]);
disp(['edges count: ', num2str(length(k(:,1)))]);
% 绘制边界
figure;
hold on;
scatter3(points(:,1), points(:,2), points(:,3), 'filled', 'MarkerFaceColor', 'b'); % 绘制点云
trisurf(k, points(:,1), points(:,2), points(:,3), 'FaceAlpha', 0.3); % 绘制边界面
title('3D Boundary Surface');
xlabel('X');
ylabel('Y');
zlabel('Z');
grid on;
% 允许交互式旋转
rotate3d on;
当boundary函数shrink_factor取默认值0.5,alphashape的alpha取3,此时生成边界的点都是71个,面个数都是138个。![]()
![]()
476

被折叠的 条评论
为什么被折叠?



