opencv 提供了cvtColor()函数,用于在图像中不同的色彩空间进行转换,用于后续处理。在使用cvtColor之前首先需要了解下基本的图像色彩模式,色彩模式决定了打印或显示的图片颜色。
图像色彩模式
位图模式
位图模式是图像中最基本的格式,图像只有黑色和白色像素,是色彩模式中占有空间最小的,同样也叫做黑白图,它包含的信息量最少,无法包含图像中的细节,相当于只有0或者1
一副彩色图如果要转换成黑白模式,则一般不能直接转换,需要首先将图像转换成灰度模式
灰度模式
灰度模式即使用单一色调来表示图像,与位图模式不同,不像位图只有0和1,使用256级的灰度来表示图像,一个像素相当于占用8为一个字节,每个像素值使用0到255的亮度值代表,其中0为黑色,255为白色,相当于从黑->灰->白的过度,通常我们所说的黑白照片就是这种模式,与位图模式相比,能表现出一定的细节,占用空间也比位图模式较大
RGB模式
RGB模式为我们经常见到的,被称为真色彩。RGB模式的图像有3个颜色通道,分布为红(Red),绿(Green)和蓝(Bule),每个都占用8位一个字节来表示颜色信息,这样每个颜色的取值范围为0~255,那么就三种颜色就可以有多种组合,
当三种基色的值相等是,表现出为灰色,三种颜色都为255即为白色,三种颜色都为0,即为黑色
RGB模式的图像占用空间要比位图,灰度图都要大,但表现出的细节更加明显
CMYK模式
CMYK模式被称为印刷色彩模式,主要是来源于印刷行业,以打印油墨在纸张上的光线吸收特性为基础,与RGB类似,也是使用三种颜色,分别为青色(Cyan),品红色(Magenta),黄色(Yellow),以及黑色(Black)
与RGB不同的是:RGB模式依靠的是自身发光的色彩模式,而CMYK是一种依靠反光的色彩模式。
HSB模式
是根据日常生活中人眼的视觉对色彩的观察得而制定的一套色彩模式,最接近与人类对色彩的辨认的思考方式,所有的颜色都是用色彩三属性来描述
H:(色相):是指从物体反射或透过物体传播的颜色
S:(饱和度):是指颜色的强度或纯度,表示色相中灰色成分所占的比例
B:(亮度):是指颜色对相对明暗程度,通常 100%定义为白色;0%为黑色
除了上述以上之外,还有索引模式,多通道模式等等不再介绍
YUV格式
除了上述图像模式之外,由于历史原因大部分摄像头输入的图片格式都是YUV格式,开始主要用于电视系统以及模拟视频领域。YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。如果没用UV信息,只有Y信息,也可以进行成像不过只是黑白的,这样就能很好解决彩色电视与黑白电视的兼容问题,与RGB相比,YUV占用带宽较少,目前摄像头输出格式普遍采用YUV格式。具体介绍可以见http://iyenn.com/rec/327195.html
而在图像的处理过程中,其实很少使用YUV格式,一般都需要转成RGB格式或者灰度图格式进行转换,而opencv的cvtColor()函数支持这种转换
cvtColor
opencv的python接口如下:
st = cv.cvtColor( src, code[, dst[, dstCn]]
其中src:为原图片
code:需要进行色彩空间转换的结果
其C++接口为:
- void cv::cvtColor ( InputArray src,
- OutputArray dst,
- int code,
- int dstCn = 0
- )
使用例子将一个RGB图,转换成灰度图
- import numpy as np
- import cv2 as cv
-
- img = cv.imread(".././datasheet/len_top.jpg",cv.IMREAD_COLOR)
- cv.imshow('lenna',img)
- cv.waitKey(0)
- gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
- cv.imshow("gray", gray)
- cv.waitKey(0)
- cv.destroyAllWindows()
读取到的彩色图
转换成的灰度图:
注意使用cvtColor RGB转成其他格式时,需要注意RGB图像的三个通道的顺序,是RGB还是BGR.大部分情况下opencv为RGB,但实际上是BGR,这一点需要注意。
需要注意各个值的范围:
CV_8U图像 其通道值范围为0到255
CV_16U时其值通道值范围为0到65535
CV_32F时,其通道值范围为0到1
在线性转换时,其范围没有较大关系,但是如果是非线性转换,RGB图像需要做正确的归一化,以扩展到响应的范围。例如TGB->L*U*V转换,如果32位的浮点图像之间是由8位的图像转换而来,那么将0到255的范围转换成0,1,那么转换之前首先需要需要所需其图像
- img *= 1./255;
- cvtColor(img, img, COLOR_BGR2Luv);
如果之间使用cvtColor进行转换,将会丢掉一些信息
cvtColor Code
opencv cvtcolor支持的空间转发code,如下,基本能够满足日常需要
评论记录:
回复评论: