Finding Optimal Threshold Value for a Binary Image using Adaptive Gaussian Method

This method is very useful in finding the optimum threshold value in a binary image where the intensity can be modeled as a Bimodal Histogram. The algorithm is very straight forward. You start with an ideal threshold value (128), divide the histogram into 2 parts based on this value, and then find the average intensities in the 2 parts of the histogram. The threshold value is the average of the 2 threshold values obtained for the 2 Histograms.

You keep on iterating until you find the same vaue consecutively.

Below is a simple openCV function written in C without using any of the standard openCV functions to implement this algorithm :

int find_threshold(IplImage* image)
{
int threshold_final;
int i,j;
int k = 256;
int t_initial = k/2;

int height = image->height;
int width =  image->width;
float new_t;

CvScalar s1,s2;

int intensity_temp1 = 0, intensity_temp2 = 0;

IplImage* temp1 = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);
IplImage* temp2 = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);

int size = (temp1->height)*(temp1->width);

uchar *data_input = image->imageData;
int data_temp1[size],data_temp2[size];
int p=0,q=0;

while (1)
{

for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
if(data_input[i*(image->widthStep) + j*(image->nChannels)] < t_initial )
{
data_temp1[p] = data_input[i*(image->widthStep) + j*(image->nChannels)];
p++;
}
else
{
data_temp2[q] = data_input[i*(image->widthStep) + j*(image->nChannels)];
q++;
}
}
}
for (i = 0;i<p;i++)
{
intensity_temp1 = intensity_temp1 + data_temp1[i];
}

for (i = 0;i<q;i++)
{
intensity_temp2 = intensity_temp2 + data_temp2[i];
}

float average1 = intensity_temp1/p;
float average2 = intensity_temp2/q;

intensity_temp1 = 0;
intensity_temp2 = 0;
p=0;
q=0;

//calculate new value of threhold as the average of these 2 means
// T = (mu1 + mu2)/2
new_t = (average1 + average2)/2;
threshold_final = (int)new_t;

if (threshold_final == t_initial)
break;
else
t_initial = threshold_final;

}

return(threshold_final);
}

No comments yet

Leave a comment