Wednesday, April 1, 2015

Digital Image processing with c++ ( Chapter 7 ) - Image Smoothing (Gaussian filter)

Hi My dear friends.Today i'm going to show how to implement Gaussian Smoothing filter using C++ and openCV .Theory behind this Gaussian filter is you can learn by using this reference and it clearly mention how to make Gaussian weight matrix.And I'm going to show how I implement this code by using above mention links theory.



#include "stdafx.h"
#include <iostream>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

using namespace cv;
using namespace std;


int main()
{

 /* start producing Gaussian filter kernel*/
 const double PI = 4.0*atan(1.0) ;
 double sigma=  2;
 const int kernalWidth=5;
 const int kernalHeight=5;

 float kernalArray[kernalWidth][kernalHeight];

 double total=0;

 //calculate each relavant value to neighour pixels and store it in 2d array
 for(int row=0;row<kernalWidth;row++){

  for(int col=0;col<kernalHeight;col++){

   float value=(1/(2*PI*pow(sigma,2)))*exp(-(pow(row-kernalWidth/2,2)+pow(col-kernalHeight/2,2))/(2*pow(sigma,2)));

   kernalArray[row][col]=value;

   total+=value;
  }
 }

 //Scale value in 2d array in to 1
 for(int row=0;row<kernalWidth;row++){
  for(int col=0;col<kernalHeight;col++){

   kernalArray[row][col]=kernalArray[row][col]/total;

  }
 }

 /*End producing Gaussian filter kernel*/

 Mat RGBImage;

 RGBImage =imread("C:\\stripeys-big-red-eyes-sharp.jpg");

 Mat grayScaleImage(RGBImage.size(),CV_8UC1);
 Mat openCvGaussianFilterImage(RGBImage.size(),CV_8UC1);

 Mat FinalImage(RGBImage.size(),CV_8UC1);
 cvtColor(RGBImage,grayScaleImage,CV_RGB2GRAY);



 int rows=grayScaleImage.rows;
 int cols=grayScaleImage.cols;


 int verticleImageBound=(kernalHeight-1)/2;
 int horizontalImageBound=(kernalWidth-1)/2;

 //Assian Gaussian Blur value of the center point.Repeating this process for all other points through image

 for(int row=0+verticleImageBound;row<rows-verticleImageBound;row++){

  for(int col=0+horizontalImageBound;col<cols-horizontalImageBound;col++){

   float value=0.0;

   for(int kRow=0;kRow<kernalHeight;kRow++){
    for(int kCol=0;kCol<kernalWidth;kCol++){
     //multiply pixel value with corresponding gaussian kernal value
     float pixel=grayScaleImage.at<uchar>(kRow+row-verticleImageBound,kCol+col-horizontalImageBound)*kernalArray[kRow][kCol];
     value+=pixel;
    }
   }
   //assign new values to central point
   FinalImage.at<uchar>(row,col)=cvRound(value);

  }

 }

 //Genarate same GaussianBlur image using inbuilt openCv function
 GaussianBlur( grayScaleImage, openCvGaussianFilterImage, Size( 5, 5 ), 0 ,0 );

 namedWindow("Original Image",1);
 imshow("Original Image",grayScaleImage);

 namedWindow("Filtered Image",1);
 imshow("Filtered Image",FinalImage);

 namedWindow("openCvGaussianFilterImage",1);
 imshow("openCvGaussianFilterImage",openCvGaussianFilterImage);
 waitKey();
 return 0;
}

You can download image from this link

You can see results like this

This is our original image

This is open CV generated Gaussian blur image

This is our implemented algorithm's Gaussian blur image


Please note this .I'm not an expert on these things.Still i'm learning Image processing. This code is written according to my understand about the concepts of Gaussian smooth filter.If I did some mistake, missed something or if you have any question please leave a comment bellow.
Thank you :)

5 comments:

Unknown said...

Hi, I am founder of http://www.pixelstech.net. Would you like to contribute to our site by posting articles on our site which is a place for geeks. If you are interested, please send a note to us at admin at pixelstech.net . Looking forward to hear from you. Thank you.

Nipuna Shanthidewa said...

Hi Ke Pi.I'm highly appreciate your offer to write articles . I'll send you email .Thanks again

Rabia Fayyaz said...
This comment has been removed by the author.
Rabia Fayyaz said...

Ok . I re-tested your code again.
I think Gussian Blur is average filter. after sum all kernel value ..you have to divide by total number of values and then assign to image.

Rabia Fayyaz said...

Also, you are not computing border part,.