Open Computer Vision

September 28, 2008

Color Detection by using Color space basics

Filed under: Color Detection,Image Processing,Open Computer Vision,OpenCV — colouredpages @ 6:42 pm

Ever wondered how can i detect the color ..rather one color from many colors and highlight the same..?

This post is all about it…a quick glimpse about the color detection thing is here and also the method which I have used here is Color space conversion..So If you are a color Enthusiast then you should study this post…

Let me also tell you the algorithm used here for color detection is also used once more in another program…

So now let us extract the red things from the images and this time we will do it with perfection and let me also tell you that the we are only going to detect the red color here…

If you want to understand the whole point of this program then you need to first understand the basics
of color conversion..You need to understand how the HSV Colorspace works.

In Simple words

H-Hue which means in this channel we want to know “which” is the color which is present

Saturation-Which means how much amount of color is present which means

higher the number means that there is more color and lesser white light….in other words if you see an area which is perfectly red, which means there is more color present and lesser white light.

If you focus a torch on a coloured ball….the area where the ball shines means that more of white light is getting reflected from the ball from that part and hence that area is said to be more diluted by the white light and hence you would see the shine the color is there but there is more shine in the color…

/*ALL the necessary header files*/

 #include"math.h"
 #include"conio.h"
 #include"cv.h"
 #include"highgui.h"
 #include"stdio.h"
int main()
{
int i,j,k;//for iterations
int temp=0;//if we use a temporary var
/*here lets look at the word “heighthsv” …now lets breadk up this word…here height means

height as a regular IplImage Structure has now the addition “hsv” to the word heigh means this
height attribute is for the image which is color converted to the hsv,Similar conventions
for the monochrome image…so you may find the attribute height for the monochrome image to be
heightmono…So i believe it is easy…*/
int heighthsv,widthhsv,stephsv,channelshsv;
int heightmono,widthmono,stepmono,channelsmono;
uchar *datahsv,*datamono;
int sthreshold=140;

So have a look at this variable very closely….

We are going to use this variable to detect the intensity of the color which is red for this time
So if you have gone through the HSV color space tutorial then you must have got the concept
of what is the saturation in a HSV colorspace and if you did not before proceeding with thsi program

you should have a look at this link

http://en.wikipedia.org/wiki/HSV_color_space
This link according to me is the best link which one can ever
suggest for the understanding the color spaces
Now sthreshold means saturation threshold which means we are only allowing the pixels
above a certain value to be realized so the hue values will allow a color and the saturation value
will allow the color which more intense than the particular value…which is said by the sthreshold
Now the what do the hlower and the hupper mean…..

Now let us have a look at an example…so if red is at 0(of course hue value of red is zero..

So we need to allow red which is of a particular intensity and above
so we have selected the range of the hue value which is allowed to be 175-05
(which always means above 175 and below 10)(0-10 and 175-180)
Now an obvious question the hue range is between 0-360 and the red color is 0

so we must have selected the range to be 355-10(which means above 355 and below 10)…because after the values
approach 360 it again become zero to complete the closed circle of the hue here
But if we closely observe an INTEGER data type in which is of 1 byte(8 BITS) can store a max value of
255…so 0-360 is not realizable…to make it realizable OPENCV has compressed the circle to half
which means if originally if we have a color of the hue value 120 in the HSV color space
now to make that color realizable with the help of only one byte which has a max range of 255
the same color which has a value of 120 originally in the HSV colorspace would have a value
of 60 in opencv….which means we have divided all the original values by 2….so the color red
which is in between 0-360…would now be found in between 0-180 which is 360/2..
…and the numbers after 180 would be again zero so i have chosen the range which would detect
red would be 0-175 so the lower cut off value for the red
would be 175 and the upper cut off would be 05

You may continue copying the code from here.

double hlower=175,hupper=5;/*
here hlower is the lower cut off and the hupper is the upper cut off for hue values of red.*/

i=j=k=0;/*initializing the iteraiton variables to be zero*/

IplImage *frame=cvLoadImage(“3d-09-5balls.jpg”,1);

if(frame==NULL ) {
puts("unable to load the frame");exit(0);}
printf("frame loaded");
IplImage *colimgbot = cvCreateImage( cvGetSize(frame), 8, 3 );

IplImage *monoimgbot = cvCreateImage( cvGetSize(frame), 8, 1 );

//——————————————————————

heighthsv = colimgbot->height;
widthhsv = colimgbot->width;
stephsv =colimgbot->widthStep;
channelshsv = colimgbot->nChannels;
datahsv = (uchar *)colimgbot->imageData;
//————————–

heightmono = monoimgbot ->height;
widthmono = monoimgbot->width;
stepmono = monoimgbot->widthStep;
channelsmono = monoimgbot->nChannels;
datamono = (uchar *)monoimgbot->imageData;
cvCvtColor(frame,colimgbot,CV_RGB2HSV);
cvNamedWindow("original", CV_WINDOW_AUTOSIZE);

cvNamedWindow("Monochrome Of red Blob",CV_WINDOW_AUTOSIZE);
for(i=0;i< (heighthsv);i++)
{
for(j=0;j<(widthhsv);j++)
{
if((datahsv[(i)*stephsv+j*channelshsv]<=hlower) && (datahsv[(i)*stephsv+j*channelshsv]>=hupper))
{ if((datahsv[(i)*stephsv+j*(channelshsv)+1])>sthreshold){
datamono[i*stepmono+j*channelsmono]=255;}
else
/*A very simple concept with the loops here if the hue values are in the aforementioned range and the
threshold is met then logic one else logic zero*/
datamono[i*stepmono+j*channelsmono]=0;}
}}
for(i=0;i< (heighthsv);i++)
{
for(j=0;j<(widthhsv);j++){
if(!(datamono[i*stepmono+j*channelsmono]==0 || datamono[i*stepmono+j*channelsmono]==255))
datamono[i*stepmono+j*channelsmono]=0;}}/*Just a cross chek to ensure whether all the pixels have only
either 0 or 255*/
/*Please check these links for the explanation of the erosion and dilation functions

http://www.dca.fee.unicamp.br/dipcourse/html-dip/c9/s4/front-page.html*/

/*so now the last parameter in the function indicates how many times you want to apply dilation

or erosion*/

cvErode(monoimgbot,monoimgbot,0,6);
cvDilate( monoimgbot,monoimgbot,0,10);
/*here i have experimented with the values by changing them…and i have found
that i come to a good result by applying erosion 6 times and dilation 15 times
you can comment/uncomment play with the values and see what is going on
Sometimes you will find the areas which are shining in the image also get detected…

Please think why and then try to post a comment the best commment would get visible on this page*/

cvShowImage("original",frame);
cvSaveImage("red-ballmonochrome.jpg",monoimgbot);/*if you want to save the image*/
cvShowImage("Monochrome Of red Blob",monoimgbot);
cvWaitKey(0);
/*for all the other clarifications you can check the other posts…. you will find an answer
People who are getting started with the Opencv must make sure you

check the other posts on this blog*/

cvDestroyWindow("Monochrome Of red Blob");
cvDestroyWindow("original");
return 0;
}


30 Comments »

  1. Found ur blogpost informative.M very much interested in this field.M doing final year Engg. Project on Image Fusion using VC++/OpenCV.Would like suggestions for it wen needed.

    Comment by Vikram — February 25, 2009 @ 6:37 am | Reply

  2. Now it’s working perfect!
    Thanks!
    Is there a way to find the coordinates of the ‘center of gravity’ of the red object?

    Thanks again,
    Avi.

    Comment by rtluser — April 3, 2009 @ 2:07 pm | Reply

  3. and once more small detail, line 27:
    channelsmono = monoimgbot->Channels;
    would be:
    channelsmono = monoimgbot->nChannels;
    Kris :)

    Comment by Kris — April 4, 2009 @ 7:11 pm | Reply

  4. Hi guys help me out.

    I would like to detect other colors than red, specially blue and green
    Can anyone help me w/ the coding

    gerald

    Comment by gerald — April 5, 2009 @ 6:18 am | Reply

  5. Thanks a lot, your algorithm should be implemented in the library. OpenCV is so low level that it is unusable for color filtering.

    Comment by Bobby — May 21, 2009 @ 9:54 pm | Reply

    • Thank you…:)

      Comment by colouredpages — May 22, 2009 @ 3:46 am | Reply

  6. Thanx for the code guys, its a great help. Could you please explain how you came up with sthreshold = 140? Is it a random (i.e. experimented) value or calculated one (like hupper and hlower)
    Cheers

    Comment by achu18 — May 26, 2009 @ 2:09 am | Reply

    • Its random for sure and it differs in different environments….

      Comment by colouredpages — May 30, 2009 @ 4:35 pm | Reply

  7. Is my understanding of color space correct?
    for the following IplImage(img)

    IplImage *img ;
    int width = img->width;
    int height = img->height;
    int nchannels = img->nChannels;
    int step = img->widthStep;
    uchar *data =( uchar*)img->imageData;
    img->channelSeq is BGR

    for( i =0; i < height ; i++)
    for( j =0; j < width ; j++)
    {
    data[i*step + j*nchannels +0] is the blue channel
    data[i*step + j*nchannels +1] is the green channel
    data[i*step + j*nchannels +2] is the red channel
    }

    once you convert the img to hsv using cvCopy(img,hsvImg,NULL) then

    data[i*step + j*nchannels +0] is the hue value (between 0 and 180)
    data[i*step + j*nchannels +1] is the saturation i.e. threshold
    data[i*step + j*nchannels +2] is the value i.e. brightness

    Is this correct?

    Comment by achu18 — June 3, 2009 @ 1:09 am | Reply

    • Hey,

      Right now I am out of town but i still make sure that I check for the comments on my site.But i think you are doing a serious mistake..First of all you use cvCvtColor to change between color spaces …friends I tell you once again a certain range of numbers are converted to another range of numbers to extract a feature in the color conversion…please read the tutorial about the HSV and the color space conversion and then you would not have any problems….

      and after you are done with the conversion please treat the array as a normal simple array as you were treating the same earlier…arrays would remain arrays but the numbers would change the dimensions of the numbers would obviously be the same ..Please do not expect the same numbers to be present…I hope this helps….!!!

      Comment by colouredpages — June 4, 2009 @ 4:35 pm | Reply

      • sorry colouredpages,
        cvCopy was a typo, i meant cvCvtColor!

        Comment by achu18 — June 5, 2009 @ 12:29 am

    • Yes after you convert the Image to HSV you would handle the iplimage as an ordinary Iplmage….so you are right…and also you do not have the values above 180 for hue..so are correct ..finally great everything is fine….

      Comment by colouredpages — June 13, 2009 @ 7:08 am | Reply

  8. hey,,great work!

    just curios,,what if you want to detect other colors?

    and how did you arrive with the value of sthreshold?

    Comment by martin — June 27, 2009 @ 12:23 pm | Reply

    • Its really dyanmic and you have to guess,…

      Comment by colouredpages — June 27, 2009 @ 5:29 pm | Reply

  9. hey guys,

    does anyone knows the hupper and hlower for green or blue??

    thx

    Comment by john — October 21, 2009 @ 2:29 am | Reply

    • now lemme see how many people give approximately correct answers to this question..!!

      Comment by colouredpages — October 21, 2009 @ 6:14 am | Reply

      • so do u know the answer??

        Comment by john — October 22, 2009 @ 1:21 am

      • Ok then i do not know the answer..Have fun….I do not give answers to people who do not work by themselves…!!

        Comment by colouredpages — November 5, 2009 @ 6:25 pm

  10. Please the values of thresholds: sthreshold, hlower and hupper for detecting the blue ball, please it is urgent.thank you very much

    Comment by Amel — October 26, 2009 @ 4:37 pm | Reply

    • Could you please atleast experiment…? take the lower value to be 5 and the upper to be 10 and the next time take the lower value to be 10 and upper to be 15..proceed till you get the result…!! I am sure you would get the answer yourself by this method…please do not ask the next time for the values of the other colors..!!

      Comment by colouredpages — November 5, 2009 @ 6:23 pm | Reply

  11. Hi,

    I am new to opencv, still learning procedures and all the functions. I am trying to run your program but getting this error:

    Bad number of channels (Incorrect number of channels for this conversion code) in function cvCvtColor, . \cvcolor.cpp

    Can you advice whats the best way to tackle this?

    Regards
    Jas Singh

    Comment by Jas Singh — November 4, 2009 @ 10:18 pm | Reply

    • Dude,

      I really do not think you should be getting an error like this…really if you look at the previous comments they were able to compile the code ..Please send me the screen shot and the complete error details a colouredpages@gmail.com

      Comment by colouredpages — November 5, 2009 @ 6:21 pm | Reply

  12. I am student of engineering.I have tested this code to detect red ball from the ground(green area).But result is not good. what changes I should make?
    Thank you in advance.

    Comment by NK — November 10, 2009 @ 9:05 am | Reply

  13. I am student from eng. I have used this code to find red ball on ground image but it does not give good result. can not detect ball

    Comment by NK — November 10, 2009 @ 9:28 am | Reply

    • Dear,
      If you observe closely, i have always told that the program which I have provided would require some changes in the environment which you use the program in…please try to change some values… I have got many mails saying that the program is working fine..!!

      Comment by colouredpages — November 13, 2009 @ 10:04 am | Reply

  14. Just wanted to say thank you. This article was very helpful. keep it up! :)

    Comment by h — November 23, 2009 @ 10:03 pm | Reply

  15. Wow… thanks for all the information! All the information related with HSV and how to work with it in OpenCV has been very useful for me!

    Comment by Oscar — April 18, 2010 @ 1:54 pm | Reply

  16. The link you provide for HSV tutorial (http://www.mandelbrot-dazibao.com/HSV/HSV.htm) does not work). Can you give any other, or the correct path? I could not understand the hlower and hupper values. Can you please explain?
    Best regards,

    Comment by Paulo Trigueiros — May 6, 2010 @ 4:19 pm | Reply

    • The best link i have found is http://en.wikipedia.org/wiki/HSV_color_space . Try to understand the third paragraph and do not complicate the issue….’h', ‘s’,'v’, hue means color, saturation means the amount of color and value means the amount of brightness. simple do not think much….check the opencv documentation and find out the maximum and the minimum values those three components can take and tweak it a bit to make it work for you…(This way I am asking you to learn to drive the car and then get to know the internal details of the car(how it works))…:)

      Comment by colouredpages — May 7, 2010 @ 5:28 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.