OpenCV:获取 3 通道 RGB 图像,分割通道并仅使用 R+G 查看图像

Posted

技术标签:

【中文标题】OpenCV:获取 3 通道 RGB 图像,分割通道并仅使用 R+G 查看图像【英文标题】:OpenCV: Taking a 3 channel RGB image, splitting channels and viewing an image with only R+G 【发布时间】:2013-12-03 02:46:05 【问题描述】:

我只想查看 RGB 图像中的 R+G 通道,因为当蓝色通道被移除时,我可以获得更好的对比度来检测物体。我使用 OpenCV 拆分通道,但是在将蓝色通道设置为 0 后合并相同的通道时,我的代码无法编译。

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

using namespace cv;
using namespace std;

int main( int argc, char** argv )

    if( argc != 2)
    
     cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
     return -1;
    

    Mat image,fin_img;
    image = imread(argv[1], CV_LOAD_IMAGE_COLOR);   // Read the file

    if(! image.data )                              // Check for invalid input
    
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    

   namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
                      // Show our image inside it.

    // Create Windows
    namedWindow("Red",1);
    namedWindow("Green",1);
    namedWindow("Blue",1);

    // Create Matrices (make sure there is an image in input!)

    Mat channel[3];
    imshow( "Original Image", image ); 


    // The actual splitting.
    split(image, channel);


   channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0

    //Merging red and green channels

    merge(channel,image);
    imshow("R+G", image);

    waitKey(0);//Wait for a keystroke in the window
    return 0;

我可以对我哪里出错有任何反馈吗?我怀疑是将蓝色通道设置为 0。有没有更好的方法将其设置为 0?有没有办法使用 cvMixChannels() 来做到这一点?

【问题讨论】:

【参考方案1】:

你需要改变这些行

    channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0

    //Merging red and green channels
    merge(channel,image);

    channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0

    //Merging red and green channels
    merge(channel,3,image);

编辑

根据您的评论,这里是完整的代码和结果。

#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>    

using namespace cv;
using namespace std;

int main( int argc, char** argv )

    if( argc != 2)
    
     cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
     return -1;
    

    Mat image,fin_img;
    image = imread("bgr.png", CV_LOAD_IMAGE_COLOR);   // Read the file

    if(! image.data )                              // Check for invalid input
    
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    

   namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
                      // Show our image inside it.

    // Create Windows
    namedWindow("Red",1);
    namedWindow("Green",1);
    namedWindow("Blue",1);

    // Create Matrices (make sure there is an image in input!)

    Mat channel[3];
    imshow( "Original Image", image );


    // The actual splitting.
    split(image, channel);


   channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0

    //Merging red and green channels

    merge(channel,3,image);
    imshow("R+G", image);
    imwrite("dest.jpg",image);

    waitKey(0);//Wait for a keystroke in the window
    return 0;

源图片

没有蓝色成分的结果

【讨论】:

感谢 Haris 的反馈,我试过了,但在运行时遇到了分段错误。所以我决定尝试使用 mixChannels 的另一种方法,并且成功了。我可以分享代码:【参考方案2】:

好的,我开始使用 mixChannels():我在上面的代码 sn-p 中附加了一个补充:

Mat gr( image.rows, image.cols, CV_8UC3);

// forming an array of matrices is a quite efficient operation,
// because the matrix data is not copied, only the headers
   Mat out[] = gr;
// bgr[1] -> gr[1],
// bgr[2] -> gr[2], 
int from_to[] = 1,1, 2,2 ;
mixChannels( &image, 1, out, 2, from_to, 2 );

imshow("R+G",gr);

谢谢 哈沙

【讨论】:

【参考方案3】:

最有效的方法是不进行任何拆分和合并。这样既节省时间又节省内存。

只需将您的图像与cv::Scalar(0,255,255) 逐位与,这会将您的蓝色通道设置为零。

如:imshow("R+G", src &amp; cv::Scalar(0,255,255));

【讨论】:

【参考方案4】:

另一种方法是从源图像中减去Scalar(255,0,0)

#include <opencv2/opencv.hpp>
using namespace cv;

int main(int argc, char **argv)

    Mat src = imread(argv[1], CV_LOAD_IMAGE_COLOR);
    imshow("src", src );
    src -= Scalar(255,0,0);
    imshow("Green and Red channels", src );
    waitKey();
    return 0;

【讨论】:

以上是关于OpenCV:获取 3 通道 RGB 图像,分割通道并仅使用 R+G 查看图像的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV RGB直方图计算与绘制----calcHist()函数normalize()函数

想要从图像中获取绿色 RGB 通道时出错

openCV-python(六)图像操作——通道拆分与合并

opencv 图像基本操作 获取图像大小ROI操作通道分割与合并等

opencv 提取单通道 ,转化灰度图像。

在 python 中使用 OpenCV 分割图像