OpenCV-Python系列之改变颜色空间
从本次教程开始,我们正式进入基础篇的学习,OpenCV图像处理中最重要的一环就是图像的颜色空间,我们在之前已经见到过关于图像灰度化的例子,但这仅仅是其中的一种。
颜色空间
色彩/颜色空间(英语:Color space)是对色彩的组织方式。借助色彩空间和针对物理设备的测试,可以得到色彩的固定模拟和数字表示。色彩空间可以只通过任意挑选一些颜色来定义,比如像彩通系统就只是把一组特定的颜色作为样本,然后给每个颜色定义名字和代码;也可以是基于严谨的数学定义,比如 Adobe RGB、sRGB。
许多人都知道在绘画时可以使用红色、黄色和蓝色这三种原色生成不同的颜色,这些颜色就定义了一个色彩空间。我们将品红色的量定义为X 坐标轴、青色的量定义为Y坐标轴、黄色的量定义为Z坐标轴,这样就得到一个三维空间,每种可能的颜色在这个三维空间中都有唯一的一个位置。
但是,这并不是唯一的一个色彩空间。例如,当在计算机监视器上显示颜色的时候,通常使用RGB(红色、绿色、蓝色)色彩空间定义,这是另外一种生成同样颜色的方法,红色、绿色、蓝色被当作X、Y和Z坐标轴。另外一个生成同样颜色的方法是使用色相(X轴)、饱和度(色度)(Y轴)和明度(Z轴)表示,这种方法称为HSB色彩空间。另外还有许多其它的色彩空间,许多可以按照这种方法用三维(X、Y、Z)、更多或者更少维表示,但是有些根本不能用这种方法表示。
我们生活中大多数看到的彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图、二值图、HSV、HSI等颜色制式,OpenCV提供了cvtColor()函数来实现这些功能。首先看一下cvtColor函数定义:
cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
. InputArray src: 输入图像即要进行颜色空间变换的原图像,可以是Mat类
. OutputArray dst: 输出图像即进行颜色空间变换后存储图像,也可以Mat类
. int code: 转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片,后面会详细讲述
. int dstCn = 0: 目标图像通道数,如果取值为0,则由src和code决定
函数的作用是将一个图像从一个颜色空间转换到另一个颜色空间,但是从RGB向其他类型转换时,必须明确指出图像的颜色通道,前面我们也提到过,在OpenCV中,其默认的颜色制式排列是BGR而非RGB。所以对于24位颜色图像来说,前8-bit是蓝色,中间8-bit是绿色,最后8-bit是红色。常见的R,G,B通道的取值范围为:
. 0-255 :CV_8U类型图片
. 0-65535: CV_16U类型图片
. 0-1: CV_32F类型图片
在本次教程中我们只研究几种重要的颜色空间转化方法,包括有灰度化,HSV空间转换。我们首先来看代码:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | import cv2 img = cv2.imread( "cat.jpg" ) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS) LAB = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) LUV = cv2.cvtColor(img, cv2.COLOR_BGR2LUV) cv2.imshow( "gray" , gray) cv2.imshow( "hsv" , hsv) cv2.imshow( "hls" , hls) cv2.imshow( "LAB" , LAB) cv2.imshow( "LUV" , LUV) cv2.waitKey( 0 ) cv2.destroyAllWindows() |
我们来看效果:
我们看到了六个不同颜色的猫,当然,OpenCV内部的颜色空间转换多达150多种,在这里不可能一一演示,我们只讲最重要的两种:灰度化和HSV,灰度化就不必多说了,主要看看HSV,HSV通常用与颜色追踪,也算是一种初级的目标追踪方法,它比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。
HSV 表达彩色图像的方式由三个部分组成:
· Hue(色调、色相)
· Saturation(饱和度、色彩纯净度)
· Value(明度)
用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。
Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。表示如下:
颜色圆环上所有的颜色都是光谱上的颜色,从红色开始按逆时针方向旋转,Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色等等。
在 GRB中 颜色由三个值共同决定,比如黄色为即 (255,255,0);在HSV中,黄色只由一个值决定,Hue=60即可。
HSV 圆柱体的半边横截面(Hue=60):
其中水平方向表示饱和度,饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。
竖直方向表示明度,决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。
可以通俗理解为:
在Hue一定的情况下,饱和度减小,就是往光谱色中添加白色,光谱色所占的比例也在减小,饱和度减为0,表示光谱色所占的比例为零,导致整个颜色呈现白色。
明度减小,就是往光谱色中添加黑色,光谱色所占的比例也在减小,明度减为0,表示光谱色所占的比例为零,导致整个颜色呈现黑色。
HSV 对我们来说是一种比较直观的颜色模型。我们可以很轻松地得到单一颜色,即指定颜色角H,并让V=S=1,然后通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小V而S不变,同样增加白色可以减小S而V不变。例如,要得到深蓝色,V=0.4 S=1 H=240度。要得到浅蓝色,V=1 S=0.4 H=240度。
HSV 的拉伸对比度增强就是对 S 和 V 两个分量进行归一化即可,H 保持不变。
注意:在 OpenCV 中 HSV 三个分量的范围为:
· H = [0,179]
· S = [0,255]
· V = [0,255]
目标颜色追踪
前面已经提到过,颜色追踪根据HSV色彩空间来实现的,首先我们需要对一个BGR值进行颜色空间转换,得到HSV值。
为了识别特定颜色的物体,获取到颜色所对应的HSV值很重要,这里我们给出一个转化表:
而要想用代码实现这些数据范围,我们需要知道OpenCV的一个函数:
cv2. inRange(InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst),对于各个参数的解析:
1.src是输入的数组
2.lowerb是包含lowerb的最小值数组或分量,本教程中用于上表中的最小数值
3.upperb是包含upperb的最大值数组或分量,本教程中用于上表中的最大数值
4.输出的数组,大小和通道数与src一样,并且是CV_8V的类型
我们来看代码,该代码用于打开摄像头,识别绿色物体的移动:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import cv2 import numpy as np cap = cv2.VideoCapture( 0 ) while True : ret, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_black = np.array([ 35 , 43 , 46 ]) upper_black = np.array([ 77 , 255 , 255 ]) mask = cv2.inRange(hsv, lower_black, upper_black) res = cv2.bitwise_and(frame, frame, mask = mask) cv2.imshow( 'frame' , frame) cv2.imshow( 'mask' , mask) cv2.imshow( 'res' , res) k = cv2.waitKey( 5 ) & 0xFF if k = = 27 : break cv2.destroyAllWindows() |
我们来看效果:
完美,这样用HSV跟踪物体就可以了,最重要的还是取值范围的标定,根据上面的那个表格来进行取值就完全可以。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· .NET Core GC压缩(compact_phase)底层原理浅谈
· Winform-耗时操作导致界面渲染滞后
· Phi小模型开发教程:C#使用本地模型Phi视觉模型分析图像,实现图片分类、搜索等功能
· 语音处理 开源项目 EchoSharp