CV — 色彩空间:RGB、HSV、HLS

CV — 色彩空间:RGB、HSV、HLS

一、 RGB

(一) RGB 颜色系统

  1. RGB 简介:

    • RGB是从颜色发光的原理来设计定的,通俗点说它的颜色混合方式就好像有红、绿、蓝三盏灯,当它们的光相互叠合的时候,色彩相混,而亮度却等于三者亮度之总和,越混合亮度越高,即加法混合。

    • 红、绿、蓝 三个颜色通道 每种色各分为 256 阶亮度(范围:0 ~ 255):
      在0时“灯”最弱——是关掉的,而在255时“灯”最亮。当三色灰度数值相同时,产生不同灰度值的灰色调,即三色灰度都为 0 时(0,0,0),是最暗的黑色调;三色灰度都为255时(255,255,255),是最亮的白色调。

  2. RGB 的局限性:

    • 自然环境下获取的图像容易受 自然光照、遮挡和阴影 等情况的影响,即对 亮度 比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。
    • 人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。
    • 总结:RGB 颜色空间适合于显示系统,却并不适合于图像处理。

二、HSV

(一) HSV颜色模型

HSV(Hue, Saturation, Value)是根据颜色的直观特性由 A. R. Smith 在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。

这个模型中颜色的参数分别是:色调(Hue),饱和度(Saturation),明度(Saturation)

用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。

img
  1. 色调H:

    用角度度量,取值范围为 0°~360°,表示色彩信息,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。
    它们的补色是:黄色为60°,青色为180°,紫色为300°;

    • 在 RGB 中 颜色由三个值共同决定,比如黄色为即 (255,0,255);在HSV中,黄色只由一个值决定,Hue = 60即可。
  2. 饱和度S:

    饱和度S:表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色;饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。通常取值范围为:0%~100%,值越大,颜色越饱和。

    一种颜色,可以看成是 某种光谱色 与 白色 混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。

  3. 明度V:

    明度:表示颜色明亮的程度。对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)~ 100%(白)。明度为0表示纯黑色(此时颜色最暗)。

  • HSV 在线取色板:

  • 补充理解:

    • 描述一件物品的颜色的时候通常会说 “它是什么颜色(H)?”,“颜色深不深(S)?”,"亮不亮(V)?"
      恰好可以对应 HSV 中的:色调、饱和度、明度
  • 区别点:

    RGB颜色空间更加面向于工业,而 HSV 更加面向于用户,大多数做图像识别这一块的都会运用HSV颜色空间,因为HSV颜色空间表达起来更加直观。

    基于RGB 的局限性,在 图像处理 中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。

    在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

  • 注意:在 OpenCV 中 HSV 三个分量的范围为:

    • H = [0,179];S = [0,255];V = [0,255]

    • 测试代码:

      import cv2
      
      image = cv2.imread('000007.jpg')
      cv2.imshow('org_img', image)
      
      img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
      cv2.imshow('img_hsv', img_hsv)
      
      // 对应 hsv 三通道的值
      H, S, V = cv2.split(img_hsv)
      
      cv2.waitKey(0)
      cv2.destroyAllWindows()
      

(二) 代码案例

1. HSV 值进行目标物体的提取
  1. 获取要跟踪物体颜色的HSV值
    对一个BGR值进行颜色空间转换,得到HSV值。

    >>> blue = np.uint8([[[255,0,0]]])
    >>> hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)
    >>> print(hsv_blue)
    [[[120 255 255]]]
    
  2. 使用该 HSV 值范围进行目标物体的提取:
    提取方案:

    • 根据 RGB 的值(如:#869C90,#899F92,#8A9E92,#8A9F8E),转换得到 HSV 各通道的数值范围
    • 然后对其中的Hue值进行加10和减10(这里的10也可以为其他值,视具体情况而定),得到Hue的范围,还要指定S和V的范围:
    • 最后整个HSV值的上限和下限为 [hue+10,100,100]和 [hue-10,255,255],S和V的下限值可以根据实际情况设置。

    按照以上确定好的 HSV 的范围 进行提取。

    • 代码如下:

      import cv2
      import numpy as np
      
      path = "compass.jpg"
      img = cv2.imread(path)
      
      # Convert BGR to HSV
      hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
      
      sensitivity = 15
      
      # define range of blue color in HSV
      lower_blue = np.array([120-sensitivity,100,100])
      upper_blue = np.array([120+sensitivity,255,255])
      # Threshold the HSV image to get a range of blue color
      mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)
      
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
      mask_blue = cv2.morphologyEx(mask_blue, cv2.MORPH_CLOSE, kernel)  # 闭运算
      mask_blue = cv2.morphologyEx(mask_blue, cv2.MORPH_OPEN, kernel)   # 开运算
       
      # define range of red color in HSV
      lower_red_0, upper_red_0 = np.array([0,100,100]), np.array([sensitivity,255,255])
      lower_red_1, upper_red_1 = np.array([180-sensitivity,100,100]), np.array([180,255,255])
      # Threshold the HSV image to get a range of red color
      mask_0 = cv2.inRange(hsv, lower_red_0, upper_red_0)
      mask_1 = cv2.inRange(hsv, lower_red_1, upper_red_1)
      mask_red = cv2.bitwise_or(mask_0, mask_1)
      
      mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_CLOSE, kernel)
      mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_OPEN, kernel)
      
      
      # 合并蓝色mask和红色mask
      mask = cv2.bitwise_or(mask_blue, mask_red)
      # Bitwise-AND mask
      res = cv2.bitwise_and(img, img, mask=mask)
      
      cv2.imshow('image',img)
      cv2.imshow('mask_blue',mask_blue)
      cv2.imshow('mask_red',mask_red)
      cv2.imshow('res',res)
      
      if cv2.waitKey(0)==ord('q'):
          cv2.destroyAllWindows()
      

      下面分别原图,蓝色掩码,红色掩码,以及蓝色和红色区域。

    img
2. 使用 HSV 图像分割

可以利用颜色空间进行图像分割,如果图像的颜色特征比强度特征更好,则可以尝试将其转换为HSV,然后在 H通道 上进行自适应二值化处理。

import cv2

image = cv2.imread(img_path)
cv2.imshow('image', image)
# Convert BGR to HLS
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# hsv[:, :, 0]:取hsv 中的 h(色调)的值
cv2.imshow('hsv', hsv[:,:,0])
# 在H通道上进行自适应二值化处理
(thresh, im_bw) = cv2.threshold(hsv[:,:,0], 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow('otsu', im_bw)

三、HLS

1. HLS 颜色空间

HLS 也有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。
HLS 和 HSV 的区别就是最后一个分量不同,HLS 中的 L 分量为亮度,亮度为100,表示白色,亮度为0,表示黑色;

下面是 HLS 颜色空间圆柱体:

img

提取白色物体时,使用 HLS 更方便,因为 HSV 中的Hue里没有白色,白色需要由S和V共同决定(S=0, V=100)。而在 HLS 中,白色仅由亮度L一个分量决定。所以检测白色时使用 HSL 颜色空间更准确。

  • 注意:在 OpenCV 中 HLS 三个分量的范围为:
    • H = [0,179]
    • L = [0,255]
    • S = [0,255]

2. 代码案例

image = cv2.imread(image_label_line[0])

# Convert BGR to HLS
imgHLS = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)

参考资料

  • https://zhuanlan.zhihu.com/p/67930839
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值