由于阈值处理直观、实现简单且计算速度快,而且EMCV中不含有该算法,下面用OpenCV给出实现的代码。
1. 处理流程:
1).为全局阈值选择一个初始估计值T(图像的平均灰度)。
2).用T分割图像。产生两组像素:G1有灰度值大于T的像素组成,G2有小于等于T像素组成。
3).计算G1和G2像素的平均灰度值m1和m2;
4).计算一个新的阈值:T = (m1 + m2) / 2;
5).重复步骤2和4,直到连续迭代中的T值间的差为零。
2.源代码:
//gray image U8 全局阈值分割
int vicIsodataThreshold(IplImage *p_image_in, float offset, int *threshold)
{
int ret = 0;
int i, j;
int T = 0;
unsigned char *data;
unsigned char *data_line;
if (NULL == p_image_in || NULL == threshold)
{
return -1;
}
float T0 = 0.0;//初始阈值
float sum_0 = 0.0;
for (i = 0 ; i< p_image_in->height ; i++)
{
data = (unsigned char *)p_image_in->imageData + i * p_image_in->widthStep;
for (j =0 ; j < p_image_in->width;j++)
{
data_line = data + j;
sum_0 += (float)*data_line;
}
}
T0 = sum_0 / (p_image_in->height * p_image_in->width);
T = (int)(T0 + 0.5);
float T1 = 0.0, T2 = 0.0;
float sum_1 = 0.0, sum_2 = 0.0;
int count1, count2;
float dT = 255.0;
//计算T两侧的灰度平均值,然后把二者的均值赋值给T
while (dT > offset)
{
T1 = 0.0;
T2 = 0.0;
sum_1 = 0.0;
sum_2 = 0.0;
count1 = 0;
count2 = 0;
for (i = 0 ; i< p_image_in->height ; i++)
{
data = (unsigned char *)p_image_in->imageData + i * p_image_in->widthStep;
for (j =0 ; j < p_image_in->width;j++)
{
data_line = data + j;
if (*data_line >= T)
{
sum_1 += (float)*data_line;;
count1++;
}
else if(*data_line < T)
{
sum_2 += (float)*data_line;;
count2++;
}
}
}
T1 = sum_1 / count1;
T2 = sum_2 / count2;
dT = fabs(T - (T1 + T2)/2);
T = (T1 + T2)/2;
cout<<"the T is "<
reference:http://blog.csdn.net/renshengrumenglibing/article/details/7251127