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 :)