1. 程式人生 > >基於openCV3的顏色通道分離及多通道影象混合

基於openCV3的顏色通道分離及多通道影象混合

注:文件摘至《OpenCV3程式設計入門》毛星雲版
<1>通道分離: split()函式
split函式用於將一個多通道陣列分離成幾個單通道陣列。這裡的array 按語境翻譯為陣列或者陣列。split函式的C++版本有兩個原型, 分別是:
• c ++: void split( const Mat& src, Mat*mvbegin);
• C++ : void split(InputArray m ,Outpu從nayOfArrays mv);
變數介紹如下:
· 第一個引數, InputArray 型別的m 或者const Mat&型別的src ,填我們需要進行分離的多通道陣列。
· 第二個引數, OutputArrayOfArrays 型別的mv , 填函式的輸出陣列或者輸出
的vector 容器。
split 函式分割多通道陣列轉換成獨立的單通道陣列,公式如下:
mv[c] (I)= src(I )c

<2>通道合併: merge()函式
merge() 函式是split() 函式的逆向操作將多個數組合併成一個多通道的陣列。它通過組合一些給定的單通道陣列,將這些孤立的單通道數組合併成一個多通道的陣列,從而創建出一個由多個單通道陣列組成的多通道陣列。它有兩個基於C十+的函式原型如下。
• C++: void merge(const Mat* mv, size_tcount, Ou陽山rray dst)
• C++: void merge( In putArrayO隊rrays mv,OutputArray dst)
變數介紹如下。
· 第一個引數, mv 。填需要被合井的輸入矩陣或vector 容器的陣列,這個mv 引數中所有的矩陣必須有著一樣的尺寸和深度。
· 第二個引數, count。 當mv 為一個空白的C 陣列時,代表輸入矩陣的個數,這個引數顯然必須大於1。
· 第三個引數, dst。即輸出矩陣,和mv[0]擁有一樣的尺寸和深度,井且通道的數量是矩陣陣列中的通道的總數。
函式解析如下。
merge 函式的功能是將一些數組合併成一個多通道的陣列。關於組合的細節,輸出矩陣中的每個元素都將是輸出陣列的串接。其中, 第i 個輸入陣列的元素被視為mv[i] 。 C 一般用其中的Mat: :at()方法對某個通道進行存取,也就是這樣用:channels.at(0) 。
這裡的Mat: :at()方法返回一個引用到指定的陣列元素。注意是引用,相當於兩者等價,也就是修改其中一個,另一個也會隨之改變。
<例項>
標頭檔案包含及名稱空間

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;

實現多通道的影象混合

bool  MultiChannelBlending()
{
    //【0】定義相關變數
    Mat srcImage;
    Mat logoImage;
    vector<Mat> channels;
    Mat  imageBlueChannel;

    //=================【藍色通道部分】=================
// 描述:多通道混合-藍色分量部分 //============================================ // 【1】讀入圖片 logoImage= imread("dota_logo.jpg",0); srcImage= imread("dota_jugg.jpg"); if( !logoImage.data ) { printf("Oh,no,讀取logoImage錯誤~! \n"); return false; } if( !srcImage.data ) { printf("Oh,no,讀取srcImage錯誤~! \n"); return false; } //【2】把一個3通道影象轉換成3個單通道影象 split(srcImage,channels);//分離色彩通道 //【3】將原圖的藍色通道引用返回給imageBlueChannel,注意是引用,相當於兩者等價,修改其中一個另一個跟著變 imageBlueChannel= channels.at(0); //【4】將原圖的藍色通道的(500,250)座標處右下方的一塊區域和logo圖進行加權操作,將得到的混合結果存到imageBlueChannel中 addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows))); //【5】將三個單通道重新合併成一個三通道 merge(channels,srcImage); //【6】顯示效果圖 namedWindow(" <1>遊戲原畫+logo藍色通道"); imshow(" <1>遊戲原畫+logo藍色通道",srcImage); //=================【綠色通道部分】================= // 描述:多通道混合-綠色分量部分 //============================================ //【0】定義相關變數 Mat imageGreenChannel; //【1】重新讀入圖片 logoImage= imread("dota_logo.jpg",0); srcImage= imread("dota_jugg.jpg"); if( !logoImage.data ) { printf("讀取logoImage錯誤~! \n"); return false; } if( !srcImage.data ) { printf("讀取srcImage錯誤~! \n"); return false; } //【2】將一個三通道影象轉換成三個單通道影象 split(srcImage,channels);//分離色彩通道 //【3】將原圖的綠色通道的引用返回給imageBlueChannel,注意是引用,相當於兩者等價,修改其中一個另一個跟著變 imageGreenChannel= channels.at(1); //【4】將原圖的綠色通道的(500,250)座標處右下方的一塊區域和logo圖進行加權操作,將得到的混合結果存到imageGreenChannel中 addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows))); //【5】將三個獨立的單通道重新合併成一個三通道 merge(channels,srcImage); //【6】顯示效果圖 namedWindow("<2>遊戲原畫+logo綠色通道"); imshow("<2>遊戲原畫+logo綠色通道",srcImage); //=================【紅色通道部分】================= // 描述:多通道混合-紅色分量部分 //============================================ //【0】定義相關變數 Mat imageRedChannel; //【1】重新讀入圖片 logoImage= imread("dota_logo.jpg",0); srcImage= imread("dota_jugg.jpg"); if( !logoImage.data ) { printf("Oh,no,讀取logoImage錯誤~! \n"); return false; } if( !srcImage.data ) { printf("Oh,no,讀取srcImage錯誤~! \n"); return false; } //【2】將一個三通道影象轉換成三個單通道影象 split(srcImage,channels);//分離色彩通道 //【3】將原圖的紅色通道引用返回給imageBlueChannel,注意是引用,相當於兩者等價,修改其中一個另一個跟著變 imageRedChannel= channels.at(2); //【4】將原圖的紅色通道的(500,250)座標處右下方的一塊區域和logo圖進行加權操作,將得到的混合結果存到imageRedChannel中 addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows))); //【5】將三個獨立的單通道重新合併成一個三通道 merge(channels,srcImage); //【6】顯示效果圖 namedWindow("<3>遊戲原畫+logo紅色通道 "); imshow("<3>遊戲原畫+logo紅色通道 ",srcImage); return true; }

測試一下

int main(   )
{
    system("color 9F");
    if(MultiChannelBlending( ))
    {
        cout<<endl<<"\n執行成功,得出了需要的影象~! ";
    }
    waitKey(0);
    return 0;
}

效果圖如下:

這裡寫圖片描述

這裡寫圖片描述