利用opencv-python的hsv空间进行图像提取

HSV颜色空间简介

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

这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
色调可以表示颜色的种类,它是一个角度,范围是0-180°,0对应red,60对应green,120对应blue。
饱和度表示该颜色接近光谱色的程度,范围是0-255,当其为0时,只能显示黑色-白色。其逐渐增大时,颜色逐渐接近光谱色。
明度也可以理解为亮度,范围是0-255,当其为0时,为纯黑色。逐渐增大时,可逐渐显示出颜色。
(以上三个范围在不同的地方有不同的定义)
如下图可以形象的理解:
在这里插入图片描述

图像提取的例子

1.识别按钮的简单例子

设想有一工业机器人,现任务是将一墙壁上的某一按钮按下,我们现在将问题最简化然后解决。
假设墙壁为蓝色(Blue),有两个按钮分别为红色(Red),绿色(Green),现在的任务是识别出红色(Red)按钮。
解决过程:
第一步:导入所需库:

import cv2 as cv
import numpy as np

第二步:创建墙壁模型:

ground = np.ones((512,512,3),np.uint8)
for i in range(512):
    for j in range(512):
        ground[i,j] = [255,0,0]
cv.circle(ground,(200,200),50,(0,0,255),-1)
cv.circle(ground,(400,400),50,(0,255,0),-1)
cv.imshow('ground',ground)

墙壁图片如下:
在这里插入图片描述
第三步:将墙壁图片转化到HSV空间:

ground_hsv = cv.cvtColor(ground,cv.COLOR_BGR2HSV)

第四步:设置红色的取值范围并将红色取出:

lower = np.array([0,200,200])
upper = np.array([20,255,255])

red_mask = cv.inRange(ground_hsv,lower,upper)

当待识别颜色不是标准三原色时,我们可以事先查询该颜色对应的HSV颜色,在例子2中会使用到。
第五步:对原图像进行处理:

red = cv.bitwise_and(ground,ground,mask=red_mask)

cv.imshow('red',red)

显示的结果为:
在这里插入图片描述
可见已将红色按钮区域识别出

2.水果分类

我们的目标是在如下一张含有四种水果的图中,找出梨的位置:
在这里插入图片描述
代码如下

import cv2 as cv
import numpy as np

fruit = cv.imread('D:/programming/Python learn/opencv_learn/fruit.jpg')
pear = cv.imread('D:/programming/Python learn/opencv_learn/pear.jpg')

cv.imshow('fruit',fruit)

#找到梨的HSV参数范围的过程:
pear_hsv = cv.cvtColor(pear,cv.COLOR_BGR2HSV)
a = pear_hsv.shape[0]
b = pear_hsv.shape[1]
h = []
s = []
v = []
for i in range(int(a/2)-10,int(a/2)+9):
    for j in range(int(b/2)-10,int(b/2)+9):
        h.append(pear_hsv[i,j][0])
        s.append(pear_hsv[i,j][1])
        v.append(pear_hsv[i,j][2])
H = np.array(h)
S = np.array(s)
V = np.array(v)
h_min = np.min(H)
h_max = np.max(H)
s_min = np.min(S)
s_max = np.max(S)
v_min = np.min(V)
v_max = np.max(V)

fruit_hsv = cv.cvtColor(fruit,cv.COLOR_BGR2HSV)

lower = np.array([h_min,s_min-5,v_min-5])
upper = np.array([h_max,s_max+5,v_max+5])

pear_mask = cv.inRange(fruit_hsv,lower,upper)

pear = cv.bitwise_and(fruit,fruit,mask=pear_mask)

cv.imshow('pear',pear)

if cv.waitKey(-1)==ord('a'):
    cv.destroyAllWindows()

输出结果为:
在这里插入图片描述
在这里插入图片描述
可以看出虽然不完全,但可以成功将梨与其他三种水果区分开并识别出。
在本例子中,我们寻找范围的办法是:将梨的图片单独取出,查询中心区域(大小20*20)的像素组成,用这块区域的最小值与最大值适当扩张组成区分依据。在具体应用中,还需要加以改变,如香蕉的有效区域不在中心,苹果的亮度变化较大等等。想要实现比较精准、更大难度的分类需要进一步学习,我们通过这两个例子了解HSV提取的基本思想即可。