feat: initial commit - massive-cloud point cloud processing system
This commit is contained in:
486
alg/点云测距v1.1/train_measurement_system/README.md
Normal file
486
alg/点云测距v1.1/train_measurement_system/README.md
Normal file
@@ -0,0 +1,486 @@
|
||||
# 列车点云测量系统
|
||||
|
||||
基于配置驱动的点云测量系统,支持多种测量任务类型。通过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. 创建并激活环境
|
||||
|
||||
```bash
|
||||
# 创建 conda 环境
|
||||
conda create -n pcc-experiment python=3.9
|
||||
conda activate pcc-experiment
|
||||
```
|
||||
|
||||
### 2. 安装依赖
|
||||
|
||||
**方式一:使用 requirements.txt**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
**方式二:安装项目**
|
||||
```bash
|
||||
# 正常安装
|
||||
pip install .
|
||||
|
||||
# 或开发模式安装(代码修改立即生效)
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
安装项目会自动安装所有依赖包,并将项目注册到 Python 环境中。
|
||||
|
||||
### 2. 准备点云文件
|
||||
|
||||
确保你有完整的列车点云文件(PLY格式),例如:
|
||||
```
|
||||
D:\lab\PCC\PCC\head_train_pointcloud\train_2_100M.ply
|
||||
```
|
||||
|
||||
### 3. 配置测量任务
|
||||
|
||||
编辑 `config/measurements.yaml`,设置点云文件路径和测量任务。
|
||||
|
||||
**支持相对路径(相对于配置文件)或绝对路径:**
|
||||
|
||||
```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. 运行测量
|
||||
|
||||
```bash
|
||||
# 使用默认配置文件
|
||||
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. 统计平均值、标准差、最小/最大距离
|
||||
|
||||
**配置参数:**
|
||||
```yaml
|
||||
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模式):**
|
||||
```yaml
|
||||
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模式):**
|
||||
```yaml
|
||||
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. 统计平均值、标准差等
|
||||
|
||||
**配置参数:**
|
||||
``` yaml
|
||||
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`:包含测量点的点云
|
||||
|
||||
---
|
||||
|
||||
## 配置文件说明
|
||||
|
||||
### 基本结构
|
||||
|
||||
```yaml
|
||||
# 点云文件路径(必填)
|
||||
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):
|
||||
|
||||
```yaml
|
||||
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` 中添加新任务:
|
||||
|
||||
```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:运行测试
|
||||
|
||||
```bash
|
||||
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拟合
|
||||
- **并行处理**:多个任务顺序执行,单个任务失败不影响其他任务
|
||||
|
||||
Reference in New Issue
Block a user