Разделение цветовых компонентов

0

Я следую этому сообщению, чтобы найти цветовые компоненты изображения. Я думал, что начну с красного компонента, а затем перейду к другим компонентам. Код, который я написал, приведен ниже. Я не использую Linux, я использую Windows.

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,image->nChannels);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            red=pImg[i*image->widthStep + j*image->nChannels + 2];
            pRed[i*image->widthStep + j*image->nChannels + 2]=red;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

Линии

red = pImg [i * image-> widthStep + j * image-> nChannels + 2];

pRed [i * image-> widthStep + j * image-> nChannels + 2] = красный;

показывают эту ошибку:

Значение типа uchar не может быть присвоено сущности типа IplImage

Где я иду не так?

  • 0
    Что вернет split ()? Например, у меня есть 2 квадрата на изображении, один красный, а другой синий. Теперь я хочу, чтобы вывод был таким, чтобы был виден только красный цвет. Будет ли split () делать это? Я действительно понятия не имею об этой функции. Не могли бы вы ответить и дать мне изображение, которое дало бы мне результат?
  • 0
    Извините, я удалил комментарий и дал ответ о том, как разделить каналы.
Теги:
opencv

3 ответа

3
Лучший ответ

Используйте C++:

cv::Mat myImage;
myImage=imread("myImage.jpg");
std::vector<cv::Mat> channels;
cv::split(myImage,channels);
imshow("Red Channel",channels[2]);
  • 0
    не могли бы вы опубликовать результат тоже, пожалуйста? И большое спасибо
0

red определяется здесь:

IplImage* red=cvCreateImage(...

Похоже, вы просто хотите индивидуальное значение цвета, поэтому вам нужно использовать новую переменную (я назвал ее redValue чтобы сделать ее менее запутанной)

    for(int j=0;j<image->width;j++)
    {
        uchar redValue=pImg[i*image->widthStep + j*image->nChannels + 2];
        pRed[i*image->widthStep + j*image->nChannels + 2]=redValue;
    }
  • 1
    вместо этого сделайте его uchar redValue чтобы не uchar redValue в заблуждение, если он хочет использовать это значение для чего-либо и интерпретировать его. Кроме того, если он не будет вынужден использовать IplImage, я бы посоветовал ему переключиться на cv::Mat как можно скорее.
  • 0
    Так как же тогда отобразить красный компонент?
-2

Во-первых: если вы не вынуждены использовать IplImage перейдите на cv::Mat потому что он намного проще использовать и понимать новый синтаксис openCV c++!

Для вашей проблемы: если вы хотите извлечь только красный канал (так, как вы это делаете, openCV может сделать это с вызовом функции для вашего), попробуйте этот код: я добавил комментарии, где я что-то изменил:

Я использую это как входное изображение для тестирования:

Изображение 174551

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    // !!! the image that shall contain the red channel must have number of channels = 1 !!!
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,1);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            // !!! you have to use a variable that holds the value of single channel pixel, which is uchar in this case (values from 0 to 255)
            uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2];
            // !!! since the red image has only 1 channel, be sure to use the right ->nChannels (from the 'red' image
            pRed[i*red->widthStep + j*red->nChannels]=redVal;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

Это должно отображать только красный канал как изображение в оттенках серого.

Результат выглядит так, как для входного изображения lena:

Изображение 174551

Если вы хотите отобразить его в RGB и отключить другие каналы, попробуйте это:

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    // !!! use 3 channels again because we want to display colors
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,3);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            // !!! you have to use a variable that holds the value of single channel pixel, which is uchar in this case (values from 0 to 255)
            uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2];
            // !!! set all channels to zero, except the red channel which is copied. be sure to use the right widthStep 
            pRed[i*red->widthStep + j*red->nChannels + 0]=0;
            pRed[i*red->widthStep + j*red->nChannels + 1]=0;
            pRed[i*red->widthStep + j*red->nChannels + 2]=redVal;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

Результат выглядит так для входного изображения lena:

Изображение 174551

  • 1
    Необработанное исключение в 0x000000013FA012F3 в Red.exe: 0xC0000005: Место записи нарушения прав доступа 0x000000000046E000. Это ошибка, и строка, которая ответственна за это: pRed [i image-> widthStep + j red-> nChannels + 2] = redVal; Вы уверены в этой программе?
  • 0
    Я редактировал его, pRed[i*image->widthStep + j*red->nChannels + 2]=redVal; было неправильно, потому что image->widthStep явно неправильно при доступе к элементам red . И поскольку у нас только один канал на красном изображении, +2 тоже был не прав :). Пришлось редактировать его во второй раз! Не могу проверить код, но эти два изменения должны сделать это, я думаю.
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню