1. 程式人生 > >OpenCV 中的split函式和merge函式 及示例

OpenCV 中的split函式和merge函式 及示例

就讓我們來詳細介紹一下這兩個互為冤家的函式。首先是進行通道分離的split函式。

<1>split函式詳解

將一個多通道陣列分離成幾個單通道陣列。ps:這裡的array按語境譯為陣列或者陣列。

這個split函式的C++版本有兩個原型,他們分別是:

C++: void split(const Mat& src, Mat*mvbegin);
C++: void split(InputArray m,OutputArrayOfArrays mv); 

關於變數介紹:

第一個引數,InputArray型別的m或者const Mat&型別的src,填我們需要進行分離的多通道陣列。

第二個引數,OutputArrayOfArrays型別的mv,填函式的輸出陣列或者輸出的vector容器。

<2>merge函式詳解

merge()函式的功能是split()函式的逆向操作,將多個數組組合合併成一個多通道的陣列。

它通過組合一些給定的單通道陣列,將這些孤立的單通道數組合併成一個多通道的陣列,從而創建出一個由多個單通道陣列組成的多通道陣列。它有兩個基於C++的函式原型:


C++: void merge(const Mat* mv, size_tcount, OutputArray dst)
C++: void merge(InputArrayOfArrays mv,OutputArray dst)
第一個引數,mv,填需要被合併的輸入矩陣或vector容器的陣列,這個mv引數中所有的矩陣必須有著一樣的尺寸和深度。

第二個引數,count,當mv為一個空白的C陣列時,代表輸入矩陣的個數,這個引數顯然必須大於1. 第三個引數,dst,即輸出矩陣,和mv[0]擁有一樣的尺寸和深度,並且通道的數量是矩陣陣列中的通道的總數。

函式解析:

merge函式的功能是將一些數組合併成一個多通道的陣列。關於組合的細節,輸出矩陣中的每個元素都將是輸出陣列的串接,其中,第i個輸入陣列的元素被視為mv[i]。 c一般用其中的Mat::at()方法對某個通道進行存取,也就是這樣用channels.at(0)。

PS: Mat::at()方法,返回一個引用到指定的陣列元素。注意是引用,相當於兩者等價,修改其中一個另一個跟著變。

at()與[]一樣,為下標索引。


綜合示例:
#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace cv;
using namespace std; 
int main()
{
	vector<Mat> channels;
	Mat imageBlueChannel;
	Mat imageGreenChannel;
	Mat imageRedChannel;
	Mat	srcImage4 = imread("C://1.jpg");
	// 把一個3通道影象轉換成3個單通道影象
	split(srcImage4, channels);//分離色彩通道
	imageBlueChannel = channels.at(0);
	imageGreenChannel = channels.at(1);
	imageRedChannel = channels.at(2);
	
	//三個分量R、G、B因為是單通道影象,所以只能顯示為灰度圖。
	//如果要想顯示出顏色來,應該用三通道影象來顯示,比如顯示R,我們就讓G和B通道的數值為0或255。
	//顯示彩色的B分量
	vector<Mat> mbgr(3);
	Mat bk1(srcImage4.size(), CV_8UC1, Scalar(0));   //畫素為0
	//表示了矩陣中元素的型別以及矩陣的通道個數,它是一系列的預定義的常量,其命名規則為CV_ + (位數)+(資料型別)+(通道數)。
	Mat imageB(srcImage4.size(), CV_8UC3);
	
	//顯示bgr三色影象中的blue通道  可以修改mbgr【1】或者mbgr【2】的值  
	mbgr[0] = channels[0];
	mbgr[1] = bk1;
	mbgr[2] = bk1;
	/*
	//顯示三通道影象原圖
	mbgr[0] = channels[0];
	mbgr[1] = channels[1];
	mbgr[2] = channels[2];
	*/
	merge(mbgr, imageB);
	imshow("imageB", imageB);
 
	waitKey();
	return 0;
}

上面的程式碼先做了相關的型別宣告,然後把載入的3通道影象轉換成3個單通道影象,放到vector<Mat>型別的channels中,接著進行引用賦值。

根據OpenCV的BGR色彩空間(bule,Green,Red,藍綠紅),其中channels.at(0)就表示引用取出channels中的藍色分量,channels.at(1)就表示引用取出channels中的綠色色分量,channels.at(2)就表示引用取出channels中的紅色分量。

一對做相反操作的plit()函式和merge()函式和用法就是這些了。另外提一點,如果我們需要從多通道陣列中提取出特定的單通道陣列,或者說實現一些複雜的通道組合,可以使用mixChannels()函式。

測試影象: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20181118203517649.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pxeDk1MTEwMg==,size_16,color_FFFFFF,t_70)

修改程式碼為:

mbgr[0] = bk1;
mbgr[1] = channels[1];
mbgr[2] = bk1;

在這裡插入圖片描述
把程式碼中的註釋去掉執行這個程式碼,就可以還原原圖了:

    mbgr[0] = channels[0];
	mbgr[1] = channels[1];
	mbgr[2] = channels[2];

在這裡插入圖片描述