1. 颜色模型与转换
1.1 RGB 颜色模型
RGB 颜色空间模型
1.2 YUV 颜色模型
1.3 HSV 颜色模型
HSV 颜色空间模型
1.4 Lab 颜色模型
Lab 颜色空间模型
1.5 GRAY 颜色模型
2. 不同颜色模型间的互相转换
2.1 cvtColor()函数原型
void cv::cvtColor(InputArray src,
OutputArray dst,
int code,
int dstCn = 0
)
• src :待转换颜色模型的原始图像。• dst :转换颜色模型后的目标图像。• code :颜色模型转换标志,如由 RGB 空间到 HSV 空间 。• dstCn :目标图像中的通道数。如果参数为 0 ,则从 src 和代码中自动导出通道数。
2.2 示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("../pic/gril_1.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat gray, HSV, YUV, Lab, img32;
img.convertTo(img32, CV_32F, 1.0 / 255); //将 CV_8U 类型转换成 CV_32F 类型
//img32.convertTo(img, CV_8U, 255); //将 CV_32F 类型转换成 CV_8U 类型
cvtColor(img32, HSV, COLOR_BGR2HSV);
cvtColor(img32, YUV, COLOR_BGR2YUV);
cvtColor(img32, Lab, COLOR_BGR2Lab);
cvtColor(img32, gray, COLOR_BGR2GRAY);
imshow("原图", img32);
imshow("HSV", HSV);
imshow("YUV", YUV);
imshow("Lab", Lab);
imshow("gray", gray);
waitKey(0);
return 0;
}
2.3 运行结果
2.3 convertTo()函数原型
void cv::Mat::convertTo(OutputArry m,
int rtype,
double alpha = 1,
double beta = 0
)
• m :转换类型后输出的图像。• rtype :转换图像的数据类型。• alpha :转换过程中的缩放因子。• beta :转换过程中的偏置因子。
该函数用来实现将已有图像转换成指定数据类型的图像,第一个参数用于输出转换数据类型后的图像,第二个参数用于声明转换后图像的数据类型。第三个参数与第四个参数用于声明两个数据类型间的转换关系,具体转换形式如下图所示。
2.4 saturate_cast函数简单介绍
if(data<0)
data=0;
else if(data>255)
data=255;elsedata不变;
int a ,b ,c, d,f,e;
a = 100;
b = 200;
c = -200;
d = saturate_cast<uchar>(a + b);
f = saturate_cast<uchar>(c);
e = saturate_cast<uchar>(a);
cout << " d == " << d << " f == " << f <<" e == " << e << endl;
运行结果:
3. 多通道分离与合并
3.1 split()函数原型
void cv::split(const Mat & src, Mat * mvbegin )
void cv::split(InputArray m, OutputArrayOfArrays mv )
- src:待分离的多通道图像。
- mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同。
- m:待分离的多通道图像。
- mv:分离后的单通道图像,为向量(vector)形式。
该函数主要是用于将多通道的图像分离成若干单通道的图像,两个函数原型中不同之处在于, 前者第二个参数输出的是 Mat 类型的数组,其数组的长度需要与多通道图像的通道数相等并且提前 定义;第二种函数原型的第二个参数输出的是一个 vector<Mat>容器,不需要知道多通道图像的通道数。
3.2 多通道合并函数 merge()
void merge(const Mat* mv, size_t count, OutputArray dst);
void merge(const vector& mv, OutputArray dst );
mv(第一种重载原型参数):需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型。
count:输入的图像数组的长度,其数值必须大于 0。
mv(第二种重载原型参数):需要合并的图像向量(vector),其中每个图像必须拥有相同的尺寸和数据类型。
dst:合并后输出的图像,与 mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。
该函数主要用于将多个图像合并成一个多通道图像,该函数也具有两种不同的函数原型,每一种函数原型都与 split() 函数相对应,两种原型分别输入数组形式的图像数据和向量( vector )形式的图像数据,在输入数组形式数据的原型中,还需要输入数组的长度。合并函数的输出结果是一个多通道的图像,其通道数目是所有输入图像通道数目的总和。这里需要说明的是,用于合并的图像并非都是单通道的,也可以是多个通道数目不相同的图像合并成一个通道更多的图像。虽然这些图像的通道数目可以不相同,但是需要所有图像具有相同的尺寸和数据类型。
3.3 示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("../pic/hand.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat HSV;
cvtColor(img, HSV, COLOR_RGB2HSV);
Mat imgs0, imgs1, imgs2; //用于存放数组类型的结果
Mat imgv0, imgv1, imgv2; //用于存放 vector 类型的结果
Mat result0, result1, result2; //多通道合并的结果
//输入数组参数的多通道分离与合并
Mat imgs[3];
split(img, imgs);
imgs0 = imgs[0];
imgs1 = imgs[1];
imgs2 = imgs[2];
// imshow("RGB-B 通道", imgs0); //显示分离后 B 通道的像素值
// imshow("RGB-G 通道", imgs1); //显示分离后 G 通道的像素值
// imshow("RGB-R 通道", imgs2); //显示分离后 R 通道的像素值
//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); //用于还原 G 通道的真实情况,合并结果为绿色
imshow("result1", result1); //显示合并结果
//输入 vector 参数的多通道分离与合并
vector<Mat> imgv;
split(img, imgv);
// imgv0 = imgv.at(0);
// imgv1 = imgv.at(1);
// imgv2 = imgv.at(2);
// imshow("HSV-H 通道", imgv0); //显示分离后 H 通道的像素值
// imshow("HSV-S 通道", imgv1); //显示分离后 S 通道的像素值
// imshow("HSV-V 通道", imgv2); //显示分离后 V 通道的像素值
//imgv.push_back(HSV); //将 vector 中的图像通道数变成不一致
merge(imgv, result2); //合并图像
imshow("result2", result2); //imshow 最多显示 4 个通道,因此结果在 Image Watch 中查看
waitKey(0);
return 0;
}
3.4 运行结果