Files
archery/design_doc/algo.md
2026-05-08 23:41:42 +08:00

7.9 KiB
Raw Blame History

  1. 系统目标

检测靶纸四角的等腰直角三角形标记(每个角一个)

计算激光落点在靶面上的二维偏移(厘米)

通过PnP算法估算靶面到相机的距离

  1. 核心算法流程 2.1 三角形检测 (detect_triangle_markers) 采用多策略级联保证鲁棒性: 图像输入 → 多阈值策略 → 候选三角形过滤 → 四点匹配 检测策略(按优先级):

1.全局Otsu二值化最快~10ms 2.自适应阈值多种block size光照不均时 3.ROI局部阈值候选不足3个时分象限独立处理 4.Black-Hat形态学增强仍不足时突出暗色标记

三角形几何验证:

必须是直角三角形检查勾股定理容差20%

两直角边长度差<20%

内部像素足够暗灰度≤130暗像素比例≥30%

与周围背景对比度≥15灰度级

四点匹配算法:

从候选三角形中枚举所有4点组合

计算四边形评分:(对角比-1)*3 + (水平比-1) + (垂直比-1) + (边长偏差)*2

选择评分最低的组合作为四角标记

2.2 单应性落点计算 (homography_calibration) 建立图像坐标系 → 靶面坐标系(二维平面)的透视变换

将激光点像素坐标映射到靶面坐标(厘米)

使用RANSAC提高鲁棒性阈值1像素

2.3 PnP距离估计 (pnp_distance_meters) 已知四个标记点的三维坐标x,y,z单位cm

通过solvePnP求解相机外参旋转+平移)

距离 = ‖平移向量‖ / 100转换为米

  1. 关键优化策略 3.1 多路径投票 同一图像区域被不同二值化方法检测到时path_votes++

选择投票数高的候选,提高检测可信度

3.2 早退机制 候选≥3个 且 覆盖3个以上象限 → 停止更多阈值尝试

大幅降低嵌入式设备计算开销

3.3 3点补全机制 当只检测到3个角时通过仿射变换估算第4个角位置

公式P_missing = M_inv @ [x_target, y_target, 1]

3.4 图像缩放 默认缩放到0.5倍进行检测由config控制

坐标还原时乘以inv_scale保持与标定矩阵一致

  1. 数据流示例 python 输入:
  • img_rgb: H×W×3 图像
  • laser_xy: (x_px, y_px) 激光点像素坐标
  • marker_positions: {0:[0,0,0], 1:[0,30,0], 2:[30,30,0], 3:[30,0,0]} # 4角3D坐标(cm)

输出: { "ok": True, "dx_cm": 2.5, # 靶面X偏移(cm向右为正) "dy_cm": -3.2, # 靶面Y偏移(cm向上为正) "distance_m": 5.43, # 相机到靶面距离(米) "offset_method": "triangle_homography", "distance_method": "pnp_triangle" } 5. 鲁棒性设计 5.1 参数自适应 从config.py动态读取所有阈值可在线调整

三角形边长范围、灰度阈值、对比度要求等均可配置

5.2 异常处理 角点退化检测(距离<3像素判定为重复

NaN/Inf校验单应性矩阵、偏移量、距离

距离合理性检查0.3~20米

5.3 降级策略 PnP失败 → 只输出偏移距离置None

4角检测失败 → 尝试3角补全

快速路径失败 → CLAHE增强兜底可选

  1. 性能特点 CPU友好默认Otsu单次处理多数场景10-30ms完成检测

内存可控最大候选数截断默认10个避免组合爆炸

嵌入式适配:支持图像缩放、早退机制降低计算量

  1. 局限性 依赖四个等腰直角三角形(需靶纸特殊设计)

要求三角形内部足够暗、与背景有对比度

单应性假设靶面为平面(实际靶纸可能有轻微起伏)

这套算法在射击训练系统中作为主要定位手段。

  1. 为了加速单应性的计算引入了yolo模型一共做了两个模型一个为靶纸和黑色三角形一体的识别模型用于做原照片上快速找到靶纸区域。另一个模型是黑色三角形的模型用于做靶纸区域再找黑色三角形。但是经过对比发现引入黑色三角形模型反而更慢。入下面的流程A和流程B yolo靶纸+传统流程B yolo靶纸+yolo黑色三角形流程A 平均值 646.08 916.4457143 标准差 94.61300968 57.40401849

公共前置(两条路都一样) 是否用靶环模型裁 Stage1

TRIANGLE_YOLO_ROI_ENABLE=True 时:跑 靶环 YOLO得到全图上的 roi_xyxy后面的三角形都在 img_work = 全图[roi] 上做(必要时再缩成 img_det 给整图传统分支用)。 False 时roi_xyxy=None三角形在 整幅相机图 上当 img_work。 之后都进入 try_triangle_scoring(img_cv, …, roi_xyxy=…, black_yolo_boxes_work=…)

在里面先做灰度、v_suppress、锐化、det_scale 缩略图等 prep与是否黑三角模型无关。 差别从 black_yolo_boxes_work 有没有有效子框列表 开始。

流程 A用黑色三角形模型Stage2 黑三角 YOLO 配置要点TRIANGLE_BLACK_YOLO_ENABLE=True且 TRIANGLE_BLACK_TRIANGLE_LOCATE_MODE="yolo",并且 已有 Stage1 裁切roi_xyxy 不能为 None否则根本不会跑黑三角 YOLO

步骤概要:

try_black_triangle_boxes_work

输入:全图 RGB + Stage1 的 ring_roi_xyxy。 在 Stage1 裁切图(与训练一致的 slab上跑 黑三角 YOLO得到若干个 子框black_boxes_work坐标在 裁切图/work 系)。 try_triangle_scoring 内

若 black_yolo_boxes_work 非空: 按配置在 Stage1 全分辨率灰度(或缩略灰度,视 det_scale / TRIANGLE_BLACK_YOLO_PATCH_GRAY_SOURCE对每个子框裁 patch跑 _extract_triangle_from_yolo_patch子框内Otsu → 失败再单次 Adaptive + 轮廓 + 形状/颜色)。 median_leg 过滤,再 四点分配 ID。 若 ≥3 个(通常 4 个)有效:认为 Stage2 成功,跳过 整幅 Stage1 上的 detect_triangle_markers。 若 不足 3 个 且未关 fallback在 缩略后的整幅 work 灰度上再走 detect_triangle_markers整图 Otsu + 整图 Adaptive×block_sizes + 各类 fallback与「不用黑三角模型时的传统主路径」同类。 后续

角点从 det 坐标 ×inv_scale 回到 work再 +roi 原点 回到全图;单应性、补第 4 点、PnP 等与另一条路相同。 耗时上多出来的部分:黑三角 YOLO 推理 + 每个子框一遍传统小流水线(成功时通常 不再付整图 detect_triangle_markers

流程 B不用黑色三角形模型纯传统定位三角 典型配置(任一即可达到「不用黑三角模型」的效果):

TRIANGLE_BLACK_YOLO_ENABLE=False或 TRIANGLE_BLACK_TRIANGLE_LOCATE_MODE="traditional"(即使模型开关开着也不跑黑三角 YOLO或 没有 Stage1 ROIroi_xyxy is None当前逻辑下 也不会跑 Stage2 黑三角 YOLO。 此时 black_yolo_boxes_work=None或不等价于「有子框」

步骤概要:

try_triangle_scoring 内 不跑 子框 _extract_triangle_from_yolo_patch。 直接在 img_det缩略后的 work 上调用 detect_triangle_markers 全局 Otsu若 TRIANGLE_SKIP_GLOBAL_OTSU_EXTRACT_ON_YOLO_ROI 在有 ROI 时可能 不算 Otsu 轮廓,但仍会生成 Otsu 图供后续用); 可选 象限 ROITRIANGLE_ROI_ENABLED 整图 AdaptiveTRIANGLE_ADAPTIVE_BLOCK_SIZES例如 (11,) 不足再走 放宽 approxPolyDP、BlackHat 等。 后面同样是过滤、四点组合/象限分配、单应性、PnP 等。 特点:没有黑三角 NPU 时间,也 没有「按框重复 4 次子框传统」;但要在 一整张缩略ROI 图 上跑一套更重的 整图 pipeline。

对照一句话 用黑三角 YOLO流程 A 不用黑三角 YOLO流程 B Stage2 黑三角模型给子框 → 子框内 Otsu + 至多一次 Adaptive 无 Stage2 模型 三角角点从哪来 优先 子框传统;不够再 整图 detect_triangle_markers 只有 整图 detect_triangle_markers 和「全图是否只做 Adaptive」 子框 不是只做 Adaptive整图回退时也与全图路径一致先 Otsu 等) 整图路径 也不是只做 Adaptive 靶环 YOLOStage1 裁切)在 A/B 里都可以开或关,与「黑三角模型」是独立开关。