You need to enable JavaScript to run this app. 如何使用OpenCV Python实现精准颜色检测 支持多类别颜色识别
优惠活动
大模型
产品
解决方案
定价
更多

如何使用OpenCV Python实现精准颜色检测 支持多类别颜色识别

准确率优化方案
  • 先修复基础逻辑bug:原判断语句存在分支重叠问题,当蓝色为最大值时,第一个if输出Blue后,第二个if判断不满足会触发else输出Red,导致同时输出两个结果,需要把第二个if改为elif,形成互斥判断分支。
  • 更换颜色空间:RGB空间对光照变化非常敏感,建议转换为HSV(色相、饱和度、明度)空间做颜色判断,排除光照亮度对颜色识别的干扰。
  • 增加帧平滑处理:取最近3~5帧的颜色均值做判断,避免单帧画面偶然波动导致的结果跳变。
  • 限制检测区域:默认只取画面中心70%的区域计算主色,排除边缘无关背景的干扰,也可支持用户手动框选检测区域。
  • 增加饱和度过滤:提前过滤掉饱和度低于阈值的像素(比如灰度、白色、黑色区域),避免无彩色区域拉偏均值计算。
多颜色拓展方案

完全可以支持更多颜色识别,核心是在HSV空间为每种目标颜色配置色相(H)、饱和度(S)的阈值范围,常见颜色的参考阈值(OpenCV中H值范围是0180,S、V是0255):

  • 红色:H 0~10 或 170~180,S 120~255,V 70~255
  • 橙色:H 11~25,S 120~255,V 70~255
  • 黄色:H 26~35,S 120~255,V 70~255
  • 绿色:H 36~77,S 120~255,V 70~255
  • 蓝色:H 78~124,S 120~255,V 70~255
  • 紫色:H 125~155,S 120~255,V 70~255
  • 棕色:H 156~170,S 80~200,V 50~180

计算逻辑改为统计每个颜色阈值范围内的像素占比,占比最高的即为当前帧主色。

优化后完整代码
import cv2
import numpy as np
from collections import deque

# 初始化摄像头
vid = cv2.VideoCapture(0)
# 缓存最近5帧的像素统计结果做平滑
frame_buffer = deque(maxlen=5)

# 定义HSV颜色阈值,格式:[颜色名, [H下限, S下限, V下限], [H上限, S上限, V上限]]
color_ranges = [
    ["红色", [0, 120, 70], [10, 255, 255]],
    ["红色", [170, 120, 70], [180, 255, 255]],
    ["橙色", [11, 120, 70], [25, 255, 255]],
    ["黄色", [26, 120, 70], [35, 255, 255]],
    ["绿色", [36, 120, 70], [77, 255, 255]],
    ["蓝色", [78, 120, 70], [124, 255, 255]],
    ["紫色", [125, 120, 70], [155, 255, 255]],
    ["棕色", [156, 80, 50], [170, 200, 180]]
]

while True:
    ret, frame = vid.read()
    if not ret:
        break
    
    # 取画面中心70%区域作为检测ROI
    h, w = frame.shape[:2]
    roi_x1, roi_x2 = int(w*0.15), int(w*0.85)
    roi_y1, roi_y2 = int(h*0.15), int(h*0.85)
    roi = frame[roi_y1:roi_y2, roi_x1:roi_x2]
    # 绘制ROI框
    cv2.rectangle(frame, (roi_x1, roi_y1), (roi_x2, roi_y2), (0,255,0), 2)
    
    # 转换为HSV空间
    hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
    
    # 统计每个颜色的像素数
    color_count = {}
    for color_name, lower, upper in color_ranges:
        mask = cv2.inRange(hsv_roi, np.array(lower), np.array(upper))
        count = cv2.countNonZero(mask)
        color_count[color_name] = color_count.get(color_name, 0) + count
    
    # 把当前帧统计结果加入缓存
    frame_buffer.append(color_count)
    # 计算缓存中所有帧的统计均值
    avg_count = {}
    for cnt in frame_buffer:
        for k, v in cnt.items():
            avg_count[k] = avg_count.get(k, 0) + v
    avg_count = {k: v/len(frame_buffer) for k, v in avg_count.items()}
    
    # 找出占比最高的颜色,若所有颜色像素占比低于10%则判定为无明显主色
    max_color = max(avg_count.items(), key=lambda x: x[1])
    total_pixel = roi.shape[0] * roi.shape[1]
    if max_color[1] / total_pixel < 0.1:
        result = "无明显主色"
    else:
        result = f"主色:{max_color[0]}"
    
    # 显示结果
    cv2.putText(frame, result, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
    cv2.imshow("主色检测", frame)
    
    # 按q键退出
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break

# 释放资源
vid.release()
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 06:36:10