当前位置:   article > 正文

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

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


前言

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

一、代码展示

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

  1. import cv2
  2. import numpy as np
  3. def color_detection(frame):
  4. # 定义颜色范围(在HSV颜色空间中)
  5. lower_red = np.array([0, 100, 100])
  6. upper_red = np.array([10, 255, 255])
  7. lower_blue = np.array([110, 100, 100])
  8. upper_blue = np.array([130, 255, 255])
  9. lower_green = np.array([50, 100, 100])
  10. upper_green = np.array([70, 255, 255])
  11. # 将帧转换为HSV颜色空间
  12. hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  13. # 根据颜色范围创建掩膜
  14. red_mask = cv2.inRange(hsv_frame, lower_red, upper_red)
  15. blue_mask = cv2.inRange(hsv_frame, lower_blue, upper_blue)
  16. green_mask = cv2.inRange(hsv_frame, lower_green, upper_green)
  17. # 对掩膜进行形态学操作,以去除噪声
  18. kernel = np.ones((5, 5), np.uint8)
  19. red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
  20. blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel)
  21. green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel)
  22. # 在原始帧中找到颜色区域并绘制方框
  23. contours, _ = cv2.findContours(red_mask + blue_mask + green_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  24. for contour in contours:
  25. x, y, w, h = cv2.boundingRect(contour)
  26. color = ""
  27. if cv2.contourArea(contour) > 500: # 设置最小区域面积以排除噪声
  28. if np.any(red_mask[y:y+h, x:x+w]):
  29. color = "红色"
  30. cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
  31. elif np.any(blue_mask[y:y+h, x:x+w]):
  32. color = "蓝色"
  33. cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
  34. elif np.any(green_mask[y:y+h, x:x+w]):
  35. color = "绿色"
  36. cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
  37. cv2.putText(frame, color, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
  38. return frame
  39. # 打开摄像头
  40. cap = cv2.VideoCapture(0)
  41. while True:
  42. # 读取摄像头帧
  43. ret, frame = cap.read()
  44. # 进行颜色识别
  45. result = color_detection(frame)
  46. # 显示结果帧
  47. cv2.imshow("Color Detection", result)
  48. # 按下 'q' 键退出循环
  49. if cv2.waitKey(1) & 0xFF == ord('q'):
  50. break
  51. # 释放摄像头和关闭窗口
  52. cap.release()
  53. 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,以确保我们只识别饱和度和明度较高的红色。代码如下:

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

(三)创建掩膜

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

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

cv2.inRange(src, lowerb, upperb)

其中三个参数分别为:

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

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

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

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

  1. red_mask = cv2.inRange(hsv_frame, lower_red, upper_red)
  2. # lower_red = np.array([0, 100, 100])
  3. # upper_red = np.array([10, 255, 255])

三、完整代码分析

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

  1. import cv2
  2. import numpy as np

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

def color_detection(frame):

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

  1. lower_red = np.array([0, 100, 100])
  2. upper_red = np.array([10, 255, 255])
  3. lower_blue = np.array([110, 100, 100])
  4. upper_blue = np.array([130, 255, 255])
  5. lower_green = np.array([50, 100, 100])
  6. upper_green = np.array([70, 255, 255])

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

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

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

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

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

  1.     kernel = np.ones((5, 5), np.uint8)
  2.     red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
  3.     blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel)
  4.     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的图像基础操作

  1.    if np.any(red_mask[y:y+h, x:x+w]):
  2.        color = "红色"
  3.       cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
  4.    elif np.any(blue_mask[y:y+h, x:x+w]):
  5.        color = "蓝色"
  6.        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
  7.    elif np.any(green_mask[y:y+h, x:x+w]):
  8.       color = "绿色"
  9.       cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
  10.    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)进入主循环

  1. while True:
  2.     # 读取摄像头帧
  3.     ret, frame = cap.read()
  4.     # 进行颜色识别
  5.     result = color_detection(frame)
  6.     # 显示结果帧
  7.     cv2.imshow("Color Detection", result)
  8.     # 按下 'q' 键退出循环
  9.     if cv2.waitKey(1) & 0xFF == ord('q'):
  10.         break
  11. # 释放摄像头和关闭窗口
  12. cap.release()
  13. cv2.destroyAllWindows()

四、总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/odstu/article/detail/62206
推荐阅读
相关标签
  

闽ICP备14008679号