分離顏色通道&多通道圖像混合

【OpenCV入門教程之五】 分離顏色通道&多通道圖像混合

1. split 單通道顯示

// 分離顏色通道 split
void splitChannel() {
    Mat srcImage = imread("../pictures/bear.jpeg"); // 彩色圖像

    vector<Mat> channels;
    split(srcImage, channels);

    for (int i = 0; i < channels.size(); ++i) {
        Mat singleChannelImage = channels.at(i);
        namedWindow(color[i]);
        imshow(color[i], singleChannelImage);
    }
}
  • 單通道圖像沒有merge其它通道,就是一個灰度矩陣,所以呈現灰度圖
  • 由于 RGB值 不同,產生的灰度圖也不同
RGB -> Gray

2. merge 多通道圖像混合

  • 將 logo 圖像 merge 底圖藍色通道
  • logo 圖像 以灰度圖像模式 加載
// 多通道混合 merge
void multiChannelBlending() {

    // 1.讀入圖片
    Mat logoImage = imread("../pictures/logo.jpg", 0); // flags=0, 灰度圖像,GrayScale
    Mat srcImage = imread("../pictures/dota.jpg"); // 彩色圖像

    // 2.把一個3通道圖像轉換成3個單通道圖像
    vector<Mat> channels; // vector容器,元素類型:Mat
    split(srcImage, channels); // 分離色彩通道

    // 3.將原圖的 藍色通道引用 返回給imageBlueChannel
    // 注意是引用,相當于兩者等價,修改其中一個另一個跟著變
    Mat imageBlueChannel = channels.at(0); // RGB 對應 210

    // 4.原圖藍色通道ROI 與 logo圖 加權操作
    // imageBlueChannel是channels.at(0)的引用,所以原圖的這個值也跟著變化
    Mat srcBlueROI = imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)); // 選中的是原圖的藍色通道的這一塊區域

    // srcBlueROI 是藍色通道值
    // logo 是灰度圖像,也可以理解為單通道
    // logo 圖像按照灰度值呈現在藍色通道中,logoImage如果倍數很大,圖像會趨向純色
    addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);

    // 5.將三個單通道重新合并成一個三通道
    merge(channels, srcImage); // srcImage更新

    // 6.顯示效果圖
    namedWindow("blue");
    imshow("blue", srcImage);
}

融合參數

addWeighted(srcBlueROI, 1, logoImage, 1, 0, srcBlueROI);

調整 logoImage 權值為較大值(1000)會 趨于純色

因為 圖像的 RGB 存儲類型有上限

addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);

3. 源代碼

#include <cv.h>
#include <highgui.h>

using namespace cv;
using namespace std;

string color[3] = {"Blue", "Green", "Red"}; // 0, 1, 2

// 分離顏色通道 split
void splitChannel() {
    Mat srcImage = imread("../pictures/bear.jpeg"); // 彩色圖像

    vector<Mat> channels;
    split(srcImage, channels);

    for (int i = 0; i < channels.size(); ++i) {
        Mat singleChannelImage = channels.at(i);
        namedWindow(color[i]);
        imshow(color[i], singleChannelImage);
    }
}

// 多通道混合 merge
void multiChannelBlending() {

    // 1.讀入圖片
    Mat logoImage = imread("../pictures/logo.jpg", 0); // flags=0, 灰度圖像,GrayScale
    Mat srcImage = imread("../pictures/dota.jpg"); // 彩色圖像

    // 2.把一個3通道圖像轉換成3個單通道圖像
    vector<Mat> channels; // vector容器,元素類型:Mat
    split(srcImage, channels); // 分離色彩通道

    // 3.將原圖的 藍色通道引用 返回給imageBlueChannel
    // 注意是引用,相當于兩者等價,修改其中一個另一個跟著變
    Mat imageBlueChannel = channels.at(0); // RGB 對應 210

    // 4.原圖藍色通道ROI 與 logo圖 加權操作
    // imageBlueChannel是channels.at(0)的引用,所以原圖的這個值也跟著變化
    Mat srcBlueROI = imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)); // 選中的是原圖的藍色通道的這一塊區域

    // srcBlueROI 是藍色通道值
    // logo 是灰度圖像,也可以理解為單通道
    // logo 圖像按照灰度值呈現在藍色通道中,logoImage如果倍數很大,圖像會趨向純色
    addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);

    // 5.將三個單通道重新合并成一個三通道
    merge(channels, srcImage); // srcImage更新

    // 6.顯示效果圖
    namedWindow("blue");
    imshow("blue", srcImage);
}

int main() {
    splitChannel();
//    multiChannelBlending();
    waitKey(0);
    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容