C++ OpenCV(六):多通道分离与合并

OpenCV 中 imread 函数载入的是 RGB 色彩空间的三通道彩色图像,通道顺序依次为 BGR。对于三通道图像 ,开发者可以使用 OpenCV 提供的函数实现通道的合并和分离。

彩色图片

分离

API

CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
  • 参数一:m,待分离的多通道图像;
  • 参数二:mv,分离后的单通道图像。

BGR 图像分离

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace std;

int main() {
    cout << CV_VERSION << endl;
    Mat src = cv::imread("../image/lena.tif", IMREAD_ANYCOLOR);
    if (src.empty()) {
        cout << "图片不存在" << endl;
        return -1;
    }

    vector<Mat> channels;
    Mat bChannel, gChannel, rChannel;
    split(src, channels);
    bChannel = channels[0];
    gChannel = channels[1];
    rChannel = channels[2];

    imshow("原图", src);
    imshow("Blue", bChannel);
    imshow("Green", gChannel);
    imshow("Red", rChannel);

    waitKey(0);
    return 0;
}

效果

单通道灰度图

官方示例

/**
 * @file core_split.cpp
 * @brief It demonstrates the usage of cv::split .
 *
 * It shows how to split a 3-channel matrix into a 3 single channel matrices.
 *
 * @author KUANG Fangjun
 * @date August 2017
 */

#include <iostream>
#include <opencv2/core.hpp>

using namespace std;
using namespace cv;

int main()
{
    //! [example]
    char d[] = {1,2,3,4,5,6,7,8,9,10,11,12};
    Mat m(2, 2, CV_8UC3, d);
    Mat channels[3];
    split(m, channels);

    /*
    channels[0] =
    [  1,   4;
       7,  10]
    channels[1] =
    [  2,   5;
       8,  11]
    channels[2] =
    [  3,   6;
       9,  12]
    */
    //! [example]

    return 0;
}

配合 OpenCV Image Viewer 查看对应位置的数值,更易于理解。

合并

API

CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
  • 参数一:mv,需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型;
  • 参数二:dst,合并后输出的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。

示例

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace std;

int main() {
    cout << CV_VERSION << endl;
    Mat src = cv::imread("../image/lena.tif", IMREAD_ANYCOLOR);
    if (src.empty()) {
        cout << "图片不存在" << endl;
        return -1;
    }

    vector<Mat> channels;
    Mat bChannel, gChannel, rChannel;
    split(src, channels);

    // B通道清零
    channels[0] = Mat::zeros(src.rows, src.cols, channels[0].type());

    Mat dst;
    merge(channels, dst);
    imshow("合并", dst);

    waitKey(0);
    return 0;
}

效果

B通道清零

官方示例

#include <iostream>
#include <opencv2/core.hpp>

using namespace std;
using namespace cv;

int main()
{
    //! [example]
    Mat m1 = (Mat_<uchar>(2,2) << 1,4,7,10);
    Mat m2 = (Mat_<uchar>(2,2) << 2,5,8,11);
    Mat m3 = (Mat_<uchar>(2,2) << 3,6,9,12);

    Mat channels[3] = {m1, m2, m3};
    Mat m;
    merge(channels, 3, m);
    /*
    m =
    [  1,   2,   3,   4,   5,   6;
       7,   8,   9,  10,  11,  12]
    m.channels() = 3
    */
    //! [example]

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndroidKt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值