一、颜色模型与转换
1.1RGB颜色模型
? ? ? ?RGB颜色空间模型:
?
? ? ? ? 该模型的命名方式是采用三种颜色的英文首字母,分别是红色,绿色,和蓝色。在RGB模型中所有的颜色都是这三种颜色通过不同比例的混合模型,如果三种颜色都为零,则表示为黑色,如果三种颜色的分量相同且都为最大值,则表示为白色。在这个基础上增加第四个通道即为RGBA模型,第四个通道表示颜色的透明度,当没有透明度需求的时候,RGBA模型就会退化成RGB模型。
1.2YUV颜色模型
? ? ? ? YUV模型是电视信号系统所采用的颜色编码方式。这三个变量分别表示像素的亮度(Y)、红色分量与亮度信号差值(U)、蓝色与亮度的差值(V)。这种颜色模型主要用于视频和图像的传输。RGB模型与YUV模型之间的转换关系如下:
?1.3HSV颜色模型
? ? ? ??HSV是一种将RGB色彩空间中的点在倒圆锥体中的表示方法。HSV即色相(Hue)、饱和度(Saturation)、明度(Value),又称HSB(B即Brightness)。色相是色彩的基本属性,就是平常说的颜色的名称,如红色、黄色等。饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0-100%的数值。明度(V),取0-max(计算机中HSV取值范围和存储的长度有关)。HSV颜色空间可以用一个圆锥空间模型来描述。圆锥的顶点处,V=0,H和S无定义,代表黑色。圆锥的顶面中心处V=max,S=0,H无定义,代表白色。
1.4Lab颜色模型
? ? ? ? Lab颜色模型弥补来了RGB颜色模型的不足。是一种设备无关和基础与生理特征的颜色模型。在模型中, L表示亮度,a和b是两个颜色通道,两者的取值区间都是-128~127,其中a通道数值有小到打对应的颜色是从绿色变成红色,b通道数值由小到大对应的颜色是由蓝色变成黄色。
1.5GRAY颜色模型
? ? ? ? GRAY模型并不是一个彩色模型,而是一个灰度图像,灰度图像具有相同尺寸相同亚索格式所占容量小,易于采集,便于传输等优点。常用RGB模型转化成灰度图像的方式:
????????????????GRAY = 0.3R+ 0.59G+ 0.11B
1.6不同颜色模型之间的互相转换
? ? ? ? OpenCV提供了cvtColor()函数用于转化功能。
void cv::cvtColor(InputArray src,
OutputArray dst,
int code,
int dstCn = 0
)
src: 待转换颜色模型的原始图像。
dst:转换颜色模型后的目标图像。
code:颜色空间转换的标志。
dstCn:目标图像中的通道数。
????????如果转换过程中添加了alpha通道(RGB模型中第四个通道,表示透明度),则其值将设置为相应通道范围的最大值:CV_8U为255,CV_16U为65535,CV_32F为1。
cvtColor()函数颜色模型转换常用标志参数
标志参数 | 简记 | 作用 | COLOR_BGR2BGRA | 0 | 对RGB图像添加alpha通道 | COLOR_BGR2RGB | 4 | 彩色图像通道颜色顺序的更改 | COLOR_BGR2GRAY | 10 | 彩色图像转化成灰度图像 | COLOR_GRAY2BGR | 8 | 灰度图像转化成彩色图像(伪彩色) | COLOR_BGR2YUV | 82 | RGB颜色模型转成YUV颜色模型 | COLOR_YUV2BGR | 84 | YUV颜色模型转成RGB颜色模型 | COLOR_BGR2HSV | 40 | RGB颜色模型转成HSV颜色模型 | COLOR_HSV2BGR | 54 | HSV颜色模型转成RGB颜色模型 | COLOR_BGR2Lab | 44 | BGR颜色模型转成Lab颜色模型 | COLOR_Lab2BGR | 56 | Lab颜色模型转成RGB颜色模型 |
代码实例:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("lena.png");
if (img.empty())
{
cout << "请检查输入的图像数据是否正确" << endl;
return -1;
}
Mat gray, HSV, YUV, Lab;
cvtColor(img, HSV, COLOR_BGR2HSV);
cvtColor(img, YUV, COLOR_BGR2YUV);
cvtColor(img, Lab, COLOR_BGR2Lab);
cvtColor(img, gray, COLOR_BGR2GRAY);
imshow("原图", img);
imshow("HSV", HSV);
imshow("YUV", YUV);
imshow("Lab", Lab);
imshow("gray", gray);
waitKey(0);
return 0;
}
二、多通道分离函数与合并
2.1多通道分离函数split()
????????OpenCV中针对多通道分离函数split()有两种重载原型。
void cv::split(const Mat &src,
Mat *mvbegin
)
void cv::split(InputArray m,
OutArray mv
)
src:带分离的多通道图像。
mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同。
m:带分离的多通道图像。
mv:分离后的单通道图像,为向量(vector)形式。
? ? ? ? 虽然两个函数原型输入参数的类型不同,但通道分离的原理是相同的,可以用下式表示:
? ? ? ? mv[c](I) = src(I)
2.2多通道合并函数merge()
? ? ? ? OpenCV针对多通道分离合并函数merge()也有两种重载原型。
void cv::merge(const Mat &mv,
size_t cout,
OutputArray dst
)
void cv::merge(InputArrayOfArrays mv,
OutputArray dst
)
mv(第一种重载原型参数) : 需要合并的图像数组,其中每个图像必须有相同的尺寸和数据类型。
cout:输入的图像数组的长度,其数值必须大于0。
mv(第二种重载原型参数):需要合并的图像向量(vector),其中每个图像必须拥有相同的尺寸和数据类型。
dst:合并后输出的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。
2.3图像多通道分离与合并例程
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("C:\\Users\\王淏\\Pictures\\f9afe18da2fb1fa2ff72c4d8b29fe6a (2).png");
if (img.empty())
{
cout << "请检查输入的图像数据是否正确" << endl;
return -1;
}
Mat HSV;
cvtColor(img, HSV, COLOR_BGR2HSV);
Mat imgs0, imgs1, imgs2; //用于存放数组类型的结果
Mat imgv0, imgv1, imgv2; //用于存放vector类型的结果
Mat result0, result1, result2; //多通道合并的结果
//输入数组参数的多通道分离与合并0
Mat imgs[3];
split(img, imgs);
imgs0 = imgs[0];
imgs1 = imgs[1];
imgs2 = imgs[2];
imshow("RGB-B通道", imgs0);
imshow("RGB-G通道", imgs1);
imshow("RGB-R通道", imgs2);
imgs[2] = img; //将数组中的图像通道数变成不一致
merge(imgs, 3, result0); //合并图像
//imshow("result0", result0); imshow最多显示4个通道因此结果Image Watch中查看
Mat zero = cv::Mat::zeros(img.rows, img.cols, CV_8UC1);
imgs[0] = zero;
imgs[2] = zero;
merge(imgs , 3, result1);
imshow("result1", result1);
//输入vector参数的多通道分离与合并
vector<Mat> imgv;
split(HSV, imgv);
imgv0 = imgv.at(0);
imgv1 = imgv.at(1);
imgv2 = imgv.at(2);
imshow("HSV-H通道", imgv0);
imshow("HSV-S通道", imgv1);
imshow("HSV-V通道", imgv2);
imgv.push_back(HSV); //将vector中的图像通道数变成不一致
merge(imgv, result2);
//imshow("result2", result2); imshow最多显示4个通道,因此结果在Image Watch中查看
waitKey(0);
return 0;
}
|