彩色模型

数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。而HSV模型更符合人描述和解释颜色的方式,HSV的彩色描述对人来说是自然且非常直观的。
RGB就是指Red,Green和Blue,一副图像由这三个channel(通道)构成;
Gray就是只有灰度值一个channel;
HSV即Hue(色调),Saturation(饱和度)和Value(亮度)三个channel。

HSV模型

HSV模型中颜色的参数分别是:色调(H:hue),饱和度(S:saturation),亮度(V:value)。由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。

色调(H:hue):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;(OpenCV中H的取值范围为0~180,8bit存储时)

饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和;

亮度(V:value):取值范围为0(黑色)~255(白色)。

opencv 字体 颜色渐变 opencv颜色特征_opencv

BGR转HSV

设 (r, g, b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 r, g 和 b 中的最大者。设 min 等于这些值中的最小者。要找到在 HSV 空间中的 (h, s, v) 值,这里的 h ∈ [0, 360)是角度的色相角,而 s, v ∈ [0,1] 是饱和度和亮度,计算为:

max=max(R,G,B) 
 min=min(R,G,B) 
 if R = max:H = (G-B)/(max-min) 
 if G = max:H = 2 + (B-R)/(max-min) 
 if B = max:H = 4 + (R-G)/(max-min)H = H * 60 
 if H < 0:H = H + 360 
 V=max(R,G,B) 
 S=(max-min)/max

OpenCV下有个函数可以直接将RGB模型转换为HSV模型,注意的是OpenCV中H∈ [0, 180), S ∈ [0, 255], V ∈ [0, 255]。我们知道H分量基本能表示一个物体的颜色,但是S和V的取值也要在一定范围内,因为S代表的是H所表示的那个颜色和白色的混合程度,也就说S越小,颜色越发白,也就是越浅;V代表的是H所表示的那个颜色和黑色的混合程度,也就说V越小,颜色越发黑。经过实验,识别蓝色的取值是 H在100到140,S和V都在90到255之间。一些基本的颜色H的取值可以如下设置:

Orange 0-22
Yellow 22- 38
Green 38-75
Blue 75-130
Violet 130-160
Red 160-179

Python实现

RGB在OpenCV中存储为BGR的顺序,数据结构为一个3D的numpy.array,索引的顺序是行,列,通道:

BGRImg = cv2.imread(ImgPath)
B = BGRImg[:, :, 0]
G = BGRImg[:, :, 1]
R = BGRImg[:, :, 2]

也可以使用:

BGRImg = cv2.imread(ImgPath)
B, G, R = cv2.split(BGRImg)

注意:cv2.split的速度比直接索引要慢,但cv2.split返回的是拷贝,直接索引返回的是引用(改变B就会改变BGRImg)

转换颜色空间:(从BGR转换到HSV)
cv2.cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV)

HSV空间亦是如此:
HSV = cv2.cvtColor(Img, cv2.COLOR_BGR2HSV)
H, S, V = cv2.split(HSV)

颜色物体检测

以检测蓝色物体为例
Python代码:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):

    # Take each frame
    _, frame = cap.read()

    # Convert BGR to HSV
    hsv = cv2.cvtColor(frame, cv2.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 = cv2.inRange(hsv, lower_blue, upper_blue)

    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)

    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()

实验结果如下: