图像二值化的目的是最大限度的将图象中感兴趣的部分保留下来,在很多情况下,也是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。这个看似简单的问题,在过去的四十年里受到国内外学者的广泛关注,产生了数以百计的阈值选取方法,但如同其他图像分割算法一样,没有一个现有方法对各种各样的图像都能得到令人满意的结果。

在这些庞大的分类方法中,基于直方图的全局二值算法占有了绝对的市场份额,这些算法都从不同的科学层次提出了各自的实施方案,并且这类方法都有着一些共同的特点:

  1、简单;

2、算法容易实现;

3、执行速度快。

本文摘取了若干种这类方法进行了介绍。

  一:灰度平局值值法:

  1、描述:即使用整幅图像的灰度平均值作为二值化的阈值,一般该方法可作为其他方法的初始猜想值。

  2、原理:   

       

3、实现代码:

 public static int GetMeanThreshold(int[] HistGram){int Sum = 0, Amount = 0;for (int Y = 0; Y < 256; Y++){Amount += HistGram[Y];Sum += Y * HistGram[Y];}return Sum / Amount;}

二、百分比阈值(P-Tile法)

1、描述

Doyle于1962年提出的P-Tile (即P分位数法)可以说是最古老的一种阈值选取方法。该方法根据先验概率来设定阈值,使得二值化后的目标或背景像素比例等于先验概率,该方法简单高效,但是对于先验概率难于估计的图像却无能为力。

  2、该原理比较简单,直接以代码实现。

    /// <summary>/// 百分比阈值/// </summary>/// <param name="HistGram">灰度图像的直方图</param>/// <param name="Tile">背景在图像中所占的面积百分比</param>/// <returns></returns>public static int GetPTileThreshold(int[] HistGram, int Tile = 50){int Y, Amount = 0, Sum = 0;for (Y = 0; Y < 256; Y++) Amount += HistGram[Y];        //  像素总数for (Y = 0; Y < 256; Y++){Sum = Sum + HistGram[Y];if (Sum >= Amount * Tile / 100) return Y;}return -1;}

      三、基于谷底最小值的阈值

     1、描述:

  此方法实用于具有明显双峰直方图的图像,其寻找双峰的谷底作为阈值,但是该方法不一定能获得阈值,对于那些具有平坦的直方图或单峰图像,该方法不合适。

  2、实现过程:

  该函数的实现是一个迭代的过程,每次处理前对直方图数据进行判断,看其是否已经是一个双峰的直方图,如果不是,则对直方图数据进行半径为1(窗口大小为3)的平滑,如果迭代了一定的数量比如1000次后仍未获得一个双峰的直方图,则函数执行失败,如成功获得,则最终阈值取两个双峰之间的谷底值作为阈值。

注意在编码过程中,平滑的处理需要当前像素之前的信息,因此需要对平滑前的数据进行一个备份。另外,首数据类型精度限制,不应用整形的直方图数据,必须转换为浮点类型数据来进行处理,否则得不到正确的结果。

该算法相关参考论文如下:

   J. M. S. Prewitt and M. L. Mendelsohn, "The analysis of cell images," innnals of the New York Academy of Sciences, vol. 128, pp. 1035-1053, 1966.
     C. A. Glasbey, "An analysis of histogram-based thresholding algorithms," CVGIP: Graphical Models and Image Processing, vol. 55, pp. 532-537, 1993.

3、实现代码:

    public static int GetMinimumThreshold(int[] HistGram){int Y, Iter = 0;double[] HistGramC = new double[256];           // 基于精度问题,一定要用浮点数来处理,否则得不到正确的结果double[] HistGramCC = new double[256];          // 求均值的过程会破坏前面的数据,因此需要两份数据for (Y = 0; Y < 256; Y++){HistGramC[Y] = HistGram[Y];HistGramCC[Y] = HistGram[Y];}// 通过三点求均值来平滑直方图while (IsDimodal(HistGramCC) == false)                                        // 判断是否已经是双峰的图像了
        {HistGramCC[0] = (HistGramC[0] + HistGramC[0] + HistGramC[1]) / 3;                 // 第一点for (Y = 1; Y < 255; Y++)HistGramCC[Y] = (HistGramC[Y - 1] + HistGramC[Y] + HistGramC[Y + 1]) / 3;     // 中间的点HistGramCC[255] = (HistGramC[254] + HistGramC[255] + HistGramC[255]) / 3;         // 最后一点System.Buffer.BlockCopy(HistGramCC, 0, HistGramC, 0, 256 * sizeof(double));Iter++;if (Iter >= 1000) return -1;                                                   // 直方图无法平滑为双峰的,返回错误代码
        }// 阈值极为两峰之间的最小值 bool Peakfound = false;for (Y = 1; Y < 255; Y++){if (HistGramCC[Y - 1] < HistGramCC[Y] && HistGramCC[Y + 1] < HistGramCC[Y]) Peakfound = true;if (Peakfound == true && HistGramCC[Y - 1] >= HistGramCC[Y] && HistGramCC[Y + 1] >= HistGramCC[Y])return Y - 1;}return -1;}

  其中IsDimodal函数为判断直方图是否是双峰的函数,代码如下:

    private static bool IsDimodal(double[] HistGram)       // 检测直方图是否为双峰的
    {// 对直方图的峰进行计数,只有峰数位2才为双峰 int Count = 0;for (int Y = 1; Y < 255; Y++){if (HistGram[Y - 1] < HistGram[Y] && HistGram[Y + 1] < HistGram[Y]){Count++;if (Count > 2) return false;}}if (Count == 2)return true;elsereturn false;}

  4、效果:

   

    

        原图                                                 二值图                                          原始直方图                平滑后的直方图

  对于这种有较明显的双峰的图像,该算法还是能取得不错的效果的。

四、基于双峰平均值的阈值

       1、描述:

  该算法和基于谷底最小值的阈值方法类似,只是最后一步不是取得双峰之间的谷底值,而是取双峰的平均值作为阈值。

2、参考代码:

 public static int GetIntermodesThreshold(int[] HistGram){int Y, Iter = 0, Index;double[] HistGramC = new double[256];           // 基于精度问题,一定要用浮点数来处理,否则得不到正确的结果double[] HistGramCC = new double[256];          // 求均值的过程会破坏前面的数据,因此需要两份数据for (Y = 0; Y < 256; Y++){HistGramC[Y] = HistGram[Y];HistGramCC[Y] = HistGram[Y];}// 通过三点求均值来平滑直方图while (IsDimodal(HistGramCC) == false)                                                  // 判断是否已经是双峰的图像了
        {HistGramCC[0] = (HistGramC[0] + HistGramC[0] + HistGramC[1]) / 3;                   // 第一点for (Y = 1; Y < 255; Y++)HistGramCC[Y] = (HistGramC[Y - 1] + HistGramC[Y] + HistGramC[Y + 1]) / 3;       // 中间的点HistGramCC[255] = (HistGramC[254] + HistGramC[255] + HistGramC[255]) / 3;           // 最后一点System.Buffer.BlockCopy(HistGramCC, 0, HistGramC, 0, 256 * sizeof(double));         // 备份数据,为下一次迭代做准备Iter++;if (Iter >= 10000) return -1;                                                       // 似乎直方图无法平滑为双峰的,返回错误代码
        }
// 阈值为两峰值的平均值int[] Peak = new int[2];for (Y = 1, Index = 0; Y < 255; Y++)if (HistGramCC[Y - 1] < HistGramCC[Y] && HistGramCC[Y + 1] < HistGramCC[Y]) Peak[Index++] = Y - 1;return ((Peak[0] + Peak[1]) / 2);}

3、效果:

     

       原图                                                 二值图                                           原始直方图                平滑后的直方图

五、迭代最佳阈值

  1、描述:

该算法先假定一个阈值,然后计算在该阈值下的前景和背景的中心值,当前景和背景中心值得平均值和假定的阈值相同时,则迭代中止,并以此值为阈值进行二值化。

2、实现过程:

  (1)求出图象的最大灰度值和最小灰度值,分别记为gl和gu,令初始阈值为:

(2) 根据阈值T0将图象分割为前景和背景,分别求出两者的平均灰度值Ab和Af:

              

(3) 令

    如果Tk=Tk+1,则取Tk为所求得的阈值,否则,转2继续迭代。

3、参考代码:

    public static int GetIterativeBestThreshold(int[] HistGram){int X, Iter = 0;int MeanValueOne, MeanValueTwo, SumOne, SumTwo, SumIntegralOne, SumIntegralTwo;int MinValue, MaxValue;int Threshold, NewThreshold;for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++) ;for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--) ;if (MaxValue == MinValue) return MaxValue;          // 图像中只有一个颜色             if (MinValue + 1 == MaxValue) return MinValue;      // 图像中只有二个颜色
Threshold = MinValue;NewThreshold = (MaxValue + MinValue) >> 1;while (Threshold != NewThreshold)    // 当前后两次迭代的获得阈值相同时,结束迭代
        {SumOne = 0; SumIntegralOne = 0;SumTwo = 0; SumIntegralTwo = 0;Threshold = NewThreshold;for (X = MinValue; X <= Threshold; X++)         //根据阈值将图像分割成目标和背景两部分,求出两部分的平均灰度值
            {SumIntegralOne += HistGram[X] * X;SumOne += HistGram[X];}MeanValueOne = SumIntegralOne / SumOne;for (X = Threshold + 1; X <= MaxValue; X++){SumIntegralTwo += HistGram[X] * X;SumTwo += HistGram[X];}MeanValueTwo = SumIntegralTwo / SumTwo;NewThreshold = (MeanValueOne + MeanValueTwo) >> 1;       //求出新的阈值Iter++;if (Iter >= 1000) return -1;}return Threshold;}

  4、效果:

                

                

       原图                                          二值图                                         直方图 

六、OSTU大律法

  1、描述:

该算法是1979年由日本大津提出的,主要是思想是取某个阈值,使得前景和背景两类的类间方差最大,matlab中的graythresh即是以该算法为原理执行的。

2、原理:

关于该算法的原理,网络上有很多,这里为了篇幅有限,不加以赘述。

3、参考代码:

    public static int GetOSTUThreshold(int[] HistGram){int X, Y, Amount = 0;int PixelBack = 0, PixelFore = 0, PixelIntegralBack = 0, PixelIntegralFore = 0, PixelIntegral = 0;double OmegaBack, OmegaFore, MicroBack, MicroFore, SigmaB, Sigma;              // 类间方差;int MinValue, MaxValue;int Threshold = 0;for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++) ;for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--) ;if (MaxValue == MinValue) return MaxValue;          // 图像中只有一个颜色             if (MinValue + 1 == MaxValue) return MinValue;      // 图像中只有二个颜色for (Y = MinValue; Y <= MaxValue; Y++) Amount += HistGram[Y];        //  像素总数
PixelIntegral = 0;for (Y = MinValue; Y <= MaxValue; Y++) PixelIntegral += HistGram[Y] * Y;SigmaB = -1;for (Y = MinValue; Y < MaxValue; Y++){PixelBack = PixelBack + HistGram[Y];PixelFore = Amount - PixelBack;OmegaBack = (double)PixelBack / Amount;OmegaFore = (double)PixelFore / Amount;PixelIntegralBack += HistGram[Y] * Y;PixelIntegralFore = PixelIntegral - PixelIntegralBack;MicroBack = (double)PixelIntegralBack / PixelBack;MicroFore = (double)PixelIntegralFore / PixelFore;Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore);if (Sigma > SigmaB){SigmaB = Sigma;Threshold = Y;}}return Threshold;}

  4、效果:

            

  该算法对于那些具有平坦的直方图的图像具有一定的适应能力。

、一维最大熵

      1、描述:

该算法把信息论中熵的概念引入到图像中,通过计算阈值分割后两部分熵的和来判断阈值是否为最佳阈值。

2、算法原理

这方面的文章也比较多,留给读者自行去查找相关资料。

3、参考代码:

public static int Get1DMaxEntropyThreshold(int[] HistGram){int  X, Y,Amount=0;double[] HistGramD = new double[256];double SumIntegral, EntropyBack, EntropyFore, MaxEntropy;int MinValue = 255, MaxValue = 0;int Threshold = 0;for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++) ;for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--) ;if (MaxValue == MinValue) return MaxValue;          // 图像中只有一个颜色             if (MinValue + 1 == MaxValue) return MinValue;      // 图像中只有二个颜色for (Y = MinValue; Y <= MaxValue; Y++) Amount += HistGram[Y];        //  像素总数for (Y = MinValue; Y <= MaxValue; Y++)   HistGramD[Y] = (double)HistGram[Y] / Amount+1e-17;MaxEntropy = double.MinValue; ;for (Y = MinValue + 1; Y < MaxValue; Y++){SumIntegral = 0;for (X = MinValue; X <= Y; X++) SumIntegral += HistGramD[X];EntropyBack = 0;for (X = MinValue; X <= Y; X++) EntropyBack += (-HistGramD[X] / SumIntegral * Math.Log(HistGramD[X] / SumIntegral));EntropyFore = 0;for (X = Y + 1; X <= MaxValue; X++) EntropyFore += (-HistGramD[X] / (1 - SumIntegral) * Math.Log(HistGramD[X] / (1 - SumIntegral)));if (MaxEntropy < EntropyBack + EntropyFore){Threshold = Y;MaxEntropy = EntropyBack + EntropyFore;}}return Threshold;}

八、力矩保持法 
     1、描述:

  该算法通过选择恰当的阈值从而使得二值后的图像和原始的灰度图像具有三个相同的初始力矩值。

  2、原理:

 参考论文:W. Tsai, “Moment-preserving thresholding: a new approach,” Comput.Vision Graphics Image Process., vol. 29, pp. 377-393, 1985.

由于无法下载到该论文(收费的),仅仅给出从其他一些资料中找到的公式共享一下。

其中的A\B\C的函数可见代码部分。

3、参考代码:

public static byte GetMomentPreservingThreshold(int[] HistGram){int X, Y, Index = 0, Amount=0;double[] Avec = new double[256];double X2, X1, X0, Min;for (Y = 0; Y <= 255; Y++) Amount += HistGram[Y];        //  像素总数for (Y = 0; Y < 256; Y++) Avec[Y] = (double)A(HistGram, Y) / Amount;       // The threshold is chosen such that A(y,t)/A(y,n) is closest to x0.// The following finds x0.
X2 = (double)(B(HistGram, 255) * C(HistGram, 255) - A(HistGram, 255) * D(HistGram, 255)) / (double)(A(HistGram, 255) * C(HistGram, 255) - B(HistGram, 255) * B(HistGram, 255));X1 = (double)(B(HistGram, 255) * D(HistGram, 255) - C(HistGram, 255) * C(HistGram, 255)) / (double)(A(HistGram, 255) * C(HistGram, 255) - B(HistGram, 255) * B(HistGram, 255));X0 = 0.5 - (B(HistGram, 255) / A(HistGram, 255) + X2 / 2) / Math.Sqrt(X2 * X2 - 4 * X1);for (Y = 0, Min = double.MaxValue; Y < 256; Y++){if (Math.Abs(Avec[Y] - X0) < Min){Min = Math.Abs(Avec[Y] - X0);Index = Y;}}return (byte)Index;}private static double A(int[] HistGram, int Index){double Sum = 0;for (int Y = 0; Y <= Index; Y++)Sum += HistGram[Y];return Sum;}private static double B(int[] HistGram, int Index){double Sum = 0;for (int Y = 0; Y <= Index; Y++)Sum += (double)Y * HistGram[Y];return Sum;}private static double C(int[] HistGram, int Index){double Sum = 0;for (int Y = 0; Y <= Index; Y++)Sum += (double)Y * Y * HistGram[Y];return Sum;}private static double D(int[] HistGram, int Index){double Sum = 0;for (int Y = 0; Y <= Index; Y++)Sum += (double)Y * Y * Y * HistGram[Y];return Sum;}

对于很多图像,该算法也能取得比较满意的结果。

   九、基于模糊集理论的阈值

该算法的具体分析可见:基于模糊集理论的一种图像二值化算法的原理、实现效果及代码

此法也借用香农熵的概念,该算法一般都能获得较为理想的分割效果,不管是对双峰的还是单峰的图像。

十、Kittler最小错误分类法

由于精力有限,以下几种算法仅仅给出算法的论文及相关的代码。

该算法具体的分析见:

  • Kittler, J & Illingworth, J (1986), "Minimum error thresholding", Pattern Recognition 19: 41-47

  参考代码:

 public static int GetKittlerMinError(int[] HistGram){int X, Y;int MinValue, MaxValue;int Threshold ;int PixelBack, PixelFore;double OmegaBack, OmegaFore, MinSigma, Sigma, SigmaBack, SigmaFore;for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++) ;for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--) ;if (MaxValue == MinValue) return MaxValue;          // 图像中只有一个颜色             if (MinValue + 1 == MaxValue) return MinValue;      // 图像中只有二个颜色Threshold = -1;MinSigma = 1E+20;for (Y = MinValue; Y < MaxValue; Y++){PixelBack = 0; PixelFore = 0;OmegaBack = 0; OmegaFore = 0;for (X = MinValue; X <= Y; X++){PixelBack += HistGram[X];OmegaBack = OmegaBack + X * HistGram[X];}for (X = Y + 1; X <= MaxValue; X++){PixelFore += HistGram[X];OmegaFore = OmegaFore + X * HistGram[X];}OmegaBack = OmegaBack / PixelBack;OmegaFore = OmegaFore / PixelFore;SigmaBack = 0; SigmaFore = 0;for (X = MinValue; X <= Y; X++) SigmaBack = SigmaBack + (X - OmegaBack) * (X - OmegaBack) * HistGram[X];for (X = Y + 1; X <= MaxValue; X++) SigmaFore = SigmaFore + (X - OmegaFore) * (X - OmegaFore) * HistGram[X];if (SigmaBack == 0 || SigmaFore == 0){if (Threshold == -1)Threshold = Y;}else{SigmaBack = Math.Sqrt(SigmaBack / PixelBack);SigmaFore = Math.Sqrt(SigmaFore / PixelFore);Sigma = 1 + 2 * (PixelBack * Math.Log(SigmaBack / PixelBack) + PixelFore * Math.Log(SigmaFore / PixelFore));if (Sigma < MinSigma){MinSigma = Sigma;Threshold = Y;}}}return Threshold;}

  从实际的运行效果看,该算法并不很好。

  十一:ISODATA(也叫做intermeans法)

  参考论文:

  • Ridler, TW & Calvard, S (1978), "Picture thresholding using an iterative selection method", IEEE Transactions on Systems, Man and Cybernetics 8: 630-632, <http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=4310039>

参考代码(未做整理):

 // Also called intermeans// Iterative procedure based on the isodata algorithm [T.W. Ridler, S. Calvard, Picture // thresholding using an iterative selection method, IEEE Trans. System, Man and // Cybernetics, SMC-8 (1978) 630-632.] // The procedure divides the image into objects and background by taking an initial threshold,// then the averages of the pixels at or below the threshold and pixels above are computed. // The averages of those two values are computed, the threshold is incremented and the // process is repeated until the threshold is larger than the composite average. That is,//  threshold = (average background + average objects)/2// The code in ImageJ that implements this function is the getAutoThreshold() method in the ImageProcessor class. //// From: Tim Morris (dtm@ap.co.umist.ac.uk)// Subject: Re: Thresholding method?// posted to sci.image.processing on 1996/06/24// The algorithm implemented in NIH Image sets the threshold as that grey// value, G, for which the average of the averages of the grey values// below and above G is equal to G. It does this by initialising G to the// lowest sensible value and iterating:// L = the average grey value of pixels with intensities < G// H = the average grey value of pixels with intensities > G// is G = (L + H)/2?// yes => exit// no => increment G and repeat//// There is a discrepancy with IJ because they are slightly different methodspublic static int GetIsoDataThreshold(int[] HistGram){int i, l, toth, totl, h, g = 0;for (i = 1; i < HistGram.Length; i++){if (HistGram[i] > 0){g = i + 1;break;}}while (true){l = 0;totl = 0;for (i = 0; i < g; i++){totl = totl + HistGram[i];l = l + (HistGram[i] * i);}h = 0;toth = 0;for (i = g + 1; i < HistGram.Length; i++){toth += HistGram[i];h += (HistGram[i] * i);}if (totl > 0 && toth > 0){l /= totl;h /= toth;if (g == (int)Math.Round((l + h) / 2.0))break;}g++;if (g > HistGram.Length - 2){return 0;}}return g;}

    十二、Shanbhag 法

        参考论文:

      Shanbhag, Abhijit G. (1994), "Utilization of information measure as a means of image thresholding", Graph. Models Image Process. (Academic Press, Inc.) 56 (5): 414--419, ISSN 1049-9652, DOI 10.1006/cgip.1994.1037

参考代码(未整理):

public static int GetShanbhagThreshold(int[] HistGram){int threshold;int ih, it;int first_bin;int last_bin;double term;double tot_ent;  /* total entropy */double min_ent;  /* max entropy */double ent_back; /* entropy of the background pixels at a given threshold */double ent_obj;  /* entropy of the object pixels at a given threshold */double[] norm_histo = new double[HistGram.Length]; /* normalized histogram */double[] P1 = new double[HistGram.Length]; /* cumulative normalized histogram */double[] P2 = new double[HistGram.Length];int total = 0;for (ih = 0; ih < HistGram.Length; ih++)total += HistGram[ih];for (ih = 0; ih < HistGram.Length; ih++)norm_histo[ih] = (double)HistGram[ih] / total;P1[0] = norm_histo[0];P2[0] = 1.0 - P1[0];for (ih = 1; ih < HistGram.Length; ih++){P1[ih] = P1[ih - 1] + norm_histo[ih];P2[ih] = 1.0 - P1[ih];}/* Determine the first non-zero bin */first_bin = 0;for (ih = 0; ih < HistGram.Length; ih++){if (!(Math.Abs(P1[ih]) < 2.220446049250313E-16)){first_bin = ih;break;}}/* Determine the last non-zero bin */last_bin = HistGram.Length - 1;for (ih = HistGram.Length - 1; ih >= first_bin; ih--){if (!(Math.Abs(P2[ih]) < 2.220446049250313E-16)){last_bin = ih;break;}}// Calculate the total entropy each gray-level// and find the threshold that maximizes it threshold = -1;min_ent = Double.MaxValue;for (it = first_bin; it <= last_bin; it++){/* Entropy of the background pixels */ent_back = 0.0;term = 0.5 / P1[it];for (ih = 1; ih <= it; ih++){ //0+1?ent_back -= norm_histo[ih] * Math.Log(1.0 - term * P1[ih - 1]);}ent_back *= term;/* Entropy of the object pixels */ent_obj = 0.0;term = 0.5 / P2[it];for (ih = it + 1; ih < HistGram.Length; ih++){ent_obj -= norm_histo[ih] * Math.Log(1.0 - term * P2[ih]);}ent_obj *= term;/* Total entropy */tot_ent = Math.Abs(ent_back - ent_obj);if (tot_ent < min_ent){min_ent = tot_ent;threshold = it;}}return threshold;}

     十三、Yen法

  参考论文:

1) Yen J.C., Chang F.J., and Chang S. (1995) "A New Criterion  for Automatic Multilevel Thresholding" IEEE Trans. on Image  Processing, 4(3): 370-378
     2) Sezgin M. and Sankur B. (2004) "Survey over Image Thresholding Techniques and Quantitative Performance Evaluation" Journal of  Electronic Imaging, 13(1): 146-165

参考代码(未整理):

 // M. Emre Celebi// 06.15.2007// Ported to ImageJ plugin by G.Landini from E Celebi's fourier_0.8 routinespublic static int GetYenThreshold(int[] HistGram){int threshold;int ih, it;double crit;double max_crit;double[] norm_histo = new double[HistGram.Length]; /* normalized histogram */double[] P1 = new double[HistGram.Length]; /* cumulative normalized histogram */double[] P1_sq = new double[HistGram.Length];double[] P2_sq = new double[HistGram.Length];int total = 0;for (ih = 0; ih < HistGram.Length; ih++)total += HistGram[ih];for (ih = 0; ih < HistGram.Length; ih++)norm_histo[ih] = (double)HistGram[ih] / total;P1[0] = norm_histo[0];for (ih = 1; ih < HistGram.Length; ih++)P1[ih] = P1[ih - 1] + norm_histo[ih];P1_sq[0] = norm_histo[0] * norm_histo[0];for (ih = 1; ih < HistGram.Length; ih++)P1_sq[ih] = P1_sq[ih - 1] + norm_histo[ih] * norm_histo[ih];P2_sq[HistGram.Length - 1] = 0.0;for (ih = HistGram.Length - 2; ih >= 0; ih--)P2_sq[ih] = P2_sq[ih + 1] + norm_histo[ih + 1] * norm_histo[ih + 1];/* Find the threshold that maximizes the criterion */threshold = -1;max_crit = Double.MinValue;for (it = 0; it < HistGram.Length; it++){crit = -1.0 * ((P1_sq[it] * P2_sq[it]) > 0.0 ? Math.Log(P1_sq[it] * P2_sq[it]) : 0.0) + 2 * ((P1[it] * (1.0 - P1[it])) > 0.0 ? Math.Log(P1[it] * (1.0 - P1[it])) : 0.0);if (crit > max_crit){max_crit = crit;threshold = it;}}return threshold;}

一行很多代码是摘自开源软件ImageJ的资料,读者也可以参考:http://fiji.sc/wiki/index.php/Auto_Threshold  这里获得更多的信息。

最后,我对这些算法的做了简单的UI界面,供有兴趣的读者参考。

工程代码下载:http://files.cnblogs.com/Imageshop/HistgramBinaryzation.rar

十三种基于直方图的图像全局二值化算法原理、实现、代码及效果。相关推荐

  1. 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果(转)

    源:十三种基于直方图的图像全局二值化算法原理.实现.代码及效果.

  2. 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果

    十三种基于直方图的图像全局二值化算法实现 1. 什么是基于直方图的图像全局二值化算法 2. 灰度平均值 3. 百分比阈值(P-Tile法) 3. 基于双峰的阈值 3.1 基于平均值的阈值 3.2 基于 ...

  3. 基于直方图的图像全局二值化算法原理、实现--基于谷底最小值的阈值

    1.描述: 此方法实用于具有明显双峰直方图的图像,其寻找双峰的谷底作为阈值,但是该方法不一定能获得阈值,对于那些具有平坦的直方图或单峰图像,该方法不合适. 2.实现过程: 该函数的实现是一个迭代的过程 ...

  4. 场景文本检测算法 可微分二值化DBNet原理与代码解析

    目录 原理介绍 Label Generation Loss函数 后处理 论文 https://arxiv.org/abs/1911.08947 代码 https://github.com/WenmuZ ...

  5. matlab最小分类错误全局二值化算法

    转自:http://download.csdn.net/detail/hupeng810/1511870 function imagBW = kittlerMet(imag) % KITTLERMET ...

  6. matlab确定灰度阈值T,matlab灰度图像二值化【灰度图像二值化算法研究】

    摘要: 在很多图像处理的过程中,经常需要对灰度图像进行二值化.本文对几种常用的图像二值化算法进行了阐述,并通过仿真,进行比较研究.根据实验结果,阐明了各种算法的优缺点. Abstract: The b ...

  7. 二值化算法OTSU源码解析

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 概述: 本文中小编将会跟大家分享一下OpenCV3.1.0中图像二 ...

  8. 【图像处理】——图像的二值化操作及阈值化操作(固定阈值法(全局阈值法——大津法OTSU和三角法TRIANGLE)和自适应阈值法(局部阈值法——均值和高斯法))

    目录 一.二值化的概念(实际上就是一个阈值化操作) 1.概念: 2.实现方法 3.常用方法 二.阈值类型 1.常见阈值类型(主要有五种类型) (1)公式描述 (2)图表描述 2.两种特殊的阈值算法(O ...

  9. python-opencv 图像阈值二值化

    本文讲解基于OpenCV-python的图像二值化API及浅显原理讲解 文章目录 一. 阈值 1. 简单阈值 2. 自适应阈值 二. 图像二值化 1. 全局图像二值化 2. 局部图像二值化 3. Ot ...

最新文章

  1. python 中文编码差异_Python 编码为什么那么蛋疼?
  2. 用C++11的std::async代替线程的创建
  3. OpenShift 4 - 用 Operator 创建 Jenkins 环境
  4. 【数据结构】【未完成】单调栈
  5. java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...
  6. PHP 订单拆单后明细总金额与订单金额存在差异
  7. MFC开发环境搭建(顺便来个Helloworld)
  8. 使用python来完成对QQ邮箱文件中转站的文件下载链接的获取
  9. Excle之说(2)-如何读“excel”
  10. 实践练习二(必选):手动部署 OceanBase 三副本集群(在同一个节点)
  11. 【Auto.js教程】Auto.js入门及第一个示例程序
  12. 外接显示器如何调整亮度
  13. [经典模型] 4. 图与网络模型及方法
  14. 修改java游戏分辨率怎么调_怎么修改jar游戏的分辨率
  15. 力促产学研结合 中国医学人工智能大会圆满落幕
  16. HTML之Data attributes
  17. 如何利用计算机求函数解析式,数据结构表达式求值(计算器)实验报告(共10篇).doc...
  18. 国内外知名云服务公司介绍
  19. Jmeter做压力测试
  20. 私募量化对冲:百舸争流,高频当道

热门文章

  1. SQL Server 2008新特性——SSMS增强
  2. 在eclipse中配置android ndk的自动编译环境builders
  3. 一地鸡毛 OR 绝地反击,2019年区块链发展指南
  4. 存储器芯片国产化布局加速 数千亿投资欲打破进口依赖
  5. 教你打造千万用户的海量视频网站、保卫云端安全!
  6. Webx示例-PetStore分析1
  7. 介绍几个好用的android自定义控件
  8. 我已经把servlet-api.jar加到classpath中了,可还是无法编译servlet
  9. ERP_Oracle Erp 11i 和 R12的区别概述(概念)
  10. android之Fragment(官网资料翻译)二