返回专辑
·Johan·4 分钟阅读

霍夫直线:结构化场景

HoughLinesP 在结构化场景(标线、PCB)仍可靠;rho/theta 分辨率和 Canny 预处理决定峰值质量。

霍夫直线:结构化场景

1. 标线检测假线爆炸,多半是边缘而非霍夫

仓库 AGV 用固定顶视相机跟地面引导线。初版 HoughLinesP 在 demo 走廊完美,换到真实库区后 overlay 上全是斜线——调 threshold 从 50 到 200 只是假线多少在变,漏检的长引导线仍在。根因是 Canny 在反光环氧和阴影交界产出碎边;霍夫只是在错误边缘上投票,不是算法「不灵」。这类问题在日志里往往表现为「霍夫参数已调到极限」,实际上应该回到边缘图肉眼检查。

霍夫适合 直线先验明确 的场景:地面标线、PCB 走线、建筑立面。曲线、断裂边、clutter 背景应换 RANSAC line fit 或 learned detector,别在错误模型上堆参数。判断该不该继续用霍夫,先看物理场景是否真的是直线主导,而不是先看 OpenCV 文档里还有哪些旋钮。

2. 参数空间与 API 选择

直线用 表示。HoughLines 返回 无限直线;工程里更常用 HoughLinesP 返回线段端点,便于算角度和画 ROI。标准式适合需要解析整条直线的标定辅助;概率式适合控制与测量。

python
edges = cv2.Canny(gray, 50, 150)
lines = cv2.HoughLinesP(
    edges, rho=1, theta=np.pi / 180, threshold=80,
    minLineLength=100, maxLineGap=10)

threshold 是累加器投票门槛;minLineLength / maxLineGap 控制碎片化。rho=1 px、theta=π/180(1°)是常见默认;近水平 dominant 的场景可加密 θ 到 0.5°,精细测角时再调。分辨率从 720p 升到 4K 时,pixel 阈值不能原样搬,应按宽度比例缩放或重新标定。

3. 预处理比 threshold 优先

边缘弱 → 无 peak;边缘碎 → 假 peak 爆炸。我的顺序:ROI mask 限制搜索区(bitwise_and(edges, mask))→ 调 Canny 双阈值 → 最后动霍夫 threshold。全图霍夫在纹理地面(瓷砖缝、阴影栅格)会产生平行 peak 簇,mask 到引导线预期带比全局降 threshold 有效得多。现场调试时我会把 Canny 输出和霍夫 overlay 录进 bag,回放对比「边缘质量变好的一周」和「假线爆炸的一周」,比口头调参可审计。

Probabilistic Hough 随机采样边缘点,速度与图像大小弱相关;结构化场景仍够快。圆孔检孔用 HoughCirclesHOUGH_GRADIENT),param1 是 Canny 高阈值,param2 是累加器 threshold——直线和圆共用同一前置:边缘质量决定成败

4. 透视与模型边界

透视下物理直线在 pinhole 图像里仍是直线——霍夫 OK。曲面(圆柱罐体、广角强畸变边缘)上「看起来直」的线不满足全局单应,应 undistort 后再检或在 3D 拟合。重复纹理(货架竖棱)会产生多组平行 peak,需结合空间先验(引导线应在 ROI 内、角度接近行驶方向)做后验筛选。RANSAC 两点式 line fit 对 outlier 边有时更简,但没有累加器峰值可视化——debug 时并排看 edge 与 inlier 更快定位问题层。

5. 下游几何:从线段到控制量

检测到线段后,工程关心的是 横向偏差航向角,不是线段数量。对每条候选线算与行驶方向的夹角,丢弃 |Δθ|>15° 的 peak;再用 ROI 内距图像中心的法向距离估计横向 offset。多线时选 vote 最高且与上一帧时间一致的线,避免帧间跳线。参数写进 yaml:canny_low/highhough_thresholdmin_line_lengthangle_gate_deg,换相机或分辨率时整包重标。

6. 与 undistort 的衔接

广角顶视未 undistort 时,物理直线在像素域仍是直线,但 等距采样 在边缘会偏——测角用图像中心附近线段更稳。若标定可用,在 undistort 图上跑 Canny+霍夫,threshold 仍用 pixel 单位;别在 raw 图上检完再手工 undistort 端点,顺序错会引入额外 bias。标定与检测分辨率不一致时,先统一 K 再谈霍夫阈值。

7. 失败模式

现象常见原因
假线过多Canny 碎 / threshold 过低
漏长线minLineLength 过大 / 边缘断
角度量化误差θ step 太粗
重复平行线纹理周期 / 未 mask

8. 验收

已知标线 scene 的 detection recall(线段 IoU 或角度误差 < 2°)。Accumulator 或 edge overlay 可视化,确认 peak 与真线对应。下游 metric:引导线角度/间距误差、AGV 横向偏差。720p 与 4K 分开标阈值;录 bag 回放固定参数,对比 inlier 线数与横向误差相关性。上线前用 hold-out 库区 clip 跑一晚,假线率超 SOP 则回滚 yaml 而不是继续拧霍夫。

霍夫是 结构化 prior 的 cheap exploit:固定相机、强直线结构时仍可靠。场景不符合直线模型时,换模型比硬调参诚实。

← 全部文章

johan's blog