HALCON + BOP:从深度图到6D Pose

「Halcon 项目」。
/~b4fb3ZrHFz~:/
链接:https://pan.quark.cn/s/1ee336f5e76d

HALCON + BOP:从深度图到6D Pose

这份资料记录了从选择数据集、理解ROI和点云,到用HALCON完成Surface Matching、稠密Pose精修、6D Pose显示、计时优化和100帧精度评估的全过程。

建议第一次阅读时按章节顺序看;以后查代码时可以直接跳到“关键代码位置”和“当前结论”。

1. 当前环境与数据

软件

  • HALCON版本:22.11 Steady

  • HALCON安装目录:E:\Halcon2022\MVTec\HALCON-22.11-Steady

  • BOP数据目录:E:\BOP-Dataset\lm

  • 当前学习资料:本文件所在目录

为什么改用BOP数据集

最初考虑使用RealSense D435i和Replica room0:

  • D435i现场深度噪声较明显,刚开始不利于判断算法错误还是传感器错误。

  • Replica适合室内场景重建和相机轨迹实验,但不方便直接学习“已知物体CAD模型的6D Pose”。

  • BOP LM同时提供RGB、深度、相机内参、PLY模型、物体Mask和6D Pose真值,更适合验证完整流程。

当前对象和场景

数据集:BOP LM 物体:obj_000008,电钻 PLY模型:E:\BOP-Dataset\lm\models\obj_000008.ply 测试场景:E:\BOP-Dataset\lm\test\000008 单帧示例:000404

场景000008中已有:

  • 200张RGB图

  • 200张深度图

  • 200张普通Mask

  • 200张可见Mask

  • 200帧相机参数和6D Pose真值

  • 电钻在全部200帧中出现

文件编号不是连续的000000~000199,实际范围约为000004~001185

数据集来源与最小组合

  • BOP官网:https://bop.felk.cvut.cz

  • Hugging Face数据集主页:https://huggingface.co/bop-benchmark/datasets

为了完成当前电钻实验,最少需要:

lm/models/obj_000008.ply lm/models/models_info.json lm/test/000008/rgb lm/test/000008/depth lm/test/000008/mask_visib lm/test/000008/scene_camera.json lm/test/000008/scene_gt.json lm/test/000008/scene_gt_info.json

当前E:\BOP-Dataset\lm已经包含所需内容,不需要再次下载。数据集已经给出电钻PLY模型,因此这一阶段不需要自己使用CAD软件重新制作模型。

BOP目录结构

E:\BOP-Dataset\lm ├─ models │ ├─ obj_000008.ply 电钻三维模型 │ └─ models_info.json 模型尺寸信息 └─ test\000008 ├─ rgb RGB图 ├─ depth 深度图 ├─ mask 完整物体Mask ├─ mask_visib 当前画面可见部分Mask ├─ scene_camera.json 相机内参、深度比例 ├─ scene_gt.json 6D Pose真值 └─ scene_gt_info.json 可见比例、真值框等信息

2. 最终流水线

RGB与深度图 → 检测框或分割Mask得到ROI → 深度图反投影成X/Y/Z图 → xyz_to_object_model_3d生成场景点云 → 读取PLY模型 → create_surface_model生成参考Surface Model → find_surface_model进行全局粗匹配 → dense_pose_refinement进行稠密Pose精修 → 得到T_camera_object → 显示红绿蓝坐标轴 → 与BOP真值比较

完整流程总图:

3. 十个处理阶段

3.1 原始RGB

RGB图方便人和二维检测器识别物体,但RGB像素本身没有三维距离。

3.2 深度图

深度图的每个有效像素保存一个距离值Z。BOP原始深度以整数形式保存,本例按depth_scale转换后再除以1000得到米。

3.3 ROI

ROI是Region of Interest,即感兴趣区域。它的作用是只保留目标附近的深度点,减少桌面、玩具和背景对配准的干扰。

当前单帧程序默认使用矩形框模拟二维检测器输出;调试时也可以使用BOP可见Mask。

3.4 深度图转换为XYZ图

用相机内参将像素坐标和深度反投影到相机三维坐标系:

X = (u - Cx) × Z / Fx Y = (v - Cy) × Z / Fy Z = 深度

其中Fx/Fy是焦距,Cx/Cy是主点,u/v是图像列和行。

3.5 ObjectModel3D场景点云

同一个像素位置的X、Y、Z组成一个三维点,所有有效点组合后就是场景点云。

HALCON关键代码:

xyz_to_object_model_3d (ImageX, ImageY, ImageZ, SceneModel3D)

3.6 PLY/CAD模型

PLY是物体的标准三维几何模型。它不一定必须由自己使用CAD软件制作,也可以来自数据集、三维扫描、厂家或公开模型。

在配准中,PLY模型是需要被移动和旋转的“参考模型”;现场深度形成的点云是“场景模型”。

3.7 Surface Model

create_surface_model会对PLY表面采样,建立点对几何特征、表面法向和搜索结构。

create_surface_model ( CADModel3D, 0.01, ['model_invert_normals'], ['true'], SurfaceModelID )

训练Surface Model较慢,但同一个物体只需离线创建一次。现在程序会将其缓存,后续用read_surface_model直接读取。

3.8 全局粗匹配

HALCON Surface-Based Matching先对场景降采样并选择关键点,再比较场景点对和CAD点对的距离及相对方向,生成候选Pose。

随后默认进行稀疏Point-to-Plane姿态优化。因此这里的“粗配”更准确地说是:

点对特征全局搜索 + 稀疏点到平面Pose优化

3.9 稠密Pose精修

设置dense_pose_refinement='true'后,HALCON使用更多场景点,让场景点到最近CAD切平面的距离尽量小。

这可以理解为HALCON封装的稠密Point-to-Plane ICP风格优化。

find_surface_model ( SurfaceModelID, SceneModel3D, RelSamplingDistance, KeyPointFraction, 0.05, 'false', ['num_matches','scene_invert_normals','dense_pose_refinement'], [1,'true','true'], PoseEstimated, Score, SurfaceMatchingResultID )

3.10 6D Pose

6D Pose包含:

  • 三个平移量:X、Y、Z

  • 三个旋转量:Rx、Ry、Rz

最终矩阵:

HomMat3DEstimated = T_camera_object

它表示“物体模型坐标系中的点如何变换到相机坐标系”。

pose_to_hom_mat3d (PoseBest, HomMat3DEstimated)

红轴是X,绿轴是Y,蓝轴是Z;轴原点表示物体位置,轴方向表示物体旋转。

HALCON当前直接输出:

图中:

  • 红色轮廓:BOP真值Pose

  • 绿色轮廓:HALCON预测Pose

  • 红/绿/蓝箭头:预测物体坐标系X/Y/Z

  • T(mm):物体原点相对于相机的位置

  • R(deg):HALCON Pose中的三个旋转角

4. 单帧结果

示例帧000404使用矩形ROI时:

场景点数:43,745 粗配平移误差:8.10 mm 粗配旋转误差:4.72° 精修平移误差:约1.72 mm 精修旋转误差:约0.71°

这个结果说明:

  • 全局粗配成功找到了正确物体附近。

  • 稠密精修显著降低了位置和角度误差。

  • 深度单位、相机内参、CAD比例和法向方向基本正确。

  • 单帧结果很好,但不能代表全部观察角度。

5. 为什么最初运行很慢

初始程序内部计时:

阶段时间
深度、ROI、XYZ点云约0.015秒
每帧重新创建Surface Model约8.99秒
额外粗配测试约8.78秒
第二次完整匹配和精修约8.00秒
总时间约29.70秒

主要问题有两个:

  1. Surface Model原本每帧重新训练。

  2. 为比较粗配和精配,程序把全局搜索完整执行了两次。

优化后:

  • Surface Model离线生成并缓存。

  • 生产模式只执行一次带稠密精修的匹配。

  • 可使用ShowVisualization := 0关闭轮廓、坐标轴和PNG输出。

显示和保存结果图本身约需3~4秒,因此“算法时间”和“带显示的演示时间”要分开看。

6. 100帧批量评估

为了避免被单帧结果误导,从200帧中均匀选择了100帧,并使用BOP可见真值Mask,先测试Surface Matching本身。

快速参数

RelSamplingDistance = 0.015 KeyPointFraction = 0.5

结果:

  • 返回Pose:44/100

  • 正确且低于5 mm、5°:14/100

  • 低于2 mm、1°:1/100

  • 平均匹配时间:约0.285秒

保守参数

RelSamplingDistance = 0.010 KeyPointFraction = 1.0

结果:

  • 返回Pose:63/100

  • 正确且低于5 mm、5°:21/100

  • 低于2 mm、1°:1/100

  • 平均匹配时间:约1.342秒

  • 返回结果中的平移误差中位数:约5.83 mm

  • 返回结果中的旋转误差中位数:约1.63°

  • 旋转误差P95接近178°,存在严重错误翻转

100帧测试带来的关键认识

000404上的约1.72 mm / 0.71°是一个效果很好的样例,但当前配置不能稳定覆盖不同观察角度。

当前真正的瓶颈是“粗配候选错误”,而不是最后的稠密精修:

错误的全局候选Pose → 稠密精修进入错误局部极值 → 产生几十毫米或接近180°的错误

精修只能改善已经接近正确解的初始Pose,不能稳定挽救完全错误的粗配。

7. 当前主程序开关

主程序:code/bop_lm_obj8_6d_pose.hdev

ROI模式

UseGroundTruthMask := 0
  • 0:矩形ROI,模拟检测器目标框

  • 1:BOP可见真值Mask,仅用于调试和算法上限测试

精度模式

AccuracyMode := 1
  • 1:保守参数0.010 / 1.0,召回和精度优先

  • 0:快速参数0.015 / 0.5,仅适合实验

可视化

ShowVisualization := 1
  • 1:显示红绿轮廓、6D坐标轴和Pose数值

  • 0:关闭图形输出,用于生产计时或批处理

是否额外运行粗配基准

RunCoarseBenchmark := 0
  • 0:生产模式,只匹配一次

  • 1:额外运行一次不带Dense Refinement的匹配,用来比较粗配和精修误差

8. 文件说明

HALCON和Python代码

  • code/bop_lm_obj8_6d_pose.hdev:单帧完整流程、计时和6D Pose显示

  • code/benchmark_bop_lm_obj8_halcon.hdev:单帧参数扫描

  • code/bop_lm_obj8_batch100_eval.hdev:100帧HALCON批量评估

  • code/prepare_bop_lm_obj8_batch100.py:准备100帧ID、真值矩阵和可见比例

  • code/analyze_bop_lm_obj8_batch100.py:汇总100帧结果

  • code/bop_lm_obj8_visualize.py:生成十张流程图

  • code/make_bop_pipeline_montage.py:拼接流程总图

结果

  • results/bop_lm_obj8_batch100_results.csv:两组参数的逐帧结果

  • results/bop_lm_obj8_batch100_summary.json:100帧汇总指标

  • results/bop_lm_obj8_batch100_worst20.csv:最差20帧

  • results/bop_lm_obj8_parameter_benchmark.tup:单帧参数扫描原始结果

  • results/bop_lm_obj8_timing_result.tup:分阶段计时

Surface Model缓存约65 MB,为避免在资料包中复制两份,仍保存在上一级目录:

../obj_000008_surface_model.sfm

9. 如何在HDevelop中运行

  1. 打开code/bop_lm_obj8_6d_pose.hdev

  2. 确认E:\BOP-Dataset\lm存在。

  3. 确认上一级outputs目录中存在obj_000008_surface_model.sfm

  4. 初次学习保持:

    ShowVisualization := 1 AccuracyMode := 1 RunCoarseBenchmark := 0
  5. 运行后观察图形窗口中的红绿轮廓、XYZ坐标轴和Pose数值。

  6. 查看输出的HomMat3DEstimated,它就是T_camera_object

批量测试时打开code/bop_lm_obj8_batch100_eval.hdev,该程序默认关闭逐帧图形显示,只输出数值结果。

10. 下一步优化方向

后续继续使用HALCON,建议按这个顺序进行:

  1. num_matches由1改为5~10,保留多个粗配候选。

  2. 根据深度残差、轮廓重合和可见面积重新选择候选Pose。

  3. 对低Score或残差异常的Pose执行拒绝,不发送给机器人。

  4. 加入相机视角和允许旋转范围约束,排除不可能的180°翻转。

  5. 尝试支持3D边缘的Surface Model。

  6. 将最差20帧逐一生成轮廓和坐标轴图,寻找共同失败模式。

  7. 连续视频使用上一帧Pose调用refine_surface_model_pose进行跟踪,丢失时才重新全局搜索。

  8. 接入D435i后重新标定内参,过滤飞点和深度边缘噪声,并单独统计真实相机精度。

  9. 机械臂场景还需要加入手眼标定误差,最终系统误差不等于单独的Pose误差。

11. 当前阶段结论

已经完成:

  • BOP LM最小数据准备

  • 深度图到XYZ和ObjectModel3D

  • PLY到Surface Model

  • HALCON全局Surface Matching

  • 稀疏和稠密Point-to-Plane Pose优化

  • T_camera_object输出

  • BOP真值误差计算

  • 红绿轮廓与6D坐标轴显示

  • Surface Model缓存和分阶段计时

  • 100帧速度、召回和精度验证

尚未完成生产要求:

  • 跨视角粗配稳定性不足

  • 错误Pose拒绝机制不足

  • 多候选重排序尚未实现

  • D435i真实数据尚未重新评估

  • 手眼标定和机器人坐标变换尚未接入

当前最重要的工程任务不是继续盲目调整Dense Refinement,而是提高全局候选的召回、筛选正确候选并可靠拒绝错误Pose。