赞
踩
public Bitmap Threshoding(Bitmap b, byte threshold)
{
int width = b.Width;
int height = b.Height;
BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * 4;
byte R, G, B, gray;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
R = p[2];
G = p[1];
B = p[0];
gray = (byte)((R * 19595 + G * 38469 + B * 7472) >> 16);
if (gray >= threshold)
{
p[0] = p[1] = p[2] = 255;
}
else
{
p[0] = p[1] = p[2] = 0;
}
p += 4;
}
p += offset;
}
b.UnlockBits(data);
return b;
}
}
#endregion
#region 自适应阈值法二值化模块
/// <summary>
/// 自适应阈值
/// </summary>
/// <param name="b">位图流</param>
/// <returns></returns>
public Bitmap AutoFitThreshold(Bitmap b)
{
// 图像灰度化
b = Gray(b);
// 建立直方图,并获取灰度统计信息
Histogram histogram = new Histogram(b);
int[] GrayLevel = histogram.Red.Value;
int peak1, peak2, valley;
int peak1Index, peak2Index, valleyIndex;
// 取双峰
peak1 = peak2 = GrayLevel[0];
peak1Index = peak2Index = 0;
for (int i = 1; i < 256; i++)
{
// 如果产生新的高峰,则将第一峰退居第二峰,新的高峰升为第一峰
if (GrayLevel[i] > peak1)
{
peak2 = peak1;
peak2Index = peak1Index;
peak1 = GrayLevel[i];
peak1Index = i;
}
} // i
// 判断两个峰值索引
int max = peak1Index;
int min = peak2Index;
if (max < min)
{
int t = max;
max = min;
min = t;
}
// 取峰谷
valley = GrayLevel[min];
valleyIndex = min;
for (int i = min; i < max; i++)
{
if (GrayLevel[i] < valley)
{
valley = GrayLevel[i];
valleyIndex = i;
}
} // i
// 根据找到的谷值对图像进行二值化
return Threshoding(b, (byte)valleyIndex);
} // end of AutoFitThreshold
#endregion
#region Otsu阈值法二值化模块
/// <summary>
/// Otsu阈值
/// </summary>
/// <param name="b">位图流</param>
/// <returns></returns>
public Bitmap OtsuThreshold(Bitmap b)
{
// 图像灰度化
b = Gray(b);
int width = b.Width;
int height = b.Height;
byte threshold = 0;
int[] hist = new int[256];
int AllPixelNumber = 0, PixelNumberSmall = 0, PixelNumberBig = 0;
double MaxValue, AllSum = 0, SumSmall = 0, SumBig, ProbabilitySmall, ProbabilityBig, Probability;
BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * 4;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
hist[p[0]]++;
p += 4;
}
p += offset;
}
b.UnlockBits(data);
}
//计算灰度为I的像素出现的概率
for (int i = 0; i < 256; i++)
{
AllSum += i * hist[i]; // 质量矩
AllPixelNumber += hist[i]; // 质量
}
MaxValue = -1.0;
for (int i = 0; i < 256; i++)
{
PixelNumberSmall += hist[i];
PixelNumberBig = AllPixelNumber - PixelNumberSmall;
if (PixelNumberBig == 0)
{
break;
}
SumSmall += i * hist[i];
SumBig = AllSum - SumSmall;
ProbabilitySmall = SumSmall / PixelNumberSmall;
ProbabilityBig = SumBig / PixelNumberBig;
Probability = PixelNumberSmall * ProbabilitySmall * ProbabilitySmall + PixelNumberBig * ProbabilityBig * ProbabilityBig;
if (Probability > MaxValue)
{
MaxValue = Probability;
threshold = (byte)i;
}
}
Console.WriteLine("Threshold == " + threshold);
return this.Threshoding(b, threshold);
} // end of OtsuThreshold 2
#endregion
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。