RSS Subscription
Linux Howtos & Tutorials

Enter your email:

Delivered by


NOTE:New tutorials are from LinuxCareer.com

Poll

Do you own or wish to have iPhone?
 


Linux eBooks FREE Download
A guide to programming Linux kernel modules
Introduction to Linux - A Hands on Guide
A Newbie's Getting Started Guide to Linux

Linux from Scratch - Create Your Own Linux System - Free eBook

Linux: The Hacking Solution (v.3.0)

SQLite 3 with PHP Essential Training – Free Video Training Tutorials

This guide will introduce you to the world of GNU/Linux

The GNU/Linux Advanced Administration

A Complete Beginner's Manual for Ubuntu 10.04 (Lucid Lynx)

Advanced Bash-Scripting Guide

Set up, maintain, and secure a small office email server

Partner Linux Sites:
How-To.LinuxCareer.com
Jobs.LinuxCareer.com
TuxMachines
Monsterb
LinuxBloggers
AdamsInfo
LinuxScrew
All For Linux

Image Processing, Linear stretch and OpenCV

In attempt to recognize objects by examining images, various Image processing and analysis techniques are applied. This article briefly describes linear stretch algorithm and its use within OpenCV.


Linear stretch technique can be applied to images where substantial lack of contrast can result in false identification of objects, its spacial relationship and significance. Contrast enhancement by linear stretch can be applied to images with very low or very high variations of brightness. To apply the Linear stretch algorithm an image needs to be converted into gray-scale and all 8bit pixels and its values are recorded into histogram.

Histogram will contain all 256 grey-levels ( 0 - 255 ) in so called bins and each pixel value will take place in the bin represented with its own value. When the histogram and the image is created, maximum ( OMAX ) and minimum ( OMIN ) values are identified.

 

Linear stretch is applied to the histogram as follows:

 

  • create a histogram of the original image
  • set new maximum ( NMAX ) and new minimum ( NMIN ) values
  • calculate number of bins in the original histogram where value of bins = ( OMAX - OMIN )
  • calculate spacing for a new histogram so space = ( NMAX - NMIN ) / ( OMAX - OMIN )
  • create a new histogram with corresponding positions for new bins ( Nb ) represented by
  • use new histogram to create new image

The previous formula can be represented by simplified version of c++ code as follows:

#include <iostream> 
 
using namespace std; 
int main() { 
 
   const int NMIN = 0; 
   const int NMAX = 255; 
   const int OMIN = 60; 
   const int OMAX = 65; 
   int space = ( NMAX - NMIN ) / ( OMAX - OMIN ) ; 
   int bins = ( OMAX - OMIN ); 
 
   for ( int j = 0; j <= bins; j++ ) { 
   	std::cout << j + OMIN << ": " << NMIN + ( j * space ) << endl; 
   } 
return 0; 
}

COMPILE:

g++ bins.cpp -o bins

OUTPUT:

60: 0
61: 51
62: 102
63: 153
64: 204
65: 255

The c++ code above is really simplified version of the linear stretch algorithm. In the next section we are going use OpenCV library to do this task.

Using OpenCV library we can take advantage of cvNormalize function. This function takes at minimum five arguments ( original image, new image, NMIN, NMAX and normalization type ). The following OpenCV c++ code takes sample image as a single argument. The following c++ code will apply cvNormalize function to a sample image and create histogram for original as well as normalized image.

#include "cv.h"
#include "highgui.h"

void create_histogram_image(IplImage*, IplImage*);

int main( int argc, char** argv )

{
//load color image specified by first argument
IplImage *source = cvLoadImage( argv[1]);

// create new image structure 
// for the grayscale output image
IplImage *gray_img = cvCreateImage( 
cvSize( source->width, source->height ), IPL_DEPTH_8U, 1 );

// set type CV_RGB2GRAY to convert 
// RGB image to grayscale 
cvCvtColor( source, gray_img, CV_RGB2GRAY );

// create new image structure 
// to hold histogram image
IplImage *hist_img = cvCreateImage(cvSize(300,240), 8, 1);
cvSet( hist_img, cvScalarAll(255), 0 );

// create new image structure 
// to hold stretched output image
IplImage *stretched_img = cvCreateImage( 
cvSize( source->width, source->height ), IPL_DEPTH_8U, 1 );

// create new image structure 
// to hold histogram image
IplImage *stretched_hist_img = cvCreateImage(cvSize(300,240), 8, 1);
cvSet( stretched_hist_img, cvScalarAll(255), 0 );

// create new image structure 
// to hold stretched output image
IplImage *equalized_img = cvCreateImage( 
cvSize( source->width, source->height ), IPL_DEPTH_8U, 1 );

// cvNormalize function call to apply linear stretch
cvNormalize(gray_img, stretched_img, 0, 255, CV_MINMAX);


// create histogram of the original image
create_histogram_image(gray_img, hist_img);
// create histogram of the new image.
create_histogram_image(stretched_img, stretched_hist_img);

// display all images
cvNamedWindow( "Original Gray-scale Image", 1 );
cvShowImage( "Original Gray-scale Image",gray_img);

cvNamedWindow( "Stretched Gray-scale Image", 1 );
cvShowImage( "Stretched Gray-scale Image",stretched_img);

cvNamedWindow( "Gray-scale Image Histogram", 1 );
cvShowImage( "Gray-scale Image Histogram",hist_img);

cvNamedWindow( "Stretched Image Histogram", 1 );
cvShowImage( "Stretched Image Histogram",stretched_hist_img);
// wait indefinitely for keystroke
cvWaitKey(0);

return 0;
}

void create_histogram_image(IplImage* gray_img, IplImage* hist_img) {
CvHistogram *hist;

int hist_size = 256;     
float range[]={0,256};
float* ranges[] = { range };
float max_value = 0.0;
float w_scale = 0.0#000000;">;

// create array to hold histogram values
hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
 
// calculate histogram values 
cvCalcHist( &gray_img, hist, 0, NULL );
 
// Get the minimum and maximum values of the histogram 
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
 
// set height by using maximim value
cvScale( hist->bins, hist->bins, ((float)hist_img->height)/max_value, 0 );

// calculate width
w_scale = ((float)hist_img->width)/hist_size;
 
// plot the histogram 
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->bins,i))),
     cvScalar(0), -1, 8, 0 );

	}
}

COMPILE:

g++ `pkg-config opencv --cflags --libs` normalize.cpp -o normalize

EXECUTE:

./normalize sample.png

OUTPUT:

sample.png ( original RGB image )

In the next step we have converted RGB image to a gray-scale:

using cvNormalize we have applied linear stretch:

 

Now we can compare histograms of both images.

 

Histogram of the original gray-scale image:

Histogram of the new stretched image:

Share this linux post:

Submit Image Processing, Linear stretch and OpenCV in Delicious Submit Image Processing, Linear stretch and OpenCV in Digg Submit Image Processing, Linear stretch and OpenCV in FaceBook Submit Image Processing, Linear stretch and OpenCV in Google Bookmarks Submit Image Processing, Linear stretch and OpenCV in Stumbleupon Submit Image Processing, Linear stretch and OpenCV in Technorati Submit Image Processing, Linear stretch and OpenCV in Twitter
 
Comments for this page are closed !!!
Please visit our new Linux Forum for additional help or discussion.


Linux eBooks FREE Download