一、前置知识
(一)图像像素存储形式
1.灰度图
对于只有黑白颜色的灰度图,为单通道,一个像素块对应矩阵中一个数字,数值为0到255, 其中0表示最暗(黑色) ,255表示最亮(白色)。
2.彩色图
对于任何一张彩色图片,有三个主通道–RGB(红绿蓝)。按不同比例相加,一个像素块对应矩阵中的一个向量, 如[24,180, 50],分别表示三种颜色的比列, 即对应深度上的数字。图片的大小为(height,width,3)。
注:opencv采用BGR模式,而不是RGB。
(二)色彩模式
1.RGB
RGB 由三个通道表示一幅图像,分别为红色( R),绿色(G)和蓝色(B)。RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。三种颜色的取值范围均为[0,255]。
2.HSV
- 在图像处理中使用较多的是HSV颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比,常用于分割指定颜色的物体。
- HSV 表达彩色图像的方式由三个部分组成:Hue(色调、色相);Saturation(饱和度、色彩纯净度);Value(明度)
- 用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。
(1)Hue(色调、色相)
Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。颜色圆环上所有的颜色都是光谱上的颜色,从红色开始按逆时针方向旋转,Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色。
(2)Saturation(饱和度、色彩纯净度)
- 其中水平方向表示饱和度,饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色。饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。
- 在Hue一定的情况下,饱和度减小,就是往光谱色中添加白色,光谱色所占的比例也在减小,饱和度减为0,表示光谱色所占的比例为零,导致整个颜色呈现白色。
(3)Value(明度)
- 竖直方向表示明度,决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。
- 明度减小,就是往光谱色中添加黑色,光谱色所占的比例也在减小,明度减为0,表示光谱色所占的比例为零,导致整个颜色呈现黑色。
(4)取值范围
H:0-180
S:0-255
V:0-255
颜色的模糊范围:
二、色彩模式转换
(一)cv2.cvtColor()
使用cv2.cvtColor()函数实现色彩空间的变换,该函数可以实现多个色彩空间之间的转换。
dst = cv2.cvtColor(src,code,[dstCn])
- src:表示原图。
- code:色彩空间转换码。
- dstCn:目标图像的通道数,默认为0,通道自动通过原图和code获得。
使用以下命令可获得code参数:
import cv2
import numpy as np
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags) ## 输出一大串
经常使用的code参数:
参数 | 解释 |
---|---|
cv2.COLOR_BGR2RGB | 从BGR模型转为RGB模型 |
cv2.COLOR_BGR2GRAY | 从BGR模型转为灰度图 |
cv2.COLOR_BGR2HSV | 从BGR模型转为HSV |
import cv2
import matplotlib.pyplot as plt
## 画图
def show_im(num,img,title):
plt.subplot(2,2,num)
plt.imshow(img)
plt.axis('off')
plt.title(title)
## 显示读取的图片
img_BGR = cv2.imread('ty.jpg',1)
show_im(1,img_BGR,'BGR')
## 将图片转为RGB图
img_RGB = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2RGB)
show_im(2,img_RGB,'RGB')
## 将图片转为灰度图
img_GRAY = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2GRAY)
show_im(3,img_GRAY,'GRAY')
## 将图片转为HSV
img_HSV = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2HSV)
show_im(4,img_HSV,'HSV')
plt.savefig('ty_conbine.jpg')
plt.show()
(二)cv2.inRange()
使用inRange函数设阈值。
dst = cv2.inRange(src, lowerb, upperb, dst=None)
- src:表示原图。
- lowerb:表示阈值下限。
- upperb:表示阈值上限。
- dst:输出和src相同的矩阵。
(三)np.uint8()
用OpenCV处理图像时,获得的矩阵类型都是uint8。uint8是专门用于存储各种图像的(包括RGB,灰度图像等),范围是从0–255。要想将当前的数组作为图像类型来进行各种操作,就要转换到uint8类型。
import numpy as np
a = [245,100,2]
np.uint8(a)
##Out[1]: array([245, 100, 2], dtype=uint8)
(四)实例
在OpenCV中HSV三个分量的范围为:H = [0,179] S = [0,255] V = [0,255]
1° BGR转换HSV
import numpy as np
import cv2
bgr_blue = np.uint8([[[255,0,0]]])
hsv_blue = cv2.cvtColor(bgr_blue, cv2.COLOR_BGR2HSV)
print(hsv_blue)
## Out[1]: array([[[120, 255, 255]]], dtype=uint8)
2° 提取特征颜色
因为H=0和H=180都对应红色,所以对于红色的话,需要定义两个范围,并进行取或操作。
import numpy as np
import cv2
import matplotlib.pyplot as plt
## 画图
def show_im(num,img,title):
plt.subplot(1,2,num)
plt.imshow(img)
plt.axis('off')
plt.title(title)
## 读取图片
ty_img = cv2.imread('ty_red.jpg')
## 显示原图(转换为rgb正常格式)
ty_rgb = cv2.cvtColor(ty_img, cv2.COLOR_BGR2RGB)
show_im(1,ty_rgb,'Original')
## 讲BGR格式转为HSV
ty_hsv = cv2.cvtColor(ty_img, cv2.COLOR_BGR2HSV)
## 取红色
sensitivity = 10
lower_red0 = np.array([0,100,100])
upper_red0 = np.array([sensitivity,255,255])
lower_red1 = np.array([180-sensitivity,100,100])
upper_red1 = np.array([180,255,255])
## 设置阈值
mask_0 = cv2.inRange(ty_hsv,lower_red0,upper_red0)
mask_1 = cv2.inRange(ty_hsv,lower_red1,upper_red1)
mask_red = cv2.bitwise_or(mask_0, mask_1)
## 对原图像处理
res = cv2.bitwise_and(ty_img,ty_img,mask=mask_red)
## 显示取红色后的效果
res_rgb = cv2.cvtColor(res, cv2.COLOR_BGR2RGB)
show_im(2,res_rgb,'Conversion')
plt.savefig('ty_exred.jpg')
plt.show()