Files
lipan 29f1d45d66 feat: 算法升级、整车配准集成与性能分析文档
算法更新: delivery v1.2.1、平整度v1.5、测距v2.2、整车配准v1.3
适配器: vehicle-registration 新增、各算法 manifest 和 adapter 更新
后端: taskCadFiles/source 字段迁移、derivedPointClouds 注册、取消任务联动
前端: ElapsedTime 时长显示、两步算法流程、canRun 逻辑修复
文档: 新增5份算法性能分析报告
2026-06-25 08:22:20 +00:00

94 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import open3d as o3d
import numpy as np
from scipy.spatial import KDTree
def compute_keep_ratio_and_density(pcd, filtered_pcd, sample_size=1000):
"""
计算直通滤波的保留率和密度变化
Args:
pcd: 原始点云
filtered_pcd: 滤波后点云
sample_size: 密度计算采样点数(加速计算)
Returns:
keep_ratio: 保留率 (%)
density_change: 密度变化 (%)
"""
n_orig = len(pcd.points)
n_filt = len(filtered_pcd.points)
# 1. 保留率
keep_ratio = n_filt / n_orig * 100
# 2. 密度变化(基于平均最近邻距离)
points_orig = np.asarray(pcd.points)
points_filt = np.asarray(filtered_pcd.points)
# 采样(点数太多时加速)
if len(points_orig) > sample_size:
idx_orig = np.random.choice(len(points_orig), sample_size, replace=False)
points_orig_sample = points_orig[idx_orig]
else:
points_orig_sample = points_orig
if len(points_filt) > sample_size:
idx_filt = np.random.choice(len(points_filt), sample_size, replace=False)
points_filt_sample = points_filt[idx_filt]
else:
points_filt_sample = points_filt
# 计算平均最近邻距离(密度指标)
if len(points_orig_sample) > 5:
tree_orig = KDTree(points_orig_sample)
dist_orig, _ = tree_orig.query(points_orig_sample, k=2) # k=2 排除自身
avg_dist_orig = np.mean(dist_orig[:, 1])
else:
avg_dist_orig = 0
if len(points_filt_sample) > 5:
tree_filt = KDTree(points_filt_sample)
dist_filt, _ = tree_filt.query(points_filt_sample, k=2)
avg_dist_filt = np.mean(dist_filt[:, 1])
else:
avg_dist_filt = 0
# 密度变化(距离增大 = 密度减小)
if avg_dist_orig > 0:
density_change = (avg_dist_filt - avg_dist_orig) / avg_dist_orig * 100
else:
density_change = 0
return keep_ratio, density_change
# ========== 使用示例 ==========
if __name__ == "__main__":
# 读取点云
pcd = o3d.io.read_point_cloud(r"E:\point_distance\data\part_car_head.ply")
# 直通滤波(Z轴)
points = np.asarray(pcd.points)
mask = (points[:, 2] >= 0.0) & (points[:, 2] <= 2.0)
filtered_points = points[mask]
filtered_pcd = o3d.geometry.PointCloud()
filtered_pcd.points = o3d.utility.Vector3dVector(filtered_points)
# 计算指标
keep_ratio, density_change = compute_keep_ratio_and_density(pcd, filtered_pcd)
print("=" * 40)
print("直通滤波指标")
print("=" * 40)
print(f"保留率: {keep_ratio:.2f}%")
print(f"密度变化: {density_change:+.2f}%")
# 解释
if density_change > 0:
print(f" → 点云变稀疏了 {density_change:.2f}%")
elif density_change < 0:
print(f" → 点云变密集了 {abs(density_change):.2f}%")
else:
print(f" → 密度基本不变")