0 引言
使用opencv进行视觉识别处理时,大多数函数需要图片为单通道(灰色),同时我们也可以通过cv.inRange、cv.bitwise_and等函数的操作,完成以颜色为特征的图像提取,达到一定程度上的图像识别。(完整代码附于文末,其中本文未提到的函数,在本专栏前几节均有提到,欢迎大家去翻阅)
1 先简单了解一下颜色空间
颜色空间主要包括BGR、HSV、HSL、GRAY等等,还有很多颜色空间,大家感兴趣可以去搜索了解了解。但博主目前最主要使用到的就是上述4种。
BGR:三通道,蓝色(B)、绿色(G)、红色(R)
HSV:三通道,色调(H),饱和度(S),明度(V)
HSL:三通道,色相(H)、饱和度(S)、亮度(L)
GRAY:单通道,灰度空间
注:三通道的颜色空间由三个参数共同作用成一种颜色。
2 将BGR转换为HSV
对于色彩空间的转换,可以使用函数cv.cvtColor(src, code),该函数输入值为两个参数,src是指处理的对象窗口,code是指颜色空间转换的类型:
例cv.COLOR_BGR2GRAY,color自然指颜色,而BGR2GRAY与BGR to GRAY同义,就是告诉计算机将BGR色彩空间转换为灰度空间。
本节将BGR转换为HSV具体程序如下:
import cv2 as cv
import numpy as np
cap=cv.VideoCapture(0)
while(1):
#读取帧
_,frame=cap.read()
#转换颜色空间BGR到HSV
hsv=cv.cvtColor(frame,cv.COLOR_BGR2HSV)
3 提取图片中的指定颜色
提取颜色有两个步骤,首先是指定我们要提取什么颜色,然后进行像素对比提取。指定颜色我们可以给一个范围,比如说我们想要提取绿色,那么我们给出范围(最大值与最小值),范围可以通过HSV分量表读取:
读取的值为:(35,43,46)~(77,255,255),因此编程:
#定义HSV中绿色范围
lower_green=np.array([35,43,46])
upper_green = np.array([77,255,255])
再使用cv.inRange(src, lowerb, upperb)函数,其中的参数分别为:
src:转换为hsv颜色空间的图片、lowerb:最小值、upperb:最大值
因此编程为:
#设置HSV的阈值,使之只取绿色
mask=cv.inRange(hsv,lower_green,upper_green)
至此,完成了指定颜色的提取。图像中为该种指定颜色的像素赋值为1,显示为白色,反之为0,显示为黑色。结果如图:
4 像素叠加,得到提取的指定颜色
像素叠加采用了按位操作符:cv.bitwise_and(srt1, srt2, mask),该函数相当于数学运算的“与”,原理如下:1&1=1、1&0=0、0&1=0、0&0=0。srt1、srt2分别为相加的两个窗口,mask为指定要更改的输出数组的元素。该函数运行时,只会将mask部分的像素进行“与”运算,最后保留指定色彩。例:
#将掩膜与图像层逐像素相加
res=cv.bitwise_and(frame,frame,mask=mask)
结果为:
5 附上完整代码
import cv2 as cv
import numpy as np
cap=cv.VideoCapture(0)
while(1):
#读取帧
_,frame=cap.read()
#转换颜色空间BGR到HSV
hsv=cv.cvtColor(frame,cv.COLOR_BGR2HSV)
#定义HSV中绿色范围
lower_green = np.array([35, 43, 46])
upper_green = np.array([77, 255, 255])
#设置HSV的阈值,使之只取绿色
mask=cv.inRange(hsv,lower_green,upper_green)
#将掩膜与图像层逐像素相加
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()
至此,完成了opencv颜色空间的转换,并且完成以颜色为特征的图像提取,达到一定程度上的图像识别。欢迎大家的批评指正~