OpenCV: Taking a 3 channel RGB image, splitting channels and viewing an image with only R+G

前端 未结 4 2022
走了就别回头了
走了就别回头了 2020-12-14 07:26

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 cha

相关标签:
4条回答
  • 2020-12-14 08:06

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

    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

    0 讨论(0)
  • 2020-12-14 08:09

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

    #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;
    }
    
    0 讨论(0)
  • 2020-12-14 08:10

    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

    enter image description here

    Result without blue component

    enter image description here

    0 讨论(0)
  • 2020-12-14 08:23

    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.

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

    0 讨论(0)
提交回复
热议问题