Python中使用OpenCV实现颜色检测主要基于HSV色彩空间,通过设定颜色范围并使用掩码技术来识别特定颜色。

1.核心实现原理
颜色检测通常采用HSV色彩空间而非RGB,因为HSV能更好地区分颜色和亮度信息。HSV中H(色调)表示颜色类型,S(饱和度)表示颜色纯度,V(明度)表示亮度。

2.主要步骤包括:

将图像从BGR转换到HSV色彩空间。
设定目标颜色的HSV阈值范围。
使用cv2.inRange()函数创建颜色掩码。
通过位运算提取检测到的颜色区域。

3.完整代码实现


import cv2
import numpy as np

class ColorDetector:
    def __init__(self):
        # 常见颜色的HSV阈值范围
        self.color_ranges = {
            'red': [
                {'lower': [0, 120, 70], 'upper': [10, 255, 255]},
                {'lower': [170, 120, 70], 'upper': [180, 255, 255]}
            ],
            'green': [
                {'lower': [35, 50, 50], 'upper': [85, 255, 255]}
            ],
            'blue': [
                {'lower': [100, 150, 0], 'upper': [140, 255, 255]}
            ],
            'yellow': [
                {'lower': [20, 100, 100], 'upper': [30, 255, 255]}
            ]
        }
    
    def detect_color(self, image_path, target_color):
        """
        检测图像中的特定颜色
        """
        # 读取图像
        img = cv2.imread(image_path)
        if img is None:
            print("无法读取图像文件")
            return None
        
        # 转换为HSV色彩空间
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        
        # 获取目标颜色的阈值范围
        if target_color not in self.color_ranges:
            print(f"不支持的颜色: {target_color}")
            return None
        
        mask = np.zeros(img.shape[:2], dtype=np.uint8)
        
        # 处理多个阈值范围(如红色有两个范围)
        for color_range in self.color_ranges[target_color]:
            lower = np.array(color_range['lower'])
            upper = np.array(color_range['upper'])
            
            # 创建颜色掩码
            color_mask = cv2.inRange(hsv, lower, upper)
            mask = cv2.bitwise_or(mask, color_mask)
        
        # 应用掩码提取颜色区域
        result = cv2.bitwise_and(img, img, mask=mask)
        
        return result, mask
    
    def find_color_contours(self, mask):
        """
        查找颜色区域的轮廓
        """
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        return contours
    
    def real_time_color_detection(self, target_color='red'):
        """
        实时颜色检测(摄像头)
        """
        cap = cv2.VideoCapture(0)
        
        while True:
            ret, frame = cap.read()
            if not ret:
                break
            
            # 转换为HSV
            hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
            
            # 创建颜色掩码
            mask = np.zeros(frame.shape[:2], dtype=np.uint8)
            for color_range in self.color_ranges[target_color]:
                lower = np.array(color_range['lower'])
                upper = np.array(color_range['upper'])
                color_mask = cv2.inRange(hsv, lower, upper)
                mask = cv2.bitwise_or(mask, color_mask)
            
            # 查找轮廓
            contours = self.find_color_contours(mask)
            
            # 绘制轮廓
            for contour in contours:
                if cv2.contourArea(contour) > 500:  # 过滤小面积噪声
                    x, y, w, h = cv2.boundingRect(contour)
                    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
                    cv2.putText(frame, target_color, (x, y-10), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
            
            # 显示结果
            cv2.imshow('Real-time Color Detection', frame)
            cv2.imshow('Color Mask', mask)
            
            # 按'q'退出
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        
        cap.release()
        cv2.destroyAllWindows()

def interactive_color_picker(image_path):
    """
    交互式颜色选择器,用于确定颜色的HSV阈值
    """
    img = cv2.imread(image_path)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    def mouse_callback(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            print(f"位置: ({x}, {y})")
            print(f"BGR: {img[y, x]}")
            print(f"HSV: {hsv[y, x]}")
            print("-" * 30)
    
    cv2.namedWindow('Color Picker')
    cv2.setMouseCallback('Color Picker', mouse_callback)
    
    while True:
        cv2.imshow('Color Picker', img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    cv2.destroyAllWindows()

def main():
    detector = ColorDetector()
    
    # 示例:检测红色
    image_path = 'test_image.jpg'  # 替换为实际图像路径
    
    # 交互式颜色选择(用于确定阈值)
    print("点击图像查看颜色值,按'q'退出颜色选择器")
    interactive_color_picker(image_path)
    
    # 颜色检测
    result, mask = detector.detect_color(image_path, 'red')
    
    if result is not None:
        cv2.imshow('Original', cv2.imread(image_path))
        cv2.imshow('Color Detection Result', result)
        cv2.imshow('Color Mask', mask)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    # 实时检测(可选)
    print("开始实时颜色检测,按'q'退出")
    detector.real_time_color_detection('red')

if __name__ == "__main__":
    main()
<code_end>

<code_start project_name=python_颜色检测 filename=requirements.txt title=项目依赖文件 entrypoint=false runnable=false project_final_file=true>
opencv-python>=4.5.0
numpy>=1.21.0
<code_end>

该颜色检测系统具有以下特点:

- **多颜色支持**:预设了红、绿、蓝、黄等常见颜色的HSV阈值范围
- **实时检测能力**:支持摄像头实时颜色识别和轮廓标记
- **交互式调试**:提供颜色选择器功能,方便确定特定颜色的HSV值
- **精确轮廓检测**:使用OpenCV的轮廓查找功能定位颜色区域
- **灵活的阈值配置**:支持多个HSV范围组合,适应不同光照条件下的颜色识别

实现的关键在于准确设置HSV阈值范围,不同光照条件下同一颜色的HSV值会有所变化,建议通过交互式颜色选择器进行精确校准。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐