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

如何用Python的OpenCV为图像中的红色区域绘制边界?

如何在OpenCV中为检测到的红色区域绘制边界?

我正在使用Python的OpenCV进行颜色检测,希望为图像中的红色区域绘制边界。以下是我的Python代码:

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
    _, frame = cap.read()
    frame=np.fliplr(frame)
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0,170,175])
    upper_red = np.array([20,255,255])
    mask = cv2.inRange(hsv, lower_red, upper_red)
    res = cv2.bitwise_and(frame,frame, mask= mask)
    kernel = np.ones((15,15),np.float32)/225
    smoothed = cv2.filter2D(res,-1,kernel)
    cv2.imshow('Original',frame)
    cv2.imshow('Averaging',smoothed)
    _, puck = cv2.threshold(smoothed, 30, 255, cv2.THRESH_BINARY)
    cv2.imshow('Puck',puck)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()
cap.release()

目前我已成功识别出红色,但不清楚如何检测红色区域的位置并绘制边界,特此求助。


解决方案

要给检测到的红色区域绘制边界,核心是通过轮廓检测定位红色区域的轮廓,再基于轮廓绘制边界框或直接绘制轮廓。下面是具体步骤和修改后的代码:

关键步骤说明:

  • 先将二值化后的puck图像转为单通道灰度图,因为cv2.findContours需要单通道输入才能正确工作
  • 提取轮廓后,过滤掉面积过小的轮廓,避免噪声被误识别为目标区域
  • 遍历有效轮廓,用矩形框或直接绘制轮廓的方式标记红色区域

修改后的完整代码:

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
    _, frame = cap.read()
    frame = np.fliplr(frame)
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
    # 保留你原来的红色HSV检测范围
    lower_red = np.array([0,170,175])
    upper_red = np.array([20,255,255])
    mask = cv2.inRange(hsv, lower_red, upper_red)
    
    res = cv2.bitwise_and(frame, frame, mask=mask)
    kernel = np.ones((15,15),np.float32)/225
    smoothed = cv2.filter2D(res,-1,kernel)
    _, puck = cv2.threshold(smoothed, 30, 255, cv2.THRESH_BINARY)
    
    # 将3通道二值图转为单通道灰度图,满足轮廓检测的输入要求
    gray_puck = cv2.cvtColor(puck, cv2.COLOR_BGR2GRAY)
    
    # 查找轮廓:只检测最外层轮廓,压缩轮廓点减少计算量
    contours, _ = cv2.findContours(gray_puck, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # 遍历所有轮廓,绘制边界框
    for cnt in contours:
        # 过滤小面积轮廓,阈值可根据你的场景调整
        if cv2.contourArea(cnt) > 500:
            # 获取轮廓的外接矩形坐标
            x, y, w, h = cv2.boundingRect(cnt)
            # 在原图像上绘制绿色边界框(BGR格式,线宽2)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
            # 若想直接绘制轮廓,可替换为下面这行:
            # cv2.drawContours(frame, [cnt], -1, (0,255,0), 2)
    
    # 显示带有边界框的原图像
    cv2.imshow('Original with Bounding Box', frame)
    cv2.imshow('Averaging', smoothed)
    cv2.imshow('Puck', puck)
    
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()
cap.release()

代码细节解释:

  1. 单通道转换:puck是3通道的二值图像,必须转为灰度图才能让轮廓检测函数正常解析
  2. 轮廓参数选择:cv2.RETR_EXTERNAL只提取最外层轮廓,避免嵌套轮廓干扰;cv2.CHAIN_APPROX_SIMPLE会压缩轮廓上的冗余点,提升运行效率
  3. 面积过滤:通过cv2.contourArea计算轮廓面积,忽略小于500的区域,你可以根据实际拍摄场景调整这个阈值(比如目标更大就调大,更小就调小)
  4. 边界绘制:cv2.boundingRect快速获取轮廓的外接矩形,cv2.rectangle在原图像上绘制醒目的绿色框,方便观察检测结果

运行这段代码后,你就能在原画面中看到红色区域被绿色边界框标记出来了,多红色区域也能同时检测并绘制各自的边界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:15:46