生活中大多数看到的彩色图片都是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的频率。
=====================分割线==================