using System;
namespace Splash.Imaging
{
/// <summary>
/// 图像处理:大津法二值化阈值计算方法
/// </summary>
public static partial class Binarize
{
/// <summary>
/// 大津法计算阈值
/// </summary>
/// <param name="grayArray">灰度数组</param>
/// <returns>二值化阈值</returns>
public static Int32 OtsuThreshold(Byte[,] grayArray)
{ // 建立统计直方图
Int32[] Histogram = new Int32[256];
Array.Clear(Histogram, 0, 256); // 初始化
foreach (Byte b in grayArray)
{
Histogram[b]++; // 统计直方图
}
// 总的质量矩和图像点数
Int32 SumC = grayArray.Length; // 总的图像点数
Double SumU = 0; // 双精度避免方差运算中数据溢出
for (Int32 i = 1; i < 256; i++)
{
SumU += i * Histogram[i]; // 总的质量矩
}
// 灰度区间
Int32 MinGrayLevel = Array.FindIndex(Histogram, NonZero); // 最小灰度值
Int32 MaxGrayLevel = Array.FindLastIndex(Histogram, NonZero); // 最大灰度值
// 计算最大类间方差
Int32 Threshold = MinGrayLevel;
Double MaxVariance = 0.0; // 初始最大方差
Double U0 = 0; // 初始目标质量矩
Int32 C0 = 0; // 初始目标点数
for (Int32 i = MinGrayLevel; i < MaxGrayLevel; i++)
{
if (Histogram[i] == 0) continue;
// 目标的质量矩和点数
U0 += i * Histogram[i];
C0 += Histogram[i];
// 计算目标和背景的类间方差
Double Diference = U0 * SumC - SumU * C0;
Double Variance = Diference * Diference / C0 / (SumC - C0); // 方差
if (Variance > MaxVariance)
{
MaxVariance = Variance;
Threshold = i;
}
}
// 返回类间方差最大阈值
return Threshold;
}
/// <summary>
/// 检测非零值
/// </summary>
/// <param name="value">要检测的数值</param>
/// <returns>
/// true:非零
/// false:零
/// </returns>
private static Boolean NonZero(Int32 value)
{
return (value != 0) ? true : false;
}
}
}
WPF:图像处理(四)大津法
最新推荐文章于 2019-06-26 16:08:43 发布