文章目录
1、色彩空间的介绍
1.1、什么是色彩空间
所谓色彩空间,又称“色域”,即一定的色彩范围,这是一种色彩模型。sRGB、AdobeRGB、ProPhotoRGB、CMYK等都是不同的色彩空间。它们都以可见光谱为基础,但分别包含不同的色彩范围。
1.2、常见的色彩空间
1.2.1、RGB
RGB是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是运用最广的颜色系统之一。
RGB色彩空间如下图所示。
1.2.2、HSV
HSV色彩空间(Hue-色调、Saturation-饱和度、Value-值)将亮度从色彩中分解出来,在图像增强算法中用途很广。
HSV色彩空间如下图所示,用一个倒圆锥体表示整个色彩空间:
在opencv中,H的范围是0-180,S和V的范围是0-255。
1.2.3、HSI
HSI颜色模型用H、S、I三参数描述颜色特性,其中H定义颜色的波长,称为色调;S表示颜色的深浅程度,称为饱和度;I表示强度或亮度。
色调H 是描述纯色的属性(如红色、黄色等);饱和度S 表示的是一种纯色被白光稀释的程度的度量;强度I 是一个主观的描述,是人对彩色感觉的关键参数,实际上它是不可能测量的。该模型在开发基于彩色描述的图像处理算法中非常有用。
1.2.4、YCrCb
YCbCr有的时候会被写作:YCBCR,是色彩空间的一种,通常会用于影片中的影像连续处理,或是数字摄影系统中。Y为颜色的亮度(luma)成分、而CB和CR则为蓝色和红色的浓度偏移量成分。
1.2.5、YUV
“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
1.3、相应的API
(1)转换为灰度空间
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray_image", gray)
原图为
经转换后
(2)转换为HSV空间
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
cv.imshow("hsv_image", hsv)
(3)转换为YUV空间
yuv = cv.cvtColor(image, cv.COLOR_BGR2YUV)
cv.imshow("yuv_image", yuv)
(4)转换为YCrCb空间
Ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)
cv.imshow("Ycrcb_image", Ycrcb)
(5)转换为HSI空间
hsi = cv.cvtColor(image, cv.COLOR_BGR2HLS)
cv.imshow("hsi_image", hsi)
2、色彩空间的应用
色彩空间的应用太广泛了,没有做不到,只有想不到,因此我只演示一下一些简单的应用,不要小看简单了,绝大多数复杂的东西都是由各种简单而细微的事物构成的,千里之行始于足下,还是一步一步来吧。
在HSV色彩空间提取出一些颜色,我们会用到inRange这个API,顾名思义,这个函数的作用肯定是标定范围的,那么我们该如何运用呢?
2.1、颜色的提取
在上面的表格中,我们可以看到各种颜色在HSV空间的取值范围,因此我们可以通过该范围来提取出我们需要的颜色。
假如我们要从一段视频或者一张图像中提取出绿色,我们就应该先把它转换到HSV空间,代码如下:
capture = cv.VideoCapture("D:/opencv3/image/vst.avi")
while True:
ret, frame = capture.read()
if not ret: # if ret == False
break
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
接着我们要知道绿色的取值范围,由表格可得:最低值分别为35,43,46,最高值分别为77,255,255,于是我们就通过以下代码来提取出颜色:
lower_hsv = np.array([37, 43, 46]) # 查看表中绿色的HSV低值
upper_hsv = np.array([77, 255, 255]) # 查看表中绿色的HSV高值
mask = cv.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv) #cv.inRange(目标图像,阈值下,阈值上,输出图像)
这时产生的效果为
经对比,原视频中的大部分绿色都被标记出来了,那如果我们硬要原图中的绿色呢?可以使用以下操作:
dst = cv.bitwise_and(frame, frame, mask=mask) # 对比原图和掩模进行位运算
效果为:
看起来有点魔幻。
完整代码
import cv2 as cv # 导入opencv模块
import numpy as np # 导入数学函数库
def extrace_object_demo(): # 将视频中的绿色部分过滤出来,使用cv.inRange()函数
capture = cv.VideoCapture("D:/opencv3/image/vst.avi")
while True:
ret, frame = capture.read()
if not ret: # if ret == False
break
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
lower_hsv = np.array([37, 43, 46]) # 查看表中绿色的HSV低值
upper_hsv = np.array([77, 255, 255]) # 查看表中绿色的HSV高值
mask = cv.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv) # cv.inRange(目标图像,阈值下,阈值上,输出图像)
dst = cv.bitwise_and(frame, frame, mask=mask) # 对比原图和掩模进行位运算
cv.imshow("video", frame)
cv.imshow("mask", dst)
c = cv.waitKey(40)
if c == 27:
break
def color_space_demo(image): # 转化图片的色彩空间
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray_image", gray)
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
cv.imshow("hsv_image", hsv)
yuv = cv.cvtColor(image, cv.COLOR_BGR2YUV)
cv.imshow("yuv_image", yuv)
Ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)
cv.imshow("Ycrcb_image", Ycrcb)
hsi = cv.cvtColor(image, cv.COLOR_BGR2HLS)
cv.imshow("hsi_image", hsi)
print("------------hello python!------------")
src = cv.imread("D:/opencv3/image/linux.png")
cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
cv.imshow("input_image", src)
# color_space_demo(src)
extrace_object_demo()
# b, g, r = cv.split(src) # 通道分离
# cv.imshow("blue", b)
# cv.imshow("green", g)
# cv.imshow("red", r)
#
# src[:, :, 1] = 0 # 将第二个通道赋值为0
# src = cv.merge([b, g, r]) # 合并3个通道
# cv.imshow("changed_image", src)
cv.waitKey(0)
cv.destroyAllWindows() # 释放所有窗口