Society of Robots - Robot Forum

Software => Software => Topic started by: Gungrave on May 25, 2010, 01:30:03 PM

Title: Tips for red object detection
Post by: Gungrave on May 25, 2010, 01:30:03 PM
Hey guys, I'm a Computer Engineering Senior trying to do some computer vision for my design project. I'm using the summer to get acquainted with computer vision, as I've never taken a course in it nor have I any experience with it at all. So first off, thank you to the admin for the great tutorials posted on the subject! They were very helpful on getting me started off in the right direction. On to my problem...:-)

I wrote some code up in OpenCV to try and filter out everything but red objects. Here are some relevant snippets of code, and the resulting images...

First I apply an RGB max algorithm, it doesn't actually "max" the dominant color of a pixel, it just zero's the non dominant colors:
Code: [Select]
for( int y=0; y<frame->height; y++ ) {
uchar* ptr = (uchar*) (
frame->imageData + y * frame->widthStep
);

for( int x=0; x<frame->width; x++ ) {

if ( ptr[RED] > ptr[GREEN] && ptr[RED] > ptr[BLUE] ) {
//ptr[RED] = 255;
ptr[BLUE] = 0;
ptr[GREEN] = 0;
}
if ( ptr[GREEN] > ptr[RED] && ptr[GREEN] > ptr[BLUE] ) {
ptr[RED] = 0;
ptr[BLUE] = 0;
//ptr[GREEN] = 255;
}
if ( ptr[BLUE] > ptr[GREEN] && ptr[BLUE] > ptr[RED] ) {
ptr[RED] = 0;
//ptr[BLUE] = 255;
ptr[GREEN] = 0;
}
}
}

Then I apply a red threshold filter, it filters both the hue and intensity of the pixels. It looks like this:

Code: [Select]
for( int y=0; y<frame->height; y++ ) {
uchar* ptr = (uchar*) (
frame->imageData + y * frame->widthStep
);

for( int x=0; x<frame->width; x++ ) {
double r(ptr[RED]),g(ptr[GREEN]),b(ptr[BLUE]);
double light(r*.2 + g*.7 + b*.1);
if (light >= lightThresh ) {
ptr[BLUE] = 0;
ptr[GREEN] = 0;
ptr[RED] = 0;
}

}
}

for( int y=0; y<frame->height; y++ ) {
uchar* ptr = (uchar*) (
frame->imageData + y * frame->widthStep
);

for( int x=0; x<frame->width; x++ ) {

if ( ptr[RED] >= redThresh) {
ptr[BLUE] = 0;
ptr[GREEN] = 0;
//ptr[RED] = 255;
}
else {
ptr[BLUE] = 0;
ptr[GREEN] = 0;
ptr[RED] = 0;
}
}
}

This results in poor red filtering, as can be seen below:

No filters:
(http://img.photobucket.com/albums/v307/gungrave12/th_normal.png) (http://smg.photobucket.com/albums/v307/gungrave12/?action=view&current=normal.png)

RGB "Max":
(http://img.photobucket.com/albums/v307/gungrave12/th_rgbmax.png) (http://smg.photobucket.com/albums/v307/gungrave12/?action=view&current=rgbmax.png)

RGB Max + Red Threshold
(http://img.photobucket.com/albums/v307/gungrave12/th_rgbmaxrfilter.png) (http://smg.photobucket.com/albums/v307/gungrave12/?action=view&current=rgbmaxrfilter.png)


I've played around with the threshold value for about an hour, and these are the best results I can get. If the hue threshold is too low, my entire body is seen as red, even my shirt, if it's too high not even the paper is seen as red. The light threshold gives me similar headaches. I can only conclude that I'm doing something wrong, or at least less than optimal  :P.

Any tips or help to getting better results would be greatly appreciated, thanks!
Title: Re: Tips for red object detection
Post by: Cristi_Neagu on May 25, 2010, 05:48:32 PM
Try to apply the threshold first and then the max algorithm... See where that takes you...
Title: Re: Tips for red object detection
Post by: jka on May 26, 2010, 02:17:52 AM
I've been playing around with something similar. It's a robot that is supposed to find a red ball. I found out that it is problematic to just look at the red component of the RGB signal, because there is something red in almost all colours. Take grey, for example. If you have something grey with an RGB value of 128,127,127, red is the dominant colour and it will end up red in your max function.

Instead, I converted the whole image to the HSV colour space using cv::cvtColor. Then you look at the h (hue) value to find what is red in the image. The hue is an angle in the traditional colour-wheel. Read more: http://en.wikipedia.org/wiki/HSL_and_HSV (http://en.wikipedia.org/wiki/HSL_and_HSV)
Title: Re: Tips for red object detection
Post by: GearMotion on May 27, 2010, 08:03:22 AM
How about looking for red being the significantly dominant color? Something is 'red' if it it a certain number of bits greater than green or blue.
Code: [Select]
if ( ptr[RED] > (ptr[GREEN] + 30)  && ptr[RED] > (ptr[BLUE] + 30) )
{
// I'm a red pixel
}


Possibly a number even greater than 30. Depends on your overall levels.
Title: Re: Tips for red object detection
Post by: Gungrave on May 27, 2010, 02:52:39 PM
Thanks for the suggestions guys, I've been wrapped up in studying sound localization as well and I completely forgot to check this thread  :P.

I'll try your suggestions out and post some results, thanks again.