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;
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐