OpenCV圆形射击靶弹孔检测优化方案咨询
霍夫圆检测弹孔效果差是必然的——弹孔根本不是标准正圆,边缘经常带毛边、破损,再加上靶面本身的环形印刷线会产生大量干扰边缘,霍夫圆的梯度投票机制很容易被杂讯带偏,参数调得再死也容易漏检、误判。
现有代码核心问题
- 直接对全图Canny边缘做霍夫圆检测,靶面印刷环纹、光照不均产生的杂边会产生大量无效投票,尺寸小、边缘不规整的弹孔很容易被杂讯覆盖
- 弹孔本质是穿透/灼烧形成的暗斑,不是轮廓清晰的亮边圆环,霍夫圆基于边缘梯度投票的机制天然适配性差
- 弹孔检测半径硬卡7-10像素太死,不同拍摄距离、不同口径的弹孔尺寸稍有波动就会直接漏检
- 代码存在逻辑bug:调用
countHitScore前没判断hits是否为空,没检出弹孔时直接调用.tolist()会直接崩溃
可直接落地的改进方案(传统CV实现,无需训练模型,正视角固定机位场景下准确率足够)
1. 预处理加光照归一化
原代码只用了双边滤波去噪,解决不了光照不均导致的局部弹孔对比度低问题,灰度化后加一步自适应直方图均衡拉平局部亮度:
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) # 新增光照归一化 clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) gray = clahe.apply(gray) bilateral = cv.bilateralFilter(gray, 7, 15, 10)
2. 用暗阈值分割代替全图提边缘
弹孔普遍比周围靶纸颜色深,用自适应阈值直接抠出暗区域作为弹孔候选,比全图提边缘的干扰少90%:
# 提取比周围区域暗的连通块 thresh = cv.adaptiveThreshold( bilateral, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 15, 3 ) # 形态学开运算去掉印刷纹理产生的细碎噪点 kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3,3)) thresh = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=1)
3. 用轮廓特征筛选代替霍夫圆检测弹孔
对阈值分割出的连通域做轮廓检测,按弹孔的几何特征过滤无效块,稳定性远高于霍夫圆:
- 面积在弹孔对应区间(半径5-15像素对应面积约78-706像素,可根据实际拍摄分辨率调整)
- 圆度(
4*π*面积/(周长²))大于0.6,排除不规则印刷杂点、划痕 - 外接矩形宽高比在0.7-1.3之间,排除长条状干扰
对应实现代码替换原有的弹孔霍夫圆检测部分:
contours, _ = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) hits = [] for cnt in contours: area = cv.contourArea(cnt) # 过滤面积不符合的块 if area < 70 or area > 800: continue perimeter = cv.arcLength(cnt, True) if perimeter == 0: continue circularity = 4 * math.pi * area / (perimeter ** 2) x,y,w,h = cv.boundingRect(cnt) aspect_ratio = w / h # 按圆度、宽高比筛选 if circularity > 0.6 and 0.7 < aspect_ratio < 1.3: # 以轮廓质心作为弹孔中心,等面积圆半径作为弹孔半径 M = cv.moments(cnt) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) r = int(math.sqrt(area / math.pi)) hits.append([[cx, cy, r]]) # 转成和原霍夫圆输出一致的数组格式,兼容后续计分逻辑 hits = np.array(hits) if len(hits) >0 else None
4. 修复原有计分逻辑的空指针bug
score = 0 if hits is not None: score = countHitScore(hits.tolist(), delta_r, biggest_circle_center) print(f'The score is: {score}')
方案适配说明
- 上述方案对弹孔形状的容忍度远高于霍夫圆,只要弹孔和周围靶纸存在明显亮度差就能检出,基本不会把靶环圆弧误判为弹孔
- 如果后续需要应对斜视角拍摄、弹孔重叠、复杂光照场景,可以标注几百张样本训个YOLO系列的小目标检测模型,准确率能到99%以上,正视角固定机位场景下传统方案已经足够用。



从附的检测结果看,现有方案存在大量漏检、误检,替换上述轮廓检测逻辑后问题基本能解决。
内容的提问来源于stack exchange,提问作者Marian
相关产品推荐
相关产品推荐

