一、概論
在圖像顏色模型中不同的分量存放在不同的通道中,如果我們只需要顏色模型的某一個(gè)分量,例如只需要處理RGB圖像中的紅色通道,可以將紅色通道從三通道的數(shù)據(jù)中分離出來再進(jìn)行處理,這種方式可以減少數(shù)據(jù)所占據(jù)的內(nèi)存,加快程序的運(yùn)行速度。同時(shí),當(dāng)我們分別處理完多個(gè)通道后,需要將所有通道合并在一起重新生成RGB圖像。針對(duì)圖像多通道的分離與混合,OpenCV 4中提供了split()函數(shù)和merge()函數(shù)用于解決這些需求。
opencv知識(shí)點(diǎn):
- 通道分離 - split() 通道合并
- merge() 通道混合
- mixChannels()
二、多通道分離函數(shù)split()
OpenCV 4中針對(duì)多通道分離函數(shù)split()有兩種重載原型,在代碼清單3-4中給出了這兩種函數(shù)原型。
void cv::split(const Mat & src,
Mat * mvbegin
)
void cv::split(InputArray m,
OutputArrayOfArrays mv
)
src:待分離的多通道圖像。
mvbegin:分離后的單通道圖像,為數(shù)組形式,數(shù)組大小需要與圖像的通道數(shù)相同
m:待分離的多通道圖像
mv:分離后的單通道圖像,為向量vector形式
該函數(shù)主要是用于將多通道的圖像分離成若干單通道的圖像,兩個(gè)函數(shù)原型中不同之處在于前者第二個(gè)參數(shù)輸入的是Mat類型的數(shù)組,其數(shù)組的長度需要與多通道圖像的通道數(shù)相等并且提前定義;第二種函數(shù)原型的第二個(gè)參數(shù)輸入的是一個(gè)vector容器,不需要知道多通道圖像的通道數(shù)。兩個(gè)函數(shù)原型雖然輸入?yún)?shù)的類型不同,但是通道分離的原理是相同的,可以用公式(3.4)表示。
三、多通道合并函數(shù)merge()
OpenCV 4中針對(duì)多通道合并函數(shù)merge()也有兩種重載原型,在代碼清單3-5中給出了兩種原型。多通道合并函數(shù)merge()
OpenCV 4中針對(duì)多通道合并函數(shù)merge()也有兩種重載原型,在代碼清單3-5中給出了兩種原型。
void cv::merge(const Mat * mv,
size_t count,
OutputArray dst
)
void cv::merge(InputArrayOfArrays mv,
OutputArray dst
)
mv:需要合并的圖像數(shù)組,其中每個(gè)圖像必須擁有相同的尺寸和數(shù)據(jù)類型。
count:輸入的圖像數(shù)組的長度,其數(shù)值必須大于0.
mv:需要合并的圖像向量vector,其中每個(gè)圖像必須擁有相同的尺寸和數(shù)據(jù)類型。
dst:合并后輸出的圖像,與mv[0]具有相同的尺寸和數(shù)據(jù)類型,通道數(shù)等于所有輸入圖像的通道數(shù)總和。
該函數(shù)主要是用于將多個(gè)圖像合并成一個(gè)多通道圖像,該函數(shù)也具有兩種不同的函數(shù)原型,每一種函數(shù)原型都是與split()函數(shù)相對(duì)應(yīng),兩種原型分別輸入數(shù)組形式的圖像數(shù)據(jù)和向量vector形式的圖像數(shù)據(jù),在輸入數(shù)組形式數(shù)據(jù)的原型中,還需要輸入數(shù)組的長度。合并函數(shù)的輸出結(jié)果是一個(gè)多通道的圖像,其通道數(shù)目是所有輸入圖像通道數(shù)目的總和。這里需要說明的是,用于合并的圖像并非都是單通道的,也可以是多個(gè)通道數(shù)目不相同的圖像合并成一個(gè)通道更多的圖像,雖然這些圖像的通道數(shù)目可以不相同,但是需要所有圖像具有相同的尺寸和數(shù)據(jù)類型
//函數(shù)定義
void channels_demo(Mat& image);
//函數(shù)實(shí)現(xiàn)—
void QuickDemo::channels_demo(Mat& image) {
Mat mvt[3];
/*
第一種方式
通過創(chuàng)建圖像數(shù)組,存儲(chǔ)每個(gè)單通道圖像
*/
split(image, mvt);
imshow("藍(lán)色單通道", mvt[0]);
imshow("綠色單通道", mvt[1]);
imshow("藍(lán)色單通道", mvt[2]);
}
void QuickDemo::channels_demo(Mat& image) {
std::vector<Mat> mvt;
/*
第二種方式
通過創(chuàng)建動(dòng)態(tài)數(shù)組,存儲(chǔ)每個(gè)單通道圖像
*/
split(image, mvt);
imshow("藍(lán)色單通道", mvt[0]);
imshow("綠色單通道", mvt[1]);
imshow("紅色單通道", mvt[2]);
}
這里我們進(jìn)行一個(gè)演示,實(shí)現(xiàn)如下通道的混合
0通道→2通道
1通道不變
2通道→1通道
這個(gè)混合的意思是,彩色圖像本來是bgr的順序,經(jīng)過通道混合就變成了rgb。
0通道的單通道圖像,變成了2通道的單通道圖像
1通道不變
2通道的單通道圖像,變成了0通道的單通道圖像
void QuickDemo::channels_demo(Mat& image) {
Mat dst = Mat::zeros(image.size(), image.type());
int from_to[] = { 0,2,1,1,2,0 };
mixChannels(&image, 1, &dst, 1, from_to, 3);
imshow("通道混合",dst);
}
Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
// forming an array of matrices is a quite efficient operation,
// because the matrix data is not copied, only the headers
Mat out[] = { bgr, alpha };
// bgra[0] -> bgr[2], bgra[1] -> bgr[1],
// bgra[2] -> bgr[0], bgra[3] -> alpha[0]
int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
mixChannels( &bgra, 1, out, 2, from_to, 4 );
四、圖像多通道分離與合并例程
為了使讀者更加熟悉圖像多通道分離與合并的操作,同時(shí)加深對(duì)圖像不同通道作用的理解,在代碼清單3-6中實(shí)現(xiàn)了圖像的多通道分離與合并的功能。程序中用兩種函數(shù)原型分別分離了RGB圖像和HSV圖像,為了驗(yàn)證merge ()函數(shù)可以合并多個(gè)通道不相同的圖像,程序中分別用兩種函數(shù)原型合并了多個(gè)不同通道的圖像,合并后圖像的通道數(shù)為5,不能通過imshow()函數(shù)顯示,我們用Image Watch插件查看了合并的結(jié)果。由于RGB三個(gè)通道分離結(jié)果顯示時(shí)都是灰色且相差不大,因此圖3-5沒有給出其分離后的結(jié)果,只給出合并后顯示為綠色的合并圖像,同時(shí)給出HSV分離結(jié)果,其他結(jié)果讀者可以自行運(yùn)行程序查看。文章來源:http://www.zghlxwxcb.cn/news/detail-491109.html
void QuickDemo::channels_demo(Mat& image) {
Mat mvt[3];
split(image, mvt);
imshow("藍(lán)色單通道", mvt[0]);
imshow("綠色單通道", mvt[1]);
imshow("紅色單通道", mvt[2]);
Mat dst;
merge(mvt,3,dst);
/*
這里的3指,共有3個(gè)單通道圖像
*/
imshow("分離再合并",dst);
}
void QuickDemo::channels_demo(Mat& image) {
std::vector<Mat> mvt;
split(image, mvt);
imshow("藍(lán)色單通道", mvt[0]);
imshow("綠色單通道", mvt[1]);
imshow("紅色單通道", mvt[2]);
Mat dst;
merge(mvt, dst);
imshow("分離再合并",dst);
}
#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
cout<<"OpenCv Version: "<<CV_VERSION<<endl;
Mat img=imread("/home/wyh/Documents/C++demo/699342568.jpg");
if(img.empty()){
cout<<"請(qǐng)確認(rèn)輸入圖片的名稱是否正確"<<endl;
return -1;
}
Mat HSV,dst;
resize(img,dst,Size(img.cols*0.5,img.rows*0.5));
cvtColor(dst,HSV,COLOR_BGR2HSV);
Mat imgs0,imgs1,imgs2;//用于存放數(shù)組類型的結(jié)果
Mat imgv0,imgv1,imgv2;//用于存放vector類型的結(jié)果
Mat result0,result1,result2;//多通道合并的結(jié)果
//輸入數(shù)組參數(shù)的多通道分離與合并
Mat imgs[3];
split(dst,imgs);
imgs0=imgs[0];
imgs1=imgs[1];
imgs2=imgs[2];
imshow("RGB-R通道",imgs0);//顯示分離后R通道的像素值
imshow("RGB-G通道",imgs1);//顯示分離后G通道的像素值
imshow("RGB-B通道",imgs2);//顯示分離后B通道的像素值
imgs[2]=dst;//將數(shù)組中的圖像通道數(shù)變成不統(tǒng)一
merge(imgs,3,result0);//合并圖像
Mat zero=Mat::zeros(dst.rows,dst.cols,CV_8UC1);
imgs[0]=zero;
imgs[2]=zero;
merge(imgs,3,result1);//用于還原G通道的真實(shí)情況,合并結(jié)果為綠色
imshow("result1",result1);//顯示合并結(jié)果
//輸入vector參數(shù)的多通道分離與合并
vector<Mat>imgv;
split(HSV,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中的圖像通道數(shù)變成不統(tǒng)一
merge(imgv,result2);//合并圖像
waitKey(0);
return 0;
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-491109.html
到了這里,關(guān)于Opencv-C++筆記 (9) : opencv-多通道分離和合并的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!