CV

分离颜色通道&多通道图像混合

2017-07-12  本文已影响52人  谢小帅

【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);
    }
}
RGB -> Gray

2. merge 多通道图像混合

// 多通道混合 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;
}
上一篇下一篇

猜你喜欢

热点阅读