Bernsen法属于局部阈值法,在光照不均匀的条件下有较好的处理效果。其思想如下:
1:设当前像素为点为P(i,j),计算以P为中心的大小为kernel*kernel窗口内的所有像素的最大值kernelMax与最小值kernelMin,若两者差值相近,该部分属于目标或背景,将该灰度与全局阈值比较,确定是目标还是背景,若二者差值较大则可能属于目标与背景相交的边缘,此时将二者平均值作为Kernel阈值。
private void Bernsen(byte[,]_grayData,int kernel, int Tlocal, int Tglobal)
{
int halfKernel = kernel / 2;
int[] kernelData = new int[kernel * kernel];
for (int i = 0; i < _w; i++)
{
for (int j = 0; j < _h; j++)
{
if (i < halfKernel || i > _w - halfKernel - 1 ||
j < halfKernel || j > _h - halfKernel - 1)
{
_outBitmap.SetPixel(i, j, Color.Black);
}
else
{
int k = 0;
for (int x = i - halfKernel; x < i + halfKernel; x++)
{
for (int y = j - halfKernel; y < j + halfKernel; y++)
{
kernelData[k] = _grayData[x, y];
}
}
int kernelMax = kernelData.Max();
int kernelMin = kernelData.Min();
int Tkernel = (int)((kernelMax + kernelMin) * 0.5);
//灰度差值小,该点要么在目标区域,要么在背景区域
if (kernelMax - kernelMin <= Tlocal)
{
if (Tkernel > Tglobal)
_outBitmap.SetPixel(i, j, Color.Black);
else
_outBitmap.SetPixel(i, j, Color.White);
}
//灰度差值大,说明在边缘区域,将均值作为局部阈值
else
{
if (_grayData[i, j] > Tkernel)
_outBitmap.SetPixel(i, j, Color.Black);
else
_outBitmap.SetPixel(i,j,Color.White);
}
}
}
}
}