# 入户门位置检测与导出工具 基于 YOLOE 实例分割和 RGB-D 点云的入户门位置检测工具,支持从全景图像序列中检测入户门并导出其 3D 位置。 ## 功能特性 - **门实例检测**:使用 YOLOE 模型检测全景图中的各类门 - **3D 点云重建**:从 RGB-D 图像生成世界坐标系点云 - **3D 门框估计**:基于实例分割 mask 估计门的 3D 包围盒 - **入户门识别**:通过多特征评分识别入户门 - **fallback 机制**:未检测到门时基于点位可见性估计入户门位置 - **可视化输出**:支持导出带颜色的点云 + 红色球体标记的 PLY 文件 ## 环境要求 - Python 3.10+ - CUDA 12+ (可选,用于 GPU 加速) - conda 环境:`yolo26` ### 主要依赖 ``` torch ultralytics (YOLOE) open3d opencv-python numpy scipy tqdm ``` ## 目录结构 ``` high_temp/ ├── export_entrance_position.py # 主脚本 ├── camera_spherical.py # 球面相机内参模型 ├── yoloe-26x-seg.pt # YOLOE 实例分割模型 ├── scene0001/ # 场景示例 │ ├── pano_img/ # 全景 RGB 图像 │ ├── depth_img/ # 深度图像 │ ├── vision.txt # 点位姿态和可见性信息 │ └── output/ # 输出目录 └── README.md ``` ## 使用方法 ### 基础用法 ```bash # 激活环境 conda activate yolo26 # 处理单个场景 python export_entrance_position.py -s scene0001 # 指定输出路径 python export_entrance_position.py -s scene0001 -o output/entrance.json # 带可视化输出 python export_entrance_position.py -s scene0001 --vis_ply ``` ### 参数说明 | 参数 | 简写 | 默认值 | 说明 | |------|------|--------|------| | `--scene` | `-s` | 必需 | 场景文件夹路径 | | `--output` | `-o` | `None` | 输出 JSON 文件路径 | | `--model` | `-m` | `yoloe-26x-seg.pt` | YOLOE 模型路径 | | `--conf` | | `0.35` | 检测置信度阈值 | | `--iou` | | `0.45` | NMS IoU 阈值 | | `--voxel-size` | | `0.03` | 点云体素下采样尺寸 | | `--imgsz` | | `1024 2048` | YOLOE 输入图像尺寸 (高 宽) | | `--vis_ply` | | `False` | 是否导出可视化 PLY 文件 | ### 使用示例 ```bash # 使用更高置信度阈值 python export_entrance_position.py -s scene0001 --conf 0.5 # 使用更小的图像尺寸(加快处理速度) python export_entrance_position.py -s scene0001 --imgsz 640 1280 # 完整参数示例 python export_entrance_position.py \ -s scene0001 \ -o results/entrance.json \ --conf 0.4 \ --iou 0.5 \ --voxel-size 0.05 \ --vis_ply ``` ## 输入数据格式 ### 场景文件夹结构 ``` scene0001/ ├── pano_img/ # 全景 RGB 图像(JPG 格式,以点位 ID 命名) │ ├── 1.jpg │ ├── 2.jpg │ └── ... ├── depth_img/ # 深度图像(PNG 格式,16 位深度) │ ├── 1.png │ ├── 2.png │ └── ... └── vision.txt # JSON 格式,包含点位姿态和可见性信息 ``` ### vision.txt 格式 ```json { "sweepLocations": [ { "uuid": "1", "id": 1, "pose": { "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "translation": { "x": 0, "y": 0, "z": 0 } }, "puck": { "z": -1.56 }, "visibles": [2, 3, 4] } ] } ``` ## 输出格式 ### entrance_position.json ```json { "scene_name": "scene0001", "entrance_position": { "x": 5.24, "y": -1.84, "z": -0.34 }, "source": "door_detection", "is_estimated": false, "door_info": { "door_id": 0, "confidence": 0.68, "dimensions": { "width": 1.04, "height": 2.56, "thickness": 0.06 }, "center": { "x": 5.24, "y": -1.84, "z": -0.34 }, "bbox_min": { "x": 4.73, "y": -1.87, "z": -1.62 }, "bbox_max": { "x": 5.76, "y": -1.81, "z": 0.95 } }, "source_detections": [ { "pose_uuid": "8", "detection_confidence": 0.68, "image": "8.jpg" } ], "metadata": { "all_poses_count": 12, "processing_info": { "total_candidates": 1, "merged_doors": 1, "valid_doors": 1 } } } ``` ### vis.ply(可视化文件) - **格式**:ASCII PLY(兼容 MeshLab、CloudCompare) - **内容**:场景点云(真实 RGB 颜色)+ 红色球体(入户门位置) - **球体**:半径 0.2m,红色 (255, 0, 0) ## 代码结构解析 ### 核心类:`EntranceDoorDetector` ``` EntranceDoorDetector ├── __init__() # 初始化:加载位姿、模型、参数 ├── detect_and_identify() # 主流程:检测门并识别入户门 ├── export_json() # 导出 JSON 结果 └── export_vis_ply() # 导出可视化 PLY ``` ### 关键方法 | 方法 | 功能 | |------|------| | `_load_poses()` | 从 vision.txt 加载点位姿态 | | `_build_pose_matrix()` | 构建 4x4 位姿变换矩阵 | | `_mask_to_3d_points()` | 将 2D mask 映射到世界坐标 3D 点 | | `_merge_3d_doors()` | 使用并查集合并重叠的 3D 门候选 | | `_filter_door_by_properties()` | 根据物理特性过滤门(尺寸等) | | `_filter_door_by_ground_puck()` | 根据地面距离过滤门 | | `_identify_entrance_door()` | 识别入户门(多特征评分) | | `_estimate_entrance_from_poses()` | 基于点位可见性估计入户门 | ### 算法流程 ``` 1. 加载数据 ├── 读取 vision.txt 获取点位姿态 ├── 加载 YOLOE 模型 └── 准备 RGB 和深度图像 2. 门检测与 3D 重建 ├── YOLOE 实例分割检测门 ├── mask + depth → 3D 点云 ├── 过滤离群点和深度不一致点 └── 计算 3D 包围盒 3. 多帧融合 ├── 融合所有点位的点云 ├── 体素下采样 ├── 使用并查集合并重叠的 3D 门 └── 过滤无效门(尺寸、地面距离) 4. 入户门识别 ├── 尺寸评分(接近标准门尺寸) ├── 边缘评分(远离其他门) ├── 视角评分(多帧可见) ├── 边界评分(靠近空间轮廓边界) └── 选择综合评分最高的门 5. Fallback:点位估计 ├── 可见性一致性过滤室内点位 ├── 计算边界距离和中心距离评分 └── 选择最佳点位作为入户门估计位置 6. 输出结果 ├── 导出 JSON 文件 └── (可选)导出可视化 PLY ``` ### 入户门评分系统 | 评分项 | 权重 | 计算方式 | |--------|------|----------| | 尺寸评分 | 30 分 | 接近高 2.1m×宽 1.0m 得分高 | | 边缘评分 | 25 分 | 远离其他门中心得分高 | | 视角评分 | 10 分 | 被更多帧拍摄到得分高 | | 边界评分 | 30 分 | 靠近空间轮廓边界得分高 | ## 可视化查看 ### MeshLab 中查看 1. 打开 MeshLab 2. `File` → `Import Mesh` 3. 选择 `output/vis.ply` 4. 灰色点云为场景,红色球体为入户门位置 ### CloudCompare 中查看 1. 打开 CloudCompare 2. `File` → `Open` 3. 选择 `output/vis.ply` 4. 启用颜色渲染模式 ## 常见问题 ### Q: 未检测到任何门? A: 检查以下项: - 降低 `--conf` 阈值(如 0.25) - 确认 RGB 和深度图像匹配 - 检查 vision.txt 格式是否正确 ### Q: 入户门识别错误? A: 可能是评分权重问题,可调整: - 修改 `_identify_entrance_door()` 中的评分权重 - 增加边界评分权重可提高边缘门的选择概率 ### Q: PLY 文件在 MeshLab 中无法显示? A: 确保使用 ASCII 格式输出,当前代码已默认使用 ASCII 格式。 ## 许可证 MIT License