OpenCV(Python)颜色识别(一)

1. 基本原理

1.1 彩色模型

数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。而HSV模型更符合人描述和解释颜色的方式,HSV的彩色描述对人来说是自然且非常直观的。选择使用HSV模型的另一个因为是RGB通道并不能很好地反映出物体具体的颜色信息 , 而相对于RGB空间,HSV空间能够非常直观的表达色彩的明暗,色调,以及鲜艳程度,方便进行颜色之间的对比。

1.2 HSV模型

因为时间关系,在此先写出模型关键参数,若日后有朝一日变强了再来补习理论知识。
HSV模型中颜色的参数分别是:
色调(H:hue)
饱和度(S:saturation)
亮度(V:value)

由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。
(1)色调(H:hue):用角度度量,取值范围为0°~360°,
从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。
它们的补色是:黄色为60°,青色为180°,品红为300°;
(2)饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和。
(3)亮度(V:value):取值范围为0(黑色)~255(白色)

OpenCV(Python)颜色识别(一)_第1张图片

1.3 RGB转成HSV

(不确定是否在未来能否用到,在此处作为学习笔记暂时记录,理论上可以通过PS来获取目标区域的准确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

1.4 通过PS获取HSV值

在寻找关于HSV相关资料时发现并没有提供一个很方便可以直接查看的值(包括百科,事实上HSV模型的各种颜色的数值其实是在RBG的基础上通过算法进行转化得到的。)为了方便(偷懒)获取到精准的HSV模型颜色数值其实可以选择第二个方法:通过Ps软件来获取需要被识别物体的具体颜色数值。
参照表(仅供参考):
OpenCV(Python)颜色识别(一)_第2张图片
图片来自:http://blog.csdn.net/taily_duan/article/details/51506776


PS中的HSV范围,H是0-360,S是0-1,V(B)是0-1
Opencv中的HSV范围,H是0-180,S是0-255,V是0-255
因此需要转换一下,把PS中H的值除以2,S乘255,V乘255,可以得到对应的opencv的HSV值。

2.OpenCV(Python3)实现

Version1.0 提取结果不尽人意但是我会在未来一段时间里不断完善此代码以达到更好的效果。
OpenCV(Python)颜色识别(一)_第3张图片
OpenCV(Python)颜色识别(一)_第4张图片

源代码:

import cv2
import numpy
def nothing(*arg):
    pass
# Initial HSV GUI slider values to load on program start.
icol = (18, 0, 196, 36, 255, 255)
# Lower range colour sliders.
cv2.namedWindow('colorTest')
cv2.createTrackbar('lowHue', 'colorTest', icol[0], 255, nothing)
cv2.createTrackbar('lowSat', 'colorTest', icol[1], 255, nothing)
cv2.createTrackbar('lowVal', 'colorTest', icol[2], 255, nothing)
# Higher range colour sliders.
cv2.createTrackbar('highHue', 'colorTest', icol[3], 255, nothing)
cv2.createTrackbar('highSat', 'colorTest', icol[4], 255, nothing)
cv2.createTrackbar('highVal', 'colorTest', icol[5], 255, nothing)
# Raspberry pi file path example.
# frame = cv2.imread('/home/pi/python3/opencv/color-test/colour-circles-test.jpg')
# Windows file path example.
frame = cv2.imread('C:/Users/Administrator/Desktop/IMG_20200628_170115.jpg')

while True:
    # Get HSV values from the GUI sliders.
    lowHue = cv2.getTrackbarPos('lowHue', 'colorTest')
    lowSat = cv2.getTrackbarPos('lowSat', 'colorTest')
    lowVal = cv2.getTrackbarPos('lowVal', 'colorTest')
    highHue = cv2.getTrackbarPos('highHue', 'colorTest')
    highSat = cv2.getTrackbarPos('highSat', 'colorTest')
    highVal = cv2.getTrackbarPos('highVal', 'colorTest')
    # Show the original image.
    cv2.imshow('frame', frame)

    # Blur methods available, comment or uncomment to try different blur methods.
    frameBGR = cv2.GaussianBlur(frame, (7, 7), 0)
    #frameBGR = cv2.medianBlur(frameBGR, 7)
    #frameBGR = cv2.bilateralFilter(frameBGR, 15 ,75, 75)
    # Show blurred image.
    cv2.imshow('blurred', frameBGR)
    # HSV (Hue, Saturation, Value).
    # Convert the frame to HSV colour model.
    hsv = cv2.cvtColor(frameBGR, cv2.COLOR_BGR2HSV)
    # HSV values to define a colour range.
    colorLow = numpy.array([lowHue, lowSat, lowVal])
    colorHigh = numpy.array([highHue, highSat, highVal])
    mask = cv2.inRange(hsv, colorLow, colorHigh)
    # Show the first mask
    cv2.imshow('mask-plain', mask)

    kernal = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernal)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernal)
    
    # Show morphological transformation mask
    cv2.imshow('mask', mask)
    
    # Put mask over top of the original image.
    result = cv2.bitwise_and(frame, frame, mask = mask)
 
    # Show final output image
    cv2.imshow('colorTest', result)
	
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()

总结:

迫于项目时间压力以及希望能对自己的学习能力有进一步的要求,我在尝试改变自己的学习方式,这编文章只是一个开始,并非本人完全原创在查找大量实例和技术理论后对各位前辈们的经验的一种自我总结。

参考文献:

[1]https://blog.csdn.net/qq_15947787/article/details/72784253 【opencv】目标识别——HSV颜色识别
[2]https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_trackbar/py_trackbar.html
[3]https://blog.csdn.net/weixin_39490421/article/details/85998984 opencv3.1 提取图像中某一像素点的HSV值并判断颜色

你可能感兴趣的:(OpenCV之路,python)