Bootstrap

【OpenCV】颜色空间(HSV)

介绍 

颜色空间(Color Space)是指一种数学模型,用于表示和解释色彩信息。HSV(Hue, Saturation, Value)颜色空间是其中一种,它以人类感知颜色的方式为基础,将颜色分为三个独立的分量:色调(Hue)、饱和度(Saturation)和亮度(Value)。与RGB颜色空间不同的是,HSV更接近于人类对颜色的理解,因此在图像处理中经常被用来进行颜色的选择和分割。

HSV 颜色空间简介

  • Hue (色调):表示颜色的种类,例如红色、绿色或蓝色。它是基于色相环定义的,范围通常为0到360度。0度对应红色,120度对应绿色,240度对应蓝色。其他颜色则分布在这些主要颜色之间。

  • Saturation (饱和度):表示颜色的纯度或强度,即颜色中包含多少白色成分。饱和度值越高,颜色越鲜艳;反之,饱和度低则颜色显得苍白。其取值范围一般是从0到1或者0%到100%,其中0意味着灰色调,而最大值代表完全饱和的颜色。

  • Value (亮度/明度):反映了颜色的明亮程度,也就是颜色中包含了多少黑色成分。这个参数决定了一个颜色看起来有多亮或多暗。它的取值也通常是在0到1或0%到100%之间,0表示黑色,最大值表示最亮的白色。

HSV 与 RGB 的区别

  • 直观性:HSV比RGB更加直观地反映了人们对颜色的感受。比如,在调整图片中的某个特定颜色时,使用HSV可以更容易地定位并修改该颜色。

  • 分离属性:在HSV中,颜色的三种属性是分开的,这使得某些类型的图像处理任务变得简单,如颜色检测、跟踪等。

  • 光照变化鲁棒性:由于V通道单独表示亮度信息,所以HSV对于光照条件的变化具有更好的鲁棒性,尤其适合于需要忽略光照影响的应用场景。

改变颜色空间

在 OpenCV 中有超过 150 种颜色空间转换的方法。但我们仅需要研究两个最常使用的方法,他们是 BGR 到 Gray,BGR 到 HSV。

我们使用 cv.cvtColor(input_image, flag)函数进行颜色转换,其中 flag 决定了转换的类型。

对于 BGR 到 Gray 转换我们令 flag 为 **cv.COLOR_BGR2GRAY**。 同样,对于 BGR 到 HSV, 我们令 flag 为 **cv.COLOR_BGR2HSV**。如想得到其他 flag 值,只需要在 Python 终端中输入如下命令:

>>> import cv2 as cv
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
>>> print( flags )

注意 对于 HSV, 色调(Hue)范围为 [0,179], 饱和度(Saturation)范围为 [0,255] ,明亮度(Value)为 [0,255]. 不同的软件使用不同的比例. 所以如果你想用 OpenCV 的值与别的软件的值作对比,你需要归一化这些范围。

目标追踪

现在我们知道了如何将 BGR 图片转化为 HSV 图片,我们可以使用它去提取彩色对象。HSV 比 BGR 在颜色空间上更容易表示颜色。在我们的应用中,我们会尝试提取一个蓝色的彩色对象,方法为:

  • 提取每一视频帧。
  • 将 BGR 转化为 HSV 颜色空间。
  • 我们用蓝色像素的范围对该 HSV 图片做阈值。
  • 现在提取出了蓝色对象,我们可以随意处理图片了 。

下面是代码:

import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
    # Take each frame
    _, frame = cap.read()
    # Convert BGR to HSV
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    # Threshold the HSV image to get only blue colors
    mask = cv.inRange(hsv, lower_blue, upper_blue)
    # Bitwise-AND mask and original image
    res = cv.bitwise_and(frame,frame, mask= mask)
    cv.imshow('frame',frame)
    cv.imshow('mask',mask)
    cv.imshow('res',res)
    k = cv.waitKey(5) & 0xFF
    if k == 27:
        break
cv.destroyAllWindows()

接下来的图片显示了追踪蓝色对象:

6e5eba107d0a803ff3746c60e4ae4f9f.jpeg

注意 在图片中有一些噪声,在之后的章节中我们会学习如何消除。 这是目标追踪最简单的例子。当你学会了轮廓函数,你就可以做的更多,例如找到对象的质心并且使用它来追踪对象,只需在相机前面移动你的手,手指或者掌心的轨迹就可以绘制图形,还有许多其他有趣的东西。

如何找到 HSV 值去追踪?

这个问题非常简单,你可以使用相同的函数:**cv.cvtColor()**。 不需要输入图片,你只需要输入你需要的 BGR 值即可. 例如, 为了找到绿色的 HSV 值, 可以在 Python 终端中输入以下代码:

>>> green = np.uint8([[[0,255,0 ]]])
>>> hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV)
>>> print( hsv_green )
[[[ 60 255 255]]]

现在你可以取 [H-10, 100,100] 和 [H+10, 255, 255] 分别作为上界和下界. 除此之外,你可以使用任何图像编辑工具(如 GIMP)或任何在线转换器来查找这些值,但不要忘记调整 HSV 范围。

hsv对照表:

29056ee3f80846b289eeee2d675d5a99.png

apachecn.github.io/opencv-doc-zh/#/

;