较原始的Bernsen:
这个算法的中心思想是:设当前像素为P,计算以P为中心的大小为(2w+1)*(2w+1)窗口内的所有像素的最大值M与最小值N,两者的均值T,
if(M-N)> S
则当前点P的阈值为T。
else
当前窗口所在区域的灰度级差别较小,那么窗口在目标区或在背景区,若T>T'则当前点灰度值为255,否则,当前点灰度值为0.
S作者最初设为15, T'设为(255+0)/2=128。
这种最原始的算法的效果总体来说还行,但一般所用的Bernsen算法都是经过各种改进的。
#define Th 128
void Bernsen(IplImage *src, IplImage *dst)
{
int i = 0, j = 0,k = 0, l = 0, maximum = 0, minor = 0, mid_gray = 0;
int upleft = 0, upright = 0, downleft = 0, downright = 0;
int wide = src->widthStep;
int high = src->height;
unsigned long sum = 0;
int average = 0;
unsigned char *p, *q;
p = (unsigned char *)src->imageData;
q = (unsigned char *)dst->imageData;
for (j = 0; j < high; j++, p += wide)
{
for (i = 0; i < wide; i++)
{
sum += p[i];
}
}
average = sum / (wide * high);
for (j = 0; j < high; j++)
{
p = (unsigned char *)(src->imageData + j * wide);
q = (unsigned char *)(dst->imageData + j * wide);
for (i = 0; i < wide; i++)
{
upleft = (i - 15) > 0 ? (i-15):0;
upright = (i + 15) < wide ? (i+15):(wide- 1);
downleft = (j - 15) > 0 ? (j - 15):0;
downright = (j + 15) < high ? (j + 15):(high - 1);
for (k = downright; k <= downright; k++)
{
for (l = upleft; l <= upright; l++)
{
if (p[l] >= maximum)
{
maximum = p[l];
}
else if (p[l] <= minor)
{
minor = p[l];
}
}
}
mid_gray = (maximum + minor) >> 1;
if ((maximum - minor) > S)
{
q[i] = p[i] >= mid_gray ? 255 : 0;
}
else
q[i] = mid_gray >= average ? 255 : 0;
}
}
}