praxmon
praxmon

Reputation: 5121

Separating color components

I am following this post to find the colour components of an image. I thought I'll start with the red component and then proceed towards other components. The code that I have written is given below. I am not using Linux, I am using 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;
}

The lines

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

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

are showing this error:

A value of type uchar cannot be assigned to an entity of the type IplImage

Where am I going wrong?

Upvotes: 1

Views: 1433

Answers (3)

LovaBill
LovaBill

Reputation: 5139

Use C++:

cv::Mat myImage;
myImage=imread("myImage.jpg");
std::vector<cv::Mat> channels;
cv::split(myImage,channels);
imshow("Red Channel",channels[2]);

Upvotes: 4

Micka
Micka

Reputation: 20130

First: If you aren't forced to use IplImage please switch to cv::Matbecause it's so much easier to use and understand the new c++ syntax of openCV!

For your problem: if you want to extract just the red channel (manually like you do it, openCV could do it with a function call for your), try this code: I've added comments where I changed something:

I use this as an input image for testing:

enter image description here

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

This should display just the red channel as a grayscale image.

The result looks like this for a lena input image:

enter image description here

If you want to display it in RGB and shut off the other channels try this:

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

The result looks like this for lena input image:

enter image description here

Upvotes: -1

benjymous
benjymous

Reputation: 2122

red is defined here:

IplImage* red=cvCreateImage(...

It looks like you just want an individual colour value, so you need to use a new variable (I named it redValue to make it less confusing)

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

Upvotes: 0

Related Questions