From The Blackfin Handy Board

Vision: Lab1

Color Filtering

The main idea of this lab is to extract those pixels that corresponds to an specific color.

E.g. From the next image, we like to extract those areas that corresponds to an specific Blue.

The image on the left corresponds to the INPUT image. The image on the right corresponds to the OUTPUT image.

The image is captured in the YCbCr format.

The corresponding colors for most of the LEGO bricks are available here

Starting Code

Here you can download a whole set of functions that compose a project for the next color image processing.

// Check the table on http://peeron.com/cgi-bin/invcgis/colorguide.cgi

// Here you will find the table rgbtable ready to be used.

color = 196 ;
yvyv_to_blob_color( PIXEL_PER_LINE, LINES_PER_FRAME, (u8*)Frame, (u8*)Color,
rgbtable[color-1][1],rgbtable[color-1][2],rgbtable[color-1][3]);

int yvyu_to_blob_color( u32 width,

                    u32 height,
                    u8 *inptr,
                    u8 *outptr,
                    int R, int G, int B) 

{

	int w, h;   // parameters for the main loop
	int jump=1; // over sampling the image: 1 is to scan all the pixels
	int jump_w=jump,jump_h=jump;
	int Y_max,Y_min,U_max,U_min,V_min,V_max; // border of the color "window"
	int cp = 20;  // cp= color proximity
	float y,u,v,yy,uu,vv,Y,U,V,r,g,b;
	int hm_colors=0;


	r=(float)R/255;
	g=(float)G/255;
	b=(float)B/255;

    // RGB to YUV conversion 

	Y = 0.299*r + 0.587*g + 0.114*b ;
	yy = 13 + (Y*222);
	U = - 0.147*r - 0.289*g + 0.436*b ; 
	uu = 13 + (U + .436)/.872*227;
	V = 0.615*r - 0.515*g - 0.100*b ;
	vv = 13 + (V + .615)/1.23*227;

	// creat the color proximity on YUV

	U_max = (int)uu + cp;
	U_min = (int)uu - cp;
	Y_max = (int)yy + cp;
	Y_min = (int)yy - cp;
	V_max = (int)vv + cp;
	V_min = (int)vv - cp;


	for( h = 0; h <= height; h+=jump_h ) {
		for( w = 0; w <= width; w+=jump_w) {
		    outptr+=(4*(jump_w-1));
			if ((inptr[0] >= Y_min) && (inptr[0] <= Y_max) &&
				(inptr[3] >= U_min) && (inptr[3] <= U_max) &&
				(inptr[2] >= Y_min) && (inptr[2] <= Y_max) &&
				(inptr[1] >= V_min) && (inptr[1] <= V_max) )
			{	
			    // OUPUT the desired color if it is close to
			    (*outptr) = (int)yy ;
   			    outptr++;
			    (*outptr) = (int)vv;
				outptr++;
			    (*outptr) = (int)yy ;
			    outptr++;
			    (*outptr) = (int)uu;
			    outptr++;
			    hm_colors++;
			}
			else 
			{
			    // OUTPUT white color if the pixel do not correspond
                            // If you like to filter a sequence of colors just comment the line
                            // of the white color assignment
			    (*outptr) = 0x00;
   			    outptr++;
			    (*outptr) = 0x00;
			    outptr++;
			    (*outptr) = 0x00;
			    outptr++;
			    (*outptr) = 0x00;
			    outptr++;
 			}
			inptr += (4*jump_w);								
		}
		outptr+=width*(jump_h-1);
		inptr+=width*(jump_h-1);
	}

   	return 0;    

}

Mission

I) Suppose you have a robot equipped with a digital camera. An object is shown to your robot and the mission is to follow it. With the above code you can easily find a desired color at frame rate. What you have to do is answer the next question, which are the most prominent colors in an image ? and then, define an strategy to allow your robot to follow it!

On the next images you can apply an aritmetic substraction, pixel by pixel, to find what is moving.

- =

Check the function diff_image:

int diff_image( u32 width,

                    u32 height,
                    u8 *inptr,
                    u8 *outptr) {
	int w, h,index=0;
	u8 temp_pixel;

	for( h = 0; h < height; h++ ) {
		for( w = 0; w < width; w++) {
			    outptr+=2;
			    inptr+=2;
			    temp_pixel = abs((*outptr) - (*inptr));
			    if(temp_pixel<=80) { // put the color BLACK on those pixels where the difference is small
			    	outptr-=2;
			    	inptr-=2;
			        (*outptr)= 0x2A;
			    	outptr++;
			    	inptr++;
			    	(*outptr)= 0x85;
			    	outptr++;
			    	inptr++;
			    	(*outptr)= 0x2A;
			    	outptr++;
			    	inptr++;
			    	(*outptr)= 0x85;
			    	outptr++;
			    	inptr++;

			    }
			    else
			    {	
			   	outptr+=2;
			    	inptr+=2;
			    	index++;

  			    }
 		}
	}
	return index;

}

Now, you have to localize those coloured areas and define an strategy to track only those. If you are not very happy with the prescence of skin-like pixels, it should be easy to eliminate them, just check here

II) Color filtering can be used to create color layers. Even if the computation of one-color-layer is not expensive - in computational terms - consider many colors at the same time can decline the performance of our program. Here you can find a very nice strategy to overcome such a difficulty.

References

Colour and Reflectance

Processing Image Pixels, Color Intensity, Color Filtering, and Color Inversion

Bayer filter

Color Based Object Recognition

Digital Color Imaging

Retrieved from http://www.cs.uml.edu/blackfin/index.php/Vision/Lab1
Page last modified on August 21, 2006, at 06:56 PM