OpenCV:采用3通道RGB图像,分割通道,仅用R+G查看图像。

时间:2021-05-28 21:21:49

I wanted to look at only the R+G channels in an RGB image because I get better contrasts to detect an object when the Blue channel is removed. I used OpenCV to split the channels,but while merging the same after setting the blue channel to 0, my code doesn't compile.

我想只看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;
}

Could I have any feedback on where I'm going wrong? I suspect it is with setting the blue channel to 0. Is there any better way to set it to 0?Is there a way to use cvMixChannels() to do this?

我能对我的错误有任何反馈吗?我怀疑是将蓝色通道设置为0。有没有更好的方法把它设为0?是否有办法使用cvmixchannel()来完成这个任务?

4 个解决方案

#1


30  

You need to change these lines

你需要改变这些线条。

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

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

to

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

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

Edit

编辑

As per your comment here is the full code and result.

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

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

Source image

源图像

OpenCV:采用3通道RGB图像,分割通道,仅用R+G查看图像。

Result without blue component

结果没有蓝色的组件

OpenCV:采用3通道RGB图像,分割通道,仅用R+G查看图像。

#2


6  

Alright, I got to work using mixChannels():I have attached an addition to the code snippet above:

好的,我开始使用mixChannels():我已经附加了上面的代码片段:

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);

Thanks Harsha

由于Harsha

#3


6  

The most efficient way to do this is without any splits and merges. This saves both time and memory.

最有效的方法是没有任何拆分和合并。这节省了时间和内存。

Just bitwise-AND your image with cv::Scalar(0,255,255) and this will set your blue channel to zero.

只有bitwise-和你的简历的图像::标量(0,255,255),这将把你的蓝色通道设置为零。

As in: imshow("R+G", src & cv::Scalar(0,255,255));.

如:imshow(“R + G”,src和简历::标量(0255255));。

#4


4  

another way is subtracting Scalar(255,0,0) from source image

另一种方法是从源图像中减去标量(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;
}

#1


30  

You need to change these lines

你需要改变这些线条。

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

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

to

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

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

Edit

编辑

As per your comment here is the full code and result.

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

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

Source image

源图像

OpenCV:采用3通道RGB图像,分割通道,仅用R+G查看图像。

Result without blue component

结果没有蓝色的组件

OpenCV:采用3通道RGB图像,分割通道,仅用R+G查看图像。

#2


6  

Alright, I got to work using mixChannels():I have attached an addition to the code snippet above:

好的,我开始使用mixChannels():我已经附加了上面的代码片段:

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);

Thanks Harsha

由于Harsha

#3


6  

The most efficient way to do this is without any splits and merges. This saves both time and memory.

最有效的方法是没有任何拆分和合并。这节省了时间和内存。

Just bitwise-AND your image with cv::Scalar(0,255,255) and this will set your blue channel to zero.

只有bitwise-和你的简历的图像::标量(0,255,255),这将把你的蓝色通道设置为零。

As in: imshow("R+G", src & cv::Scalar(0,255,255));.

如:imshow(“R + G”,src和简历::标量(0255255));。

#4


4  

another way is subtracting Scalar(255,0,0) from source image

另一种方法是从源图像中减去标量(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;
}