OpenCV实战项目——多种颜色识别

文章目录

  • 前言
  • 一、代码展示
  • 二、战前准备
  • 二、完整代码分析
  • 总结


前言

        本专栏旨在学习记录OpenCV的各种基础知识和常用函数的用法,共八节基础内容已全部记录完毕。最后一篇文章将进入OpenCV的简单实战——各种颜色识别,在本篇文章中,我将详细记录使用OpenCV进行颜色识别的完整代码及代码分析,并上传OpenCV的所有基础内容及实战项目的源码。

一、代码展示

首先展示该实战项目的完整代码:

import cv2
import numpy as np

def color_detection(frame):
    # 定义颜色范围(在HSV颜色空间中)
    lower_red = np.array([0, 100, 100])
    upper_red = np.array([10, 255, 255])
    lower_blue = np.array([110, 100, 100])
    upper_blue = np.array([130, 255, 255])
    lower_green = np.array([50, 100, 100])
    upper_green = np.array([70, 255, 255])

    # 将帧转换为HSV颜色空间
    hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # 根据颜色范围创建掩膜
    red_mask = cv2.inRange(hsv_frame, lower_red, upper_red)
    blue_mask = cv2.inRange(hsv_frame, lower_blue, upper_blue)
    green_mask = cv2.inRange(hsv_frame, lower_green, upper_green)

    # 对掩膜进行形态学操作,以去除噪声
    kernel = np.ones((5, 5), np.uint8)
    red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
    blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel)
    green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel)

    # 在原始帧中找到颜色区域并绘制方框
    contours, _ = cv2.findContours(red_mask + blue_mask + green_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        x, y, w, h = cv2.boundingRect(contour)
        color = ""
        if cv2.contourArea(contour) > 500:  # 设置最小区域面积以排除噪声
            if np.any(red_mask[y:y+h, x:x+w]):
                color = "红色"
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
            elif np.any(blue_mask[y:y+h, x:x+w]):
                color = "蓝色"
                cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
            elif np.any(green_mask[y:y+h, x:x+w]):
                color = "绿色"
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
            cv2.putText(frame, color, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

    return frame

# 打开摄像头
cap = cv2.VideoCapture(0)

while True:
    # 读取摄像头帧
    ret, frame = cap.read()

    # 进行颜色识别
    result = color_detection(frame)

    # 显示结果帧
    cv2.imshow("Color Detection", result)

    # 按下 'q' 键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头和关闭窗口
cap.release()
cv2.destroyAllWindows()

接下来,我们将对这段代码进行详细分析

二、战前准备

        想要完成颜色识别的实战项目,除了掌握本专栏所记录的所有基础内容之外,还得熟悉以下知识:

(一)创建数组

        创建数组并不是opencv库中的内容,而是numpy库中的内容。创建数组在进行颜色检测等方面十分重要,通常可以通过创建一个三元数组来确定颜色的范围,例如RGB、HSV等。

        使用numpy库创建数组的函数如下:

np.array([a, b, c])  # 创建一个(a, b, c)的数组

其中a、b、c为常数,在本实战项目中可以设置为颜色的HSV颜色空间数值

(二)HSV颜色空间

        HSV颜色空间由三个分量组成:色相(Hue)、饱和度(Saturation)和明度(Value)。通过调整这些分量的值,我们可以选择特定的颜色范围,HSV具体含义如下:

  1. 色相(Hue):色相值表示颜色在颜色轮上的位置。不同的颜色在色相上有不同的取值范围。例如,红色的色相值约为0-10或160-180,蓝色的色相值约为110-130,绿色的色相值约为50-70。根据所需识别的颜色,选择相应的色相范围。

  2. 饱和度(Saturation):饱和度值表示颜色的纯度或鲜艳程度。较高的饱和度值表示颜色更加鲜艳,而较低的饱和度值表示颜色较为灰暗。根据实际场景中颜色的饱和度,选择适当的饱和度范围。

  3. 明度(Value):明度值表示颜色的亮度或明暗程度。较高的明度值表示颜色较亮,而较低的明度值表示颜色较暗。根据实际场景中颜色的明度,选择适当的明度范围。

        这些值是根据经验和实验进行调整的,以获得最佳的颜色识别效果。我们可以根据具体的应用场景和需求进行调整,以适应不同的颜色识别任务。在实际使用中,我们可能需要进行多次尝试和调整,以找到最适合需求的颜色范围。

        对于每种颜色(红色、蓝色和绿色),我们使用np.array()函数创建了一个包含三个元素的NumPy数组。这些元素分别代表HSV颜色空间中的色相、饱和度和明度的下限和上限。

        例如,对于红色,我们将色相的下限设置为0,上限设置为10。这意味着我们将识别色相值在0到10之间的红色。饱和度和明度的下限设置为100,上限设置为255,以确保我们只识别饱和度和明度较高的红色。代码如下:

lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])

(三)创建掩膜

        在进行颜色识别时,我们通过创建掩膜的方法来将图像进行二值化,即非黑即白,通过创建颜色掩膜,可以将图像中的特定颜色范围提取出来,让摄像头对目标颜色更为敏感

        我们使用cv2.inRange()函数来创建颜色掩膜。它会根据指定的颜色范围,将图像中在范围内的像素设置为255(白色),而其他像素则设置为0(黑色)

cv2.inRange(src, lowerb, upperb)

其中三个参数分别为:

(1)“src”, 输入图像,可以是灰度图像或彩色图像

(2)“lowerb”, 下限阈值,用于指定要提取的像素的最小值

(3)“upperb”, 上限阈值,用于指定要提取的像素的最大值

例如,创建红色掩膜的代码如下:

red_mask = cv2.inRange(hsv_frame, lower_red, upper_red)

# lower_red = np.array([0, 100, 100])
# upper_red = np.array([10, 255, 255])

三、完整代码分析

(1)我们首先导入该项目所要用到的库

import cv2
import numpy as np

(2)然后创建一个子函数用于进行颜色识别,其中,参数frame代表的是摄像头获取的帧,即待处理的图像

def color_detection(frame):

(3)在颜色识别函数中,我们先用np.array()函数创建红色、绿色、蓝色在HSV颜色空间中的阈值范围

    lower_red = np.array([0, 100, 100])
    upper_red = np.array([10, 255, 255])
    lower_blue = np.array([110, 100, 100])
    upper_blue = np.array([130, 255, 255])
    lower_green = np.array([50, 100, 100])
    upper_green = np.array([70, 255, 255])

(4)使用cv2.cvtColor()函数将帧转换为HSV颜色空间

    hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

(5)根据颜色范围使用cv2.inRange()函数创建掩膜

    red_mask = cv2.inRange(hsv_frame, lower_red, upper_red)
    blue_mask = cv2.inRange(hsv_frame, lower_blue, upper_blue)
    green_mask = cv2.inRange(hsv_frame, lower_green, upper_green)

(6)对掩膜进行形态学操作,以去除噪声
 

    kernel = np.ones((5, 5), np.uint8)
    red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
    blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel)
    green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel)

(7)将前面创建的红、绿、蓝三个掩膜进行相加,并将相加的结果作为输入图,寻找颜色的轮廓

    contours, _ = cv2.findContours(red_mask + blue_mask + green_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

(8)得到轮廓列表countours后进行遍历(循环),提取出轮廓列表中的所有轮廓值,并记录为countour

    for contour in contours:

(9)可以使用cv2.boundingRect()函数计算每一个轮廓(contour)的边界框,该函数将得到x、y、w、h四个返回值,其中:(x, y) 是矩形框左上角的坐标,w 是矩形框的宽度,h 是矩形框的高度。

        x, y, w, h = cv2.boundingRect(contour)

(10)用if语句设置最小区域面积以排除噪声,即当目标颜色区域太小时不显示

        if cv2.contourArea(contour) > 500:

(11)用if语句判断识别到的颜色处于哪个HSV颜色空间阈值内,并使用cv2.rectangle()函数绘制对应颜色的方框圈住目标颜色,再用cv2.putText()函数进行颜色注释。

        例如:red_mask[y:y+h, x:x+w]表示从红色掩膜中提取出与当前轮廓对应的区域(切片操作)。如果在该区域中存在非零值(即存在红色像素),则条件为真,表示当前轮廓属于红色区域。

        本段代码十分重要,是颜色识别的核心判断,请反复琢磨代码,确保自己十分清晰判断原理和绘制矩形方法。如果对该判断原理不够熟悉,可以自行复习一下python的if语句和opencv的图像基础操作

   if np.any(red_mask[y:y+h, x:x+w]):
       color = "红色"
       cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
   elif np.any(blue_mask[y:y+h, x:x+w]):
       color = "蓝色"
       cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
   elif np.any(green_mask[y:y+h, x:x+w]):
       color = "绿色"
       cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
   cv2.putText(frame, color, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

(12)返回帧

    return frame

(13)打开摄像头

cap = cv2.VideoCapture(0)

(14)进入主循环

while True:
    # 读取摄像头帧
    ret, frame = cap.read()

    # 进行颜色识别
    result = color_detection(frame)

    # 显示结果帧
    cv2.imshow("Color Detection", result)

    # 按下 'q' 键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头和关闭窗口
cap.release()
cv2.destroyAllWindows()

四、总结

该OpenCV实战项目全部分析完毕,本专栏到此也全部结束

你可能感兴趣的:(树莓派——OpenCV,opencv,人工智能,计算机视觉,嵌入式硬件,学习)