Подтвердить что ты не робот

OpenCV: получение 3-канального изображения RGB, разделение каналов и просмотр изображения только с помощью R + G

Мне хотелось посмотреть только каналы R + G в RGB-изображении, потому что я лучше контрастирую с тем, чтобы обнаружить объект при удалении Blue-канала. Я использовал 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() для этого?

4b9b3361

Ответ 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);

Edit

В соответствии с вашим комментарием здесь приведен полный код и результат.

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

Исходное изображение

enter image description here

Результат без синего компонента

enter image description here

Ответ 2

Хорошо, я должен работать с использованием 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);

Спасибо Harsha

Ответ 3

Самый эффективный способ сделать это - без каких-либо разделов и слияний. Это экономит время и память.

Просто побитовое - и ваше изображение с cv::Scalar(0,255,255), и это установит ваш синий канал на ноль.

Как в: imshow("R+G", src & 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;
}