You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非正视角下飞镖盘实时检测的OpenCV Python技术问询

非正视角飞镖盘的OpenCV实时检测方案(无机器学习)

针对非正视角下飞镖盘检测的问题,我们可以利用飞镖盘的椭圆形态特征和环形纹理优化检测逻辑,替代仅能识别正圆的cv2.HoughCircles,同时解决轮廓误识别的问题。以下是具体实现方案:

关键优化点

  • 替换固定阈值为自适应阈值,适配不同光照环境下的打印飞镖盘
  • 结合Canny边缘检测+形态学操作,强化飞镖盘的环形纹理特征
  • 对候选轮廓进行椭圆拟合,筛选符合飞镖盘形态的椭圆(非正视角下呈现椭圆)
  • 加入轮廓的纵横比、面积占比等约束,过滤背景干扰

完整代码实现

import cv2
import numpy as np

def detect_dartboard(frame):
    # 1. 预处理:灰度化+高斯模糊
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (7, 7), 1.5)

    # 2. 自适应阈值分割,适配不同光照
    thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                  cv2.THRESH_BINARY_INV, 11, 2)

    # 3. 形态学操作:闭运算填充小间隙,开运算去除噪点
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

    # 4. Canny边缘检测,提取环形纹理边缘
    edges = cv2.Canny(thresh, 50, 150)

    # 5. 查找轮廓,只保留最外层轮廓
    contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    dartboard_contour = None
    for contour in contours:
        area = cv2.contourArea(contour)
        # 过滤过小/过大的轮廓(根据摄像头分辨率调整阈值)
        if area < 8000 or area > frame.shape[0]*frame.shape[1]*0.5:
            continue
        
        # 计算轮廓周长,用于多边形近似
        perimeter = cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, 0.02*perimeter, True)
        
        # 尝试拟合椭圆(至少需要5个点)
        if len(approx) >= 5:
            ellipse = cv2.fitEllipse(contour)
            (x, y), (MA, ma), angle = ellipse
            # 过滤极端纵横比的椭圆(飞镖盘非正视角下不会太扁或太窄)
            aspect_ratio = max(MA, ma)/min(MA, ma)
            if 0.5 < aspect_ratio < 2.0:
                # 验证轮廓面积与椭圆面积的匹配度(飞镖盘轮廓接近椭圆)
                ellipse_area = np.pi * (MA/2) * (ma/2)
                area_ratio = area / ellipse_area
                if 0.7 < area_ratio < 1.3:
                    dartboard_contour = contour
                    # 绘制检测结果
                    cv2.ellipse(frame, ellipse, (0, 255, 0), 2)
                    cv2.circle(frame, (int(x), int(y)), 5, (0, 0, 255), -1)
                    break

    return frame

# 摄像头实时检测
cap = cv2.VideoCapture(0)
# 可选:设置摄像头分辨率,提升检测精度
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    processed_frame = detect_dartboard(frame)
    cv2.imshow('Dartboard Detection', processed_frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

测试注意事项

  1. 打印的飞镖盘尽量平整,避免褶皱导致纹理变形
  2. 调整摄像头角度,保证飞镖盘在画面中占比适中(不小于1/10画面)
  3. 避免强光直射,防止反光导致阈值分割失效

内容的提问来源于stack exchange,提问作者Indy2013

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:57:38