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

185 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

1. 系统目标
# 检测靶纸四角的等腰直角三角形标记(每个角一个)
# 计算激光落点在靶面上的二维偏移(厘米)
# 通过PnP算法估算靶面到相机的距离
2. 核心算法流程
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转换为米
3. 关键优化策略
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保持与标定矩阵一致
4. 数据流示例
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增强兜底可选
6. 性能特点
CPU友好默认Otsu单次处理多数场景10-30ms完成检测
内存可控最大候选数截断默认10个避免组合爆炸
嵌入式适配支持图像缩放早退机制降低计算量
7. 局限性
依赖四个等腰直角三角形需靶纸特殊设计
要求三角形内部足够暗与背景有对比度
单应性假设靶面为平面实际靶纸可能有轻微起伏
这套算法在射击训练系统中作为主要定位手段
8. 为了加速单应性的计算引入了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,)
不足再走 放宽 approxPolyDPBlackHat
后面同样是过滤四点组合/象限分配单应性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 里都可以开或关黑三角模型是独立开关