Files
massive-cloud/alg/点云测距v1.1/train_measurement_system/README.md

14 KiB
Raw Blame History

列车点云测量系统

基于配置驱动的点云测量系统,支持多种测量任务类型。通过YAML配置文件定义测量任务,自动完成ROI提取、平面拟合、距离计算,并生成Excel报告和可视化点云文件。

项目结构

train_measurement_system/
├── config/
│   └── measurements.yaml          # 测量任务配置文件
├── src/
│   ├── __init__.py                # 包初始化文件
│   ├── measurements/
│   │   ├── __init__.py            # 子包初始化文件
│   │   ├── base.py                # 测量任务基类
│   │   ├── plane_distance.py      # 平面到平面距离测量
│   │   ├── point_to_plane.py      # 点到平面距离测量
│   │   └── point_to_point.py      # 点到点距离测量
│   ├── config_loader.py           # 配置加载器
│   ├── task_manager.py            # 任务管理器
│   ├── roi_extractor.py           # ROI提取
│   ├── plane_fitter.py            # 平面拟合(RANSAC)
│   ├── pointcloud_loader.py       # 点云加载
│   ├── visualizer.py              # 可视化工具
│   └── excel_exporter.py          # Excel导出
├── results/                       # 测量结果输出目录(Excel文件)
├── visualizations/                # 可视化点云输出目录(PLY文件)
├── main.py                        # 主程序入口
├── pyproject.toml                 # 项目配置文件(PEP 621)
├── setup.py                       # 安装脚本(向后兼容)
├── requirements.txt               # 依赖清单
├── USAGE.md                       # 使用说明
└── README.md                      # 本文件

功能特性

  • 配置驱动: 通过YAML配置文件定义测量任务,无需修改代码
  • 多任务类型: 支持平面到平面、点到平面、点到点三种测量类型
  • 批量处理: 一次运行可执行多个测量任务
  • 自动可视化: 自动保存每个任务的ROI点云(PLY格式)
  • 结果导出: 自动生成格式化的Excel报告,包含详细统计信息
  • 鲁棒性强: RANSAC平面拟合,自动处理离群点和噪声
  • 错误处理: 单个任务失败不影响其他任务执行
  • 可扩展: 易于添加新的测量类型

环境要求

  • Python 3.9+
  • 推荐使用 conda 环境管理

快速开始

1. 创建并激活环境

# 创建 conda 环境
conda create -n pcc-experiment python=3.9
conda activate pcc-experiment

2. 安装依赖

方式一:使用 requirements.txt

pip install -r requirements.txt

方式二:安装项目

# 正常安装
pip install .

# 或开发模式安装(代码修改立即生效)
pip install -e .

安装项目会自动安装所有依赖包,并将项目注册到 Python 环境中。

2. 准备点云文件

确保你有完整的列车点云文件(PLY格式),例如:

D:\lab\PCC\PCC\head_train_pointcloud\train_2_100M.ply

3. 配置测量任务

编辑 config/measurements.yaml,设置点云文件路径和测量任务。

支持相对路径(相对于配置文件)或绝对路径:

# 相对路径(推荐)
pointcloud_file: "../../../head_train_pointcloud/train_2_100M.ply"

# 或绝对路径
pointcloud_file: "D:\\lab\\PCC\\PCC\\head_train_pointcloud\\train_2_100M.ply"

tasks:
  - name: "任务21_侧门高度"
    type: "plane_to_plane"
    enabled: true
    description: "测量侧门顶部到底部的距离"
    visualization_dir: "visualizations"
    
    source_roi:
      bbox_min: [-2500, 3358, -1545]
      bbox_max: [-1500, 3362, -1525]
    
    target_roi:
      bbox_min: [-2500, 1180, -1621]
      bbox_max: [-1500, 1180, -1500]
    
    params:
      sample_points: 100
      ransac_threshold: 2.0
      ransac_max_iterations: 1000
      min_inlier_ratio: 0.6

4. 运行测量

# 使用默认配置文件
python main.py

# 指定配置文件
python main.py -c config/custom.yaml

# 指定点云文件(覆盖配置文件中的路径)
python main.py -p data/train.ply

# 指定输出目录
python main.py -o results/

# 组合使用
python main.py -c config/custom.yaml -p data/train.ply -o results/

命令行参数:

  • -c, --config: 配置文件路径(默认: config/measurements.yaml)
  • -p, --pointcloud: 点云文件路径(覆盖配置文件)
  • -o, --output: 结果输出目录(默认: results/)

5. 查看结果

Excel报告: 保存在 results/ 目录下

  • 文件名格式:measurement_results_YYYYMMDD_HHMMSS.xlsx
  • 包含每个任务的详细统计信息:
    • 任务名称、类型、描述
    • 点位参数(ROI 范围、目标点坐标等)
    • 测量数据(平均距离、标准差、最小/最大距离)
    • 采样点数、ROI 点数、内点率
    • 错误信息(如果失败)

可视化点云: 保存在 visualizations/ 目录下

  • 文件格式:PLY
  • 可使用CloudCompare或Open3D查看
  • 用于验证ROI提取和测量点位置是否正确

测量类型详解

1. plane_to_plane(平面到平面距离)

从源平面采样点,计算到目标平面的距离。适用于测量车门高度、车体长度、窗口高度等。

工作流程:

  1. 从source_roi包围盒提取点云
  2. 使用RANSAC拟合源平面
  3. 从拟合的内点中随机采样指定数量的点
  4. 从target_roi包围盒提取点云
  5. 使用RANSAC拟合目标平面
  6. 计算采样点到目标平面的有向距离
  7. 统计平均值、标准差、最小/最大距离

配置参数:

type: "plane_to_plane"
source_roi:
  bbox_min: [x_min, y_min, z_min]
  bbox_max: [x_max, y_max, z_max]
target_roi:
  bbox_min: [x_min, y_min, z_min]
  bbox_max: [x_max, y_max, z_max]
params:
  sample_points: 100              # 采样点数
  ransac_threshold: 2.0           # RANSAC距离阈值(mm)
  ransac_max_iterations: 1000     # RANSAC最大迭代次数
  min_inlier_ratio: 0.6           # 最小内点比例

输出结果:

  • 平均距离(mm)
  • 标准差(mm)
  • 最小/最大距离(mm)
  • 采样点数
  • Source ROI点数
  • Target ROI点数
  • 平面拟合内点率

可视化文件:

  • {任务名}_source_roi.ply:源平面ROI点云
  • {任务名}_target_roi.ply:目标平面ROI点云

2. point_to_plane(点到平面距离)

测量指定点到参考平面的距离。支持两种模式:精确坐标查找和包围盒筛选。

工作流程:

  1. 根据模式获取测量点:
    • exact_points模式:在点云中查找最近点
    • bbox_filtered模式:从包围盒提取点云并筛选
  2. 从target_roi提取点云并拟合参考平面(目前的实现中,直接用z=0平面,不做拟合)
  3. 计算每个点到平面的距离
  4. 统计平均值、标准差等

配置参数(exact_points模式):

type: "point_to_plane"
mode: "exact_points"
points:
  - [-753.5, 1052.5, 1445]
  - [3446.5, 1053, 1445]
  - [-753.5, 1052.5, -1445]
target_roi:
  bbox_min: [x_min, y_min, z_min]
  bbox_max: [x_max, y_max, z_max]
params:
  search_radius: 50.0             # 查找最近点的搜索半径(mm)
  ransac_threshold: 2.0
  ransac_max_iterations: 1000
  min_inlier_ratio: 0.6
  use_absolute_distance: true     # 是否使用绝对距离

配置参数(bbox_filtered模式):

type: "point_to_plane"
mode: "bbox_filtered"
source_rois:
  - bbox_min: [x1_min, y1_min, z1_min]
    bbox_max: [x1_max, y1_max, z1_max]
  - bbox_min: [x2_min, y2_min, z2_min]
    bbox_max: [x2_max, y2_max, z2_max]
filter:
  type: "max_abs_coordinate"      # 筛选类型
  axis: "z"                       # 筛选坐标轴
  top_n: 10                       # 每个ROI选择前N个点
target_roi:
  bbox_min: [x_min, y_min, z_min]
  bbox_max: [x_max, y_max, z_max]
params:
  ransac_threshold: 2.0
  ransac_max_iterations: 1000
  min_inlier_ratio: 0.6
  use_absolute_distance: true

输出结果:

  • 平均距离(mm)
  • 标准差(mm)
  • 最小/最大距离(mm)
  • 测量点数
  • Target ROI点数
  • 平面拟合内点率

可视化文件:

  • {任务名}_found_points.ply:测量点点云

3. point_to_point(点到点距离)

测量点对之间的欧氏距离。支持对称点自动配对(例如测量关于z=0对称的点对)。

工作流程:

  1. 获取测量点:在点云中查找最近点
  2. 根据z坐标符号自动配对(z>0和z<0的点配对)
  3. 计算每对点之间的欧氏距离
  4. 统计平均值、标准差等

配置参数:

type: "point_to_point"

# 点对配置(使用任务3的6个点,配对测量)
point_pairs:
  - name: "前端点对"
    point1: [-753.5, 1052.5, -1445]
    point2: [-753.5, 1052.5, 1445]
  - name: "中间点对"
    point1: [3446.5, 1053, -1445]
    point2: [3446.5, 1053, 1445]
  - name: "后端点对"
    point1: [8146.5, 1053, -1445]
    point2: [8146.5, 1053, 1445]

# 最近点搜索半径(mm)
search_radius: 10.0

输出结果:

  • 平均距离(mm)
  • 标准差(mm)
  • 最小/最大距离(mm)
  • 点对数量

可视化文件:

  • {任务名}_found_points.ply:包含测量点的点云

配置文件说明

基本结构

# 点云文件路径(必填)
pointcloud_file: "D:\\path\\to\\pointcloud.ply"

# 测量任务列表
tasks:
  - name: "任务名称"
    type: "测量类型"
    enabled: true/false
    description: "任务描述"
    visualization_dir: "visualizations"
    # ... 其他参数

通用参数

  • name:任务名称(必填),用于标识任务和命名输出文件
  • type:测量类型(必填),可选值:plane_to_plane、point_to_plane、point_to_point
  • enabled:是否启用任务(必填),设为false可跳过该任务
  • description:任务描述(可选),用于文档说明
  • visualization_dir:可视化输出目录(可选),设置后会保存ROI点云文件

包围盒格式

所有包围盒使用以下格式,坐标单位为毫米(mm):

bbox_min: [x_min, y_min, z_min]
bbox_max: [x_max, y_max, z_max]

坐标系说明:

  • X轴:列车横向(车头到车尾)
  • Y轴:列车高度(底部到顶部)
  • Z轴:列车纵向(左侧到右侧)

RANSAC参数调优

RANSAC用于平面拟合,以下参数影响拟合质量:

  • ransac_threshold:内点距离阈值(mm)

    • 较小值(1.0-2.0):严格拟合,适合高质量点云
    • 较大值(3.0-5.0):宽松拟合,适合噪声较多的点云
  • ransac_max_iterations:最大迭代次数

    • 默认1000次,通常足够
    • 如果内点率很低,可增加到2000-5000
  • min_inlier_ratio:最小内点比例

    • 默认0.6(60%),表示至少60%的点在平面上
    • 如果点云包含多个平面或噪声多,可降低到0.4-0.5

调优建议:

  1. 先运行一次,查看内点率
  2. 如果内点率低于min_inlier_ratio,任务会失败
  3. 根据实际内点率调整参数:
    • 内点率50%-60%:降低min_inlier_ratio或增大ransac_threshold
    • 内点率>90%:可以提高要求,减小ransac_threshold

添加新任务

步骤1:确定测量类型

根据测量需求选择合适的类型:

  • 平面到平面距离:车门高度、车体长度、窗口高度等
  • 点到平面距离:特定点到参考平面的高度
  • 点到点距离:对称点对之间的距离

步骤2:确定ROI包围盒

方法1:使用点云浏览器工具

方法2:使用CloudCompare或Open3D或Freecad手动查看

  • 打开点云文件
  • 使用测量工具确定目标区域的坐标范围
  • 记录包围盒的最小和最大坐标

步骤3:编辑配置文件

在 config/measurements.yaml 中添加新任务:

- name: "新任务名称"
  type: "plane_to_plane"  # 或其他类型
  enabled: true
  description: "任务描述"
  visualization_dir: "visualizations"
  
  source_roi:
    bbox_min: [x_min, y_min, z_min]
    bbox_max: [x_max, y_max, z_max]
  
  target_roi:
    bbox_min: [x_min, y_min, z_min]
    bbox_max: [x_max, y_max, z_max]
  
  params:
    sample_points: 100
    ransac_threshold: 2.0
    ransac_max_iterations: 1000
    min_inlier_ratio: 0.6

步骤4:运行测试

python main.py

步骤5:验证结果

  1. 查看Excel报告:检查测量结果是否合理
  2. 查看可视化点云:使用CloudCompare或Open3D打开PLY文件
    • 确认ROI提取的位置正确
    • 确认平面拟合质量(内点率)
  3. 调整参数:如果结果不理想,调整包围盒或RANSAC参数

技术细节

平面拟合算法

系统使用Open3D的RANSAC算法进行平面拟合:

  1. 随机采样:从点云中随机选择3个点
  2. 拟合平面:计算平面方程 ax + by + cz + d = 0
  3. 统计内点:计算所有点到平面的距离,距离小于阈值的为内点
  4. 迭代优化:重复上述步骤,选择内点最多的平面
  5. 最终拟合:使用所有内点进行最小二乘拟合(SVD),得到最优平面

平面方程: ax + by + cz + d = 0

  • (a, b, c):平面法向量(单位向量)
  • d:平面到原点的有向距离

距离计算

点到平面距离:

distance = |ax + by + cz + d| / sqrt(a² + b² + c²)

由于法向量已归一化(sqrt(a² + b² + c²) = 1),简化为:

distance = |ax + by + cz + d|

有向距离:

  • 正值:点在法向量指向的一侧
  • 负值:点在法向量相反的一侧
  • 绝对距离:取绝对值,不考虑方向

点到点距离(欧氏距离):

distance = sqrt((x2-x1)² + (y2-y1)² + (z2-z1)²)

性能优化

  • 点云缓存:点云文件只加载一次,所有任务共享
  • 自动降采样:ROI超过10000点时自动降采样到10000点进行SVD拟合
  • 并行处理:多个任务顺序执行,单个任务失败不影响其他任务