https://blog.csdn.net/ZYTTAE/article/details/42234989

由于算法的需要,需要把彩色图像的R、G、B值分离出来,OpenCV中正好有split() 和 merge() 函数可以实现。

一、对单独彩色图片的RGB通道分离:

#include <iostream>
#include "cv.h"
#include "highgui.h" using namespace std;
using namespace cv; int main(int argc,char* argv[])
{
Mat img = imread("lena.jpg"/*,CV_LOAD_IMAGE_COLOR*/);
Mat channel[3];
split(img,channel);
imshow("original",img);
imshow("B",channel[0]);
imshow("G",channel[1]);
imshow("R",channel[2]); //set blue channel to 0
channel[0] = Mat::zeros(img.rows,img.cols,CV_8UC1);
//merge red and green channels
merge(channel,3,img);
imshow("R_G_merge",img); waitKey(0);
return 1;
}

  

二、对摄像头摄入视频帧的RGB彩色通道分离

int main(int argc,char* argv[])
{
VideoCapture cap;
cap.open(0); if(!cap.isOpened())
{
exit(0);
} cap.set(CV_CAP_PROP_FRAME_WIDTH,250);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,250); cout << "Frame Width: " << cap.get(CV_CAP_PROP_FRAME_WIDTH) << endl;
cout << "Frame Height: " << cap.get(CV_CAP_PROP_FRAME_HEIGHT) << endl; Mat frame;
vector<Mat> rgb;
cap >> frame; //rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1)); namedWindow("original", 1);
namedWindow("red", 1);
namedWindow("green", 1);
namedWindow("blue", 1); for(;;)
{
cap >> frame;
imshow("original", frame);
split(frame, rgb); imshow("red", rgb.at(2));
imshow("green", rgb.at(1));
imshow("blue", rgb.at(0)); if(waitKey(30) >= 0)
break;
} waitKey(0);
return 1;
}

  

1.split()函数

此函数的作用是将一个图像通道进行分离。
首先看一下split()函数定义:

void split(const Mat& m, vector<Mat>& mv );

参数说明:

第一个参数,const Mat&类型的src,填我们需要进行分离的图像;
第二个参数,vector<Mat>类型的mv,填函数的输出数组或者输出的vector容器,即分离后的图像;

2.merge()函数
merge()函数的功能是split()函数的逆向操作,将多个数组合并成一个多通道的数组。
首先看一下merge()函数定义:

void merge(const vector<Mat>& mv, OutputArray dst );

参数说明:

第一个参数,const <Mat>类型的mv,填需要被合并的vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度;说白了就是前面被split()函数分离后的图像通道。
第二个参数,保存为合并后的图像;

#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()
{
//【0】定义相关变量
Mat srcImage, newImage; //源图像、通道合并后的图像
Mat srcImage_B, srcImage_G, srcImage_R; //R、G、B各个通道
Mat image_H, image_S, image_V; //H、S、V各个通道
vector<Mat> channels_BGR; //vector<Mat>: 可以理解为存放Mat类型的容器(数组)
vector<Mat> channels_HSV;
//【1】读取原始图像并检查图像是否读取成功
srcImage = imread("D:\\OutPutResult\\ImageTest\\adog.jpg"); //请修改为自己的图像路径
if (srcImage.empty())
{
cout << "读取图像有误,请重新输入正确路径!\n";
return -1;
}
imshow("srcImage源图像", srcImage); //在窗口显示源图像 //【2】对加载的原图像进行通道分离,即把一个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);
imshow("srcImage_B通道", srcImage_B); //分别显示R,G,B各个通道图像
imshow("srcImage_G通道", srcImage_G);
imshow("srcImage_R通道", srcImage_R); //【3】将BGR颜色空间转换为HSV颜色空间
Mat image_hsv;
cvtColor(srcImage, image_hsv, CV_BGR2HSV);
imshow("HSV颜色空间图像", image_hsv); //【4】对加载的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);
imshow("image_H通道", image_H);//分别显示H,S,V各个通道图像
imshow("image_S通道", image_S);
imshow("image_V通道", image_V); //【5】将3个单通道重新合并成一个三通道图像
merge(channels_HSV, newImage);
imshow("将H,S,V通道合并后的图像", newImage); //【6】保持等待状态
waitKey(0);
return 0;
}

  

5.程序说明

看到这里,可能有人会问为什么分离出的通道都是黑白灰,而不是红绿蓝?

原因是分离后为单通道,相当于分离通道的同时把其他两个通道填充了相同的数值。比如红色通道,分离出红色通道的同时,绿色和蓝色被填充为和红色相同的数值,这样一来就只有黑白灰了。那么红色体现在哪呢?可以进行观察,会发现原图中颜色越接近红色的地方在红色通道越接近白色。

====================分割线===============

此程序共显示9个窗口。

先将RGB图像通道分离,分别显示R、G、B、单个通道;

后将RGB颜色空间转为HSV空间,将HSV图像通道分离,分别显示H、S、V、单个通道;

最后将H、S、V、单个通道重新合并为3通道图像;

=========================END======================

  

OpenCV 学习笔记(8)彩色图像RGB通道的分离、合并与显示的更多相关文章

  1. OpenCV 学习笔记(16)open创建无边框的显示窗口

    https://blog.csdn.net/weixin_41794771/article/details/93198098 讲解地址 // 1获取窗口句柄 winName 窗口名字 HWND win ...

  2. opencv学习笔记D01

    目录 opencv学习笔记D01 一.图片读取 二.图片保存 三.图片展示 四.图片缩放 五.四种常用插值方式的比较 1.最近邻插值 2.双线性插值 3.区域插值 4.三次样条插值 我是尾巴: ope ...

  3. opencv学习笔记(一)IplImage, CvMat, Mat 的关系

    opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...

  4. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...

  5. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

  6. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  7. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  8. opencv学习笔记(四)投影

    opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: #include <cv.h> #include <highgui.h> using namespace ...

  9. opencv学习笔记(二)寻找轮廓

    opencv学习笔记(二)寻找轮廓 opencv中使用findContours函数来查找轮廓,这个函数的原型为: void findContours(InputOutputArray image, O ...

随机推荐

  1. 移相器——K波段有源移相器设计

    博主之前在做一款K波段有源移相器,所用工艺为smic55nmll工艺,完成了几个主要模块的仿真,现对之前的工作做个总结. K波段的频率范围是18G——27GHz,所设计移相器的工作频率范围是19G—— ...

  2. 微信小程序:防止多次点击跳转(函数节流)

    场景 在使用小程序的时候会出现这样一种情况:当网络条件差或卡顿的情况下,使用者会认为点击无效而进行多次点击,最后出现多次跳转页面的情况,就像下图(快速点击了两次): 解决办法 然后从 轻松理解JS函数 ...

  3. Replication:distribution 中一直在运行 waitfor delay @strdelaytime 语句

    Replication 自动创建来一个 Job:Replication monitoring refresher for distribution,这个Agent执行一个sp: dbo.sp_repl ...

  4. SQL怎么实现SLEEP功能(等待时间) -(转载)

    语法格式: WAITFOR DELAY N'小时数:分钟数:秒数.毫秒数' 等待100毫秒: SELECT GETDATE() WAITFOR DELAY N'00:00:00.100' SELECT ...

  5. 一个简单便捷的树形显示Ztree

    这是本人在闲时研究的一个用于显示树形列表的小玩意. zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 下面就说说怎么用吧 ...

  6. ajax 执行成功以后返回的数据走的是error方法而不是success方法的问题

    今天在一个功能的时候发现写的ajax的方法执行后台代码成功后返回前台时执行的是error方法而不是success方法,代码如下 jQuery('#form').ajaxSubmit({ type: & ...

  7. 两数相加(C#数据结构和算法练习)

    两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  8. [個人紀錄] git 設定

    -- git history git config --global alias.history=log --graph --all --pretty=format:'%C(bold blue)%H% ...

  9. CMPP服务端源码

    CMPP服务端,带数据库,可以接收第三方CMPP客户端的短信,并存入数据库,结合我的cmpp客户端服务程序,将可以实现接收第三方SP的短信并转发到网关实现发送,并将状态报告.上行短信转发给第三方SP, ...

  10. asp.net core MVC 过滤器之ExceptionFilter过滤器(一)

    简介 异常过滤器,顾名思义,就是当程序发生异常时所使用的过滤器.用于在系统出现未捕获异常时的处理. 实现一个自定义异常过滤器 自定义一个异常过滤器需要实现IExceptionFilter接口 publ ...