next up previous contents
Next: Colour Inverting: Up: Introduction Previous: Image Processing   Contents

Digital Image Processing

The digital [or computer] representation of images happens like this; A digital camera captures the image, by converting the light intensity to equivalent electrical voltage levels and this is quantized by and ADC [Analog to Digital Converter], and the resulting data is stored in the camera's digital memory. The essential process that happens is that of quantizing, the real colour to a small digital value, and at that ensuring we keep it small enough to be stored in memory and large enough to hold all the colours we desire. Thus evolved the generic term for a colour element on the computer: Pixel, [Picture Element], which stores the values of colour components, namely red,green and blue. For the programmer a pixel can be represented like this:

struct pixel
{                            
	unsigned char red;    // 0  to   255 
	unsigned char green;  // 0  to   255
	unsigned char blue;   // 0  to   255
};

Here the pixel is large enough to allow us represent some 16777216 [16 Million Colours] approximately, and small enough to represent it in 24 bits! An image is a thus, intuitively a collection of different colours arranged along different rows and columns. The colours are nothing but pixels; which follows that an image is a collection of pixels in rows and columns. A image to us is simply an 2-D array of pixels.

Now that you have understood what an image is, and how its represented in an array of pixels, various formats exist in the wide world of image processing to encode and store the images, so that they occupy the least amount of memory, to facilitate among other things faster downloads and quicker processing. These formats, which you may be familiar are the ones like jpeg, png, bmp, xpm etc. Now each format uses various techniques for encoding; for example jpeg use DCT [Discrete Cosine Transform], bmp can be RLE [Run Length Encoded], and PNG could use dictionary based compression. Whew so much for a 2-D array of pixels, that the weak hearted might consider quitting.Wait; thats why the GTK and GDK libraries are considered the panacea to this pain. GDK has function calls that loads from almost any image to the sought after 2-D array of pixels.And need I say more? Lets start.

GDK can load files using the function gdk_pixbuf_new_from_file and we can get various attributes of the image like width,height and pointer to pixel buffer(to manipulate it!),process the image next, and then we can make a GTK widget from it. The following section of commented code walks through a typical section.

  1. Attribute function
  2. width int gdk_pixxbuf_get_width
  3. height int gdk_pixxbuf_get_height
  4. pixel pointer gchar *gdk_pixxbuf_get_pixels
  5. rowstride int gdk_pixxbuf_get_rowstride

  /*
	Code for loading and image & displaying it.
  */		
  #include<gtk/gtk.h>

  gchar *filename="/usr/share/pixmaps/gnu_emacs.png"; //picture to load
  GdkPixbuf *pb;                                     //pixbuf structure
  GtkImage *im;                                      //gtk widget

  pb=gdk_pixbuf_new_from_file(filename,NULL);        //load the image to pixbuf

  process_picture(pb);				     //process it the fun begins here!

  im=gtk_image_new_from_pixbuf(pb);		     //make it a widget

  gtk_widget_show(im);				     //display the image widget

I will assume that from this point onwards, we are working with a standard pixel, as defined above in section [see pixel] Of the many effets possible after befriending the pixel, the easiest ones are the pixel level or point filters.They consist of, but not limited to

  1. Gray scaling see sec [*]
  2. Colour Inverting see sec [*]
  3. Colour Masking see sec [*]
  4. Brighten see sec [*]
  5. Flip see sec [*]
  6. Invert see sec [*]
  7. Border see sec [*]

A note of accessing the pixel array as returned by the GDK. As of writing the GDK supports image of the type RGBA or RGB only. Hence we are supposed to get the attributes of height,width and bytes per pixel, before we begin. The pointer to the pixel array is a 1-D array of pixels, which has to navigated like a 2-D array as show below. It has at offsets of 0,1,2 form the current pixel location, the values of the red, green, and blue values of the current pixel.

  int ht,wt;
  int i=0,j=0;
  int rowstride=0;  
  int bpp=0;
  gchar *pixel;


  if(gdk_pixbuf_get_bits_per_sample(pb)!=8)   //we handle only 24 bit images.
  	return;                               //look at 3 bytes per pixel.

				  //getting attributes of height,
  ht=gdk_pixbuf_get_height(pb);   //width, and bpp.Also get pointer
  wt=gdk_pixbuf_get_width(pb);	  //to pixels.
  pixel=gdk_pixbuf_get_pixels(pb);

  bpp=3;
  rowstride=wt*bpp;

  for(i=0;i<ht;i++)		//iterate over the height of image.
    for(j=0;j<rowstride;j+=bpp)   //read every pixel in the row.skip
				//bpp bytes 
      {	
      
      //access pixel[i][j] as
      // pixel[i*rowstride + j]

      //access red,green and blue as

      pixel[i*rowstride + j+0]=red
      pixel[i*rowstride + j+1]=green
      pixel[i*rowstride + j+2]=blue
      
      }

We will be using the figure of the kathakali dancer shown here in figure, for our image processing needs.

Figure: A Kathakali dancer. Kathakali is the traditional art form of Kerala [India]
Image kathakali


next up previous contents
Next: Colour Inverting: Up: Introduction Previous: Image Processing   Contents
Muthiah 2004-06-04