feat: 算法升级、整车配准集成与性能分析文档

算法更新: delivery v1.2.1、平整度v1.5、测距v2.2、整车配准v1.3
适配器: vehicle-registration 新增、各算法 manifest 和 adapter 更新
后端: taskCadFiles/source 字段迁移、derivedPointClouds 注册、取消任务联动
前端: ElapsedTime 时长显示、两步算法流程、canRun 逻辑修复
文档: 新增5份算法性能分析报告
This commit is contained in:
2026-06-25 08:22:20 +00:00
parent cec0766e67
commit 29f1d45d66
266 changed files with 1311475 additions and 2846 deletions

View File

@@ -0,0 +1,94 @@
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" → 密度基本不变")