生活中大多数看到的彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图、HSV、HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能。
cvtColor函数
首先看一下cvtColor函数定义:
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
参数说明:
- src: 输入图像;
- dst: 输出图像;
- code: 颜色空间转换标识符;
- dstCn: 目标图像的通道数,该参数为0时,目标图像根据源图像的通道数和具体操作自动决定;
需要说明的是在opencv2.x时颜色空间转换code用的宏定义是CV_前缀开头,而在opencv3.x版本其颜色空间转换code宏定义更改为COLOR_开头,而经验证,2.4.13版本中opencv同时支持这两种形式的写法。故下面表格会将两种code类型同时列出,以供参考:
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
//1 变量定义
Mat srcImage, image_gray, image_hsc, image_lab;
//2 读取原始图像并检查图像是否读取成功
srcImage = imread("demo01.jpg");
if (srcImage.empty())
{
cout << "读取图像有误,请重新输入正确路径!" << endl;
return -1;
}
imshow("源图像srcImage",srcImage);//在窗口显示源图像
//3 源图像转为灰度图
//需要说明的是在opencv2.x时颜色空间转换code用的宏定义是CV_前缀开头,而在opencv3.x版本其颜色空间转换code宏定义更改为COLOR_开头
//void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
//cvtColor(srcImage,image_gray,CV_BGR2GRAY);
cvtColor(srcImage, image_gray, COLOR_BGR2GRAY);
imshow("灰度图image_gray",image_gray);
//4 源图像转为HSV颜色空间
cvtColor(srcImage,image_hsc,CV_BGR2HSV);
imshow("HSV颜色空间image_hsc", image_hsc);
//5 源图像转为Lab颜色空间
cvtColor(srcImage, image_lab, CV_BGR2Lab);
imshow("Lab颜色空间image_lab", image_lab);
//6 保持等待状态
waitKey(0);
return 0;
}
运行结果;
========================分割线=======================
在图像处理时,我们接触到的彩色以RGB居多,为了分析图像在某一通道上的特性,需要将图像的颜色通道进行分离,或者是在对某一颜色通道处理后重新进行融合。opencv提供了split()函数来进行颜色通道的分离,提供了merge()函数来进行颜色通道的融合。
1.split()函数
首先看一下split()函数定义:
void split(const Mat& m, vector<Mat>& mv );
参数说明:
- 第一个参数,const Mat&类型的src,填我们需要进行分离的图像;
- 第二个参数,vector<Mat>类型的mv,填函数的输出数组或者输出的vector容器,即分离后的图像;
========================分割线=======================
2.merge()函数
首先看一下merge()函数定义:
void merge(const vector<Mat>& mv, OutputArray dst );
参数说明:
- 第一个参数,const <Mat>类型的mv,填需要被合并的vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度;说白了就是前面被split()函数分离后的图像通道。
- 第二个参数,保存为合并后的图像;
========================分割线=======================
3.演示代码

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/*
此程序共显示9个窗口。
先将RGB图像通道分离,分别显示R、G、B、单个通道;
后将RGB颜色空间转为HSV空间,将HSV图像通道分离,分别显示H、S、V、单个通道;
最后将H、S、V、单个通道重新合并为3通道图像;
*/
int main()
{
//1 定义相关变量
Mat srcImage, newImage;//源图像,通道合并后的图像
Mat srcImage_B, srcImage_G, srcImage_R;//RGB各个通道
Mat image_H, image_S, image_V; //H S V各个通道
vector<Mat> channels_BGR; //vector<Mat> 可以理解为存放Mat类型的容器(数组)
vector<Mat> channels_HSV;
//2 读取原始图像并检查图像是否读取成功
srcImage = imread("demo01.jpg");
if (srcImage.empty())
{
cout << "读取图像错误,请重新输入正确路径" << endl;
return -1;
}
imshow("srcImage源图像",srcImage);//在窗口显示源图像
//3 对加载的源图像进行通道分离,即把一个3通道图像转换成3个单通道图像
split(srcImage,channels_BGR);
//0通道为B分量,1通道为G分量,2通道为R分量。因为:RGB色彩空间在opencv中默认通道顺序为BGR!!!
srcImage_B = channels_BGR.at(0);
srcImage_G = channels_BGR.at(1);
srcImage_R = channels_BGR.at(2);
//分别显示R G B各个通道图像
imshow("srcImage_B通道",srcImage_B);
imshow("srcImage_G通道", srcImage_G);
imshow("srcImage_R通道", srcImage_R);
//4 将BGR颜色空间转换为HSV颜色空间
Mat image_hsv;
cvtColor(srcImage,image_hsv,CV_BGR2HSV);
imshow("HSV颜色空间图像",image_hsv);
//5 对加载的HSV图像进行通道分离
split(image_hsv,channels_HSV);
//0通道为H分量,1通道为S分量,2通道为V分量
image_H = channels_HSV.at(0);
image_S = channels_HSV.at(1);
image_V = channels_HSV.at(2);
//分别显示H S V各个通道图像
imshow("image_H通道", image_H);
imshow("image_S通道", image_S);
imshow("image_V通道", image_V);
//6 将3个单通道重新合成一个三通道图像
merge(channels_HSV,newImage);
imshow("将H S V通道合并后的图像",newImage);
//7 保持等待状态
waitKey(0);
return 0;
}
======================分割线===============
有的时候,想知道要我们的程序一共运行了多长时间,这个很常用,也很简单,仅仅需要两个函数即可。
opencv里使用getTickCount()与getTickFrequency()函数记录时间;
函数解释:
getTickCount()函数:它返回从操作系统启动到当前所经的计时周期数。
getTickFrequency()函数:返回CPU的频率。
=====================分割线==================