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

如何在视频中实现霍夫圆变换?附HSV颜色检测代码解析

基于OpenCV的黄色物体检测+霍夫圆变换代码解析与完善

嘿,我来帮你把这段OpenCV代码补全并优化到位——咱们先拆解原代码的逻辑,再一步步补上霍夫圆变换的部分,顺便把黄色检测的阈值调得更靠谱些:

1. 原代码基础逻辑梳理

先给你理清楚现有代码的作用:

  • cv2.VideoCapture(0):调用电脑默认的摄像头设备
  • 循环读取每一帧画面,把BGR格式转成HSV是因为HSV颜色空间对亮度变化的鲁棒性更强,比原生BGR更适合做颜色分割
  • 原代码里的黄色HSV阈值其实有问题:lower_yellow的S(饱和度)和V(亮度)设为0,会把很多非黄色的暗区域也误判进来,咱们后面会优化这个部分

2. 优化黄色检测的HSV阈值

实际场景中,黄色的HSV范围需要给饱和度和亮度设合理下限,避免误检。这里给你一个通用的靠谱阈值,你可以根据实际光照微调:

# 优化后的黄色HSV阈值,适配大多数场景
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])

如果你的场景光照特殊,比如偏暗或偏亮,可以用OpenCV的取色工具(比如写个鼠标回调函数)来获取目标黄色的准确HSV值

3. 位与操作提取黄色区域

原代码缺少位与操作,这一步能帮你从原画面中单独提取出黄色物体的区域:

# 位与操作:只保留mask中白色区域对应的原帧像素
res = cv2.bitwise_and(frame, frame, mask=mask)

简单说就是:mask里白色(255)的部分会保留原画面的颜色,黑色(0)的部分会被置黑,这样你就能单独看到黄色物体了。

4. 霍夫圆变换的实现

霍夫圆变换对噪声很敏感,所以需要先做预处理,再调用检测函数,最后把检测到的圆画到原画面上:

预处理步骤

先把提取出的黄色区域转灰度+高斯模糊,减少噪声干扰:

# 转灰度图
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪
blur = cv2.GaussianBlur(gray, (5, 5), 0)

调用霍夫圆变换

circles = cv2.HoughCircles(
    blur,
    cv2.HOUGH_GRADIENT,  # 目前唯一实现的霍夫圆变换方法
    dp=1,  # 累加器分辨率与图像分辨率的比值,通常设1
    minDist=20,  # 检测到的圆之间的最小距离,避免重复检测
    param1=50,  # Canny边缘检测的高阈值,低阈值是它的一半
    param2=30,  # 累加器阈值:值越小检测到的圆越多(易误检),值越大越严格
    minRadius=5,  # 检测圆的最小半径,过滤过小的噪声点
    maxRadius=100  # 检测圆的最大半径,过滤过大的干扰
)

绘制检测到的圆

要先判断是否检测到圆(没检测到会返回None),然后把圆和圆心画到原画面上:

if circles is not None:
    # 把浮点型的圆参数转成整数
    circles = np.uint16(np.around(circles))
    for circle in circles[0, :]:
        # 绘制圆的外轮廓(绿色,线宽2)
        cv2.circle(frame, (circle[0], circle[1]), circle[2], (0, 255, 0), 2)
        # 绘制圆心(红色,半径3)
        cv2.circle(frame, (circle[0], circle[1]), 2, (0, 0, 255), 3)

5. 完整可运行代码

把所有部分整合起来,加上窗口显示和退出逻辑:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

# 优化后的黄色HSV阈值
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])

while True:
    # 获取每一帧,ret表示是否成功读取
    ret, frame = cap.read()
    if not ret:
        print("无法读取摄像头帧")
        break
    
    # BGR转HSV颜色空间
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
    # 创建黄色掩码
    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
    
    # 位与操作提取黄色区域
    res = cv2.bitwise_and(frame, frame, mask=mask)
    
    # 预处理:转灰度+高斯模糊,为霍夫圆变换做准备
    gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # 霍夫圆变换检测圆形
    circles = cv2.HoughCircles(
        blur,
        cv2.HOUGH_GRADIENT,
        dp=1,
        minDist=20,
        param1=50,
        param2=30,
        minRadius=5,
        maxRadius=100
    )
    
    # 如果检测到圆,在原帧上绘制
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for circle in circles[0, :]:
            # 绘制圆轮廓
            cv2.circle(frame, (circle[0], circle[1]), circle[2], (0, 255, 0), 2)
            # 绘制圆心
            cv2.circle(frame, (circle[0], circle[1]), 2, (0, 0, 255), 3)
    
    # 显示各个窗口
    cv2.imshow('Original Frame', frame)
    cv2.imshow('Yellow Mask', mask)
    cv2.imshow('Yellow Region', res)
    
    # 按q键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头资源,关闭所有窗口
cap.release()
cv2.destroyAllWindows()

6. 实用调整技巧

  • 如果检测效果不好,可以微调霍夫圆的param2参数:值减小会检测更多圆(可能误检),值增大则更严格
  • 黄色阈值可以根据场景调整:比如光照偏暗时,V的下限可以调低到80左右
  • 若摄像头帧率低,可以缩小帧尺寸(比如frame = cv2.resize(frame, (640, 480)))来加快处理速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:51:18