Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm going to identify currency notes base on color.I used histogram for this.I could identify only R,G,B values.How can i detect yellow and brown color.This is what i'm done so far.are there any other methods to detect color with out going for histogram.

C#
#include "stdafx.h"
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <cxcore.h>

int _tmain(int argc, _TCHAR* argv[])
{
IplImage* img  = cvLoadImage("500.jpg");


 if( !img )
   return -1;

 IplImage* channel = cvCreateImage( cvGetSize(img), 8, 1 );
 IplImage *hist_img = cvCreateImage(cvSize(300,240), 8, 3);
  IplImage *hist_imgfinal = cvCreateImage(cvSize(300,240), 8, 3);
 IplImage *hist_red1 = cvCreateImage(cvSize(300,240), 8, 3);
IplImage *hist_blue1 = cvCreateImage(cvSize(300,240), 8, 3);
IplImage *hist_green1 = cvCreateImage(cvSize(300,240), 8, 3);
 IplImage *mer1 = cvCreateImage(cvSize(300,240), 8, 3);
IplImage *mer2 = cvCreateImage(cvSize(300,240), 8, 3);
IplImage *mer3 = cvCreateImage(cvSize(300,240), 8, 3);
cvSet( hist_img, cvScalarAll(255), 0 );

 CvHistogram *hist_red;
 CvHistogram *hist_green;
 CvHistogram *hist_blue;

    int hist_size = 256;
    float range[]={0,256};
    float* ranges[] = { range };

    float max_value = 0.0;
     float max_valueb = 0.0;
     float max_valuer = 0.0;
     float max_valueg = 0.0;
    float max = 0.0;
        float maxb = 0.0;
        float maxg = 0.0;
    float w_scale = 0.0;


 hist_red = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
 hist_green = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
 hist_blue = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);

 /* Set image to obtain RED as Channel of Interest (COI) */
  cvSetImageCOI(img,3);
  cvCopy(img,channel);
  cvResetImageROI(img);

 /* Calculate histogram of the Image and store it in the array */
  cvCalcHist( &channel, hist_red, 0, NULL );

 /* Calculate and Plot the histograms Green and Blue channels as well */
 /* Green channel */
  cvSetImageCOI(img,2);
  cvCopy(img,channel);
  cvResetImageROI(img);

  cvCalcHist( &channel, hist_green, 0, NULL );

 /* Blue channel */
  cvSetImageCOI(img,1);
  cvCopy(img,channel);
  cvResetImageROI(img);

  cvCalcHist( &channel, hist_blue, 0, NULL );


/* Find the minimum and maximum values of the histograms */
 cvGetMinMaxHistValue( hist_red, 0, &max_valuer, 0, 0 );
 cvGetMinMaxHistValue( hist_green, 0, &maxg, 0, 0 );

 max_value = (maxg > max_valuer) ? maxg : max_valuer;

 cvGetMinMaxHistValue( hist_blue, 0, &maxb, 0, 0 );

 max_valueb = (maxb > max_value) ? maxb : max_value;
  // The variable max_value has the maximum of the three histograms
//hist = cvCreateHist(1, hsize, CV_HIST_ARRAY, ranges,1);
//cvCalcHist(planes, hist, 0, NULL);
//cvGetMinMaxHistValue(hist, &min_value, &max_value);
printf("Maximum Histogram Value: %f\n",max_valueb );
printf("Maximum Histogram Value blue");



 /* Using the maximum value, Scale/Squeeze the histogram (to fit the image) */
 cvScale( hist_red->bins, hist_red->bins, ((float)hist_img->height)/max_value, 0 );
 cvScale( hist_green->bins, hist_green->bins, ((float)hist_img->height)/max_value, 0 );
 cvScale( hist_blue->bins, hist_blue->bins, ((float)hist_img->height)/max_value, 0 );


  //A scale to estimate the number of pixels

// printf("Scale: %4.2f pixels per 100 units\n", max_value*100/((float)hist_img->height));

    /* Scale/Squeeze the histogram range to image width */
w_scale = ((float)hist_img->width)/hist_size;

/* Plot the Histograms */
    for( int i = 0; i < hist_size; i++ )
    {

      cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
        cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_red->bins,i))),
        CV_RGB(255,0,0), -1, 8, 0 );
      cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
       cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_green->bins,i))),
       CV_RGB(0,255,0), -1, 8, 0 );
      cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
       cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_blue->bins,i))),
       CV_RGB(0,0,255), -1, 8, 0 );
    }

 for( int i = 0; i < hist_size; i++ )
    {
        cvRectangle( hist_red1, cvPoint((int)i*w_scale , hist_img->height),
        cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_red->bins,i))),
        CV_RGB(255,0,0), -1, 8, 0 );
     }
     for( int i = 0; i < hist_size; i++ )
    {
        cvRectangle( hist_green1, cvPoint((int)i*w_scale , hist_img->height),
       cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_green->bins,i))),
       CV_RGB(0,255,0), -1, 8, 0 );
     }
      for( int i = 0; i < hist_size; i++ )
    {
        cvRectangle( hist_blue1, cvPoint((int)i*w_scale , hist_img->height),
       cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_blue->bins,i))),
       CV_RGB(0,0,255), -1, 8, 0 );
     }


cvAdd(hist_red1,hist_green1,mer1,0);
cvAdd(hist_red1,hist_blue1,mer2,0);
cvAdd(hist_green1,hist_blue1,mer3,0);




    return 0;
}
Posted

Color processing or color vision may sound simple but i suggest you think again. With some inspiration from human visual system. http://en.wikipedia.org/wiki/Color_vision[^]

It starts out as an opponent process http://en.wikipedia.org/wiki/Opponent_process[^]

In which color channels R,G,B are converted to Red vs Green ( R - G) ,blue vs yellow ( B - (R+G)/2) and achromatic channel (R/3 + G/3 + B/3). It seems to be imperative to start out that way. You can then filter these resulting channels to remove noise with a box filter using integral images(for speed) or a gaussian filter. Then during the learning phase your app can obtain a 3 - dimensional vector at any given position (one component from each channel) and normalize it and label it and store it as a prototype in an indexing structure such as the kd-tree.http://en.wikipedia.org/wiki/K-d_tree[^]
At run time your app can then label each pixel with it's associated color based on the closest prototype in the indexing structure.

This is a very simplified version of color processing, it goes far than this. Just wanted to share my thoughts on this matter and help you to see other possibilities. I prefer the opponent channels to R,G,B channels in the sense that opponent processing is inspired by human visual system and it probably out performs methods that use direct R,G,B value because the opponent process seem to enhance contrast between channels.

Glad to help :)
 
Share this answer
 
Comments
Nelek 26-May-12 17:29pm    
Nice answer
BupeChombaDerrick 26-May-12 17:46pm    
Thanks :)
Another solution without histogram is: you need to create a filter matrix (or IplImage) filled with the color you want to detect.

Assume that your input is IplImage* img;

All you need is to do the logical 'AND' operator on the input and the filter, the result will turn out non-zero at the detected region.

C++
IplImage* brownFilter = cvCreateImage( cvGetSize(img), 8, 1 ); // Same size as the input
IplImage* detectionResult = cvCreateImage( cvGetSize(img), 8, 1 );

cvZero( detectionResult );
cvSet( brownFilter, CV_RGB(90,40,10) ); // Your color you wanna detect

cvAnd( brownFilter, img, detectionResult, NULL );

// Now the result is stored in the detection result
cvNamedWindow("result");
cvShowImage("result", detectionResult );
cvWaitKey( 0 ); // Halt the screen


For more advanced, if you'd like to detect the similar color (not exactly the same RGB), you need to calculate the distance between

the color of each pixel to the filter color instead. If the distance does not exceed that certain threshold value, it is treated as a detected region.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900