zoukankan      html  css  js  c++  java
  • 基于模糊集理论的一种图像二值化算法的原理、实现效果及代码

      这是篇很古老的论文中的算法,发表与1994年,是清华大学黄良凯(Liang-kai Huang) 所写,因此国外一些论文里和代码里称之为Huang's fuzzy thresholding method。虽然古老也很简单,但是其算法的原理还是值得学习的。

         该论文的原文可从此处下载: Image thresholding by minimizing the measure of fuzziness

         该论文结合了当时处于研究热潮的模糊集理论,提出了一种具有较好效果的图像二值化算法,本文主要是对其进行简单的翻译和注释,并提供了测试代码。

         一、模糊集及其隶属度函数

         首先,我们假定X代表一副大小为M×N的具有L个色阶的灰度图像,而xmn代表图像X中点(m,n)处的像素灰度值,定义μx(xmn)表示该点具有某种属性的隶属度值,也就是说我们定义了一个从图像X映射到[0,1]区间的模糊子集,用专业的模糊集表达,即有:

                                           

           其中0≤μx(xmn)≤1,m=0,1,...M-1,n=0,1,...N-1。对于二值化来说,每个像素对于其所属的类别(前景或背景)都应该有很相近的关系,因此,我们可以这种关系来表示μx(xmn)的值。

           定义h(g)表示图像中具有灰度级g的像素的个数,对于一个给定的阈值t,背景和前景各自色阶值的平均值μ0和μ1可用下式表示:

                                    

                                             

          上述μ0和μ1,可以看成是指定阈值t所对应的前景和背景的目标值,而图像X中某一点和其所述的区域之间的关系,在直觉上应该和该点的色阶值与所属区域的目标值之间的差异相关。因此,对于点(m,n),我们提出如下的隶属度定义函数:

             

      其中C是一个常数,该常数使得0.5≤μx(xmn)≤1。因此,对于一个给定的阈值t,图像中任何一个像素要么属于背景,要么属于前景,因此,每个像素的隶属度不应小于0.5。

         C值在实际的编程中,可以用图像的最大灰度值减去最小灰度值来表达,即 C=gmax-gmin;

      二、模糊度的度量及取阈值的原则

         模糊度表示了一个模糊集的模糊程度,有好几种度量方式已经被提及了,本文仅仅使用了香农熵函数来度量模糊度。

         基于香农熵函数,一个模糊集A的熵定义为:

          

          其中香农函数:

         

          扩展到2维的图像,图像X的熵可以表达为:

        

      因为灰度图像至多只有L个色阶,因此使用直方图式(7)可进一步写成:

            

        可以证明式(6)在区间[0,0.5]之间是单调递增而在[0.5,1]之间是单调递减的,并且E(X)具有以下属性:

         (1)0≤E(X)≤1 ;

          (2)如果μx(xmn)=0或者μx(xmn)=1时,E(X)具有最小值0,在本文中μx(xmn)只可能为1,此时分类具有最好的明确性。

         (3)当μx(xmn)=0.5,E(X)获得最大值1,此时的分类具有最大的不明确性。

         那么对于图像X,我们确定最好的阈值t的原则就是:对于所有的可能的阈值t,取香农熵值最小时的那个t为最终的分割阈值。

         三、编程中的技巧

         有了上述原理,其实编程也是件很容易的事情了,你可以按照你的想法去做,不过作者论文中的阐述会让代码写起来更清晰、更有效。

         首先,为了表达方便,我们定义如下一些表达式:

           

         根据上述表达式,可以知道S(L-1)及W(L-1)对于一副图像来说是个常量,其中S(L-1)明显就是像素的总个数。

      我们的算法步骤如下:

         (1)、计算S(L-1)、W(L-1),设置初始阈值t=gmin,令S(t-1)=0、W(t-1)=0;

          (2)、 计算下面算式:

                   

          稍微有点数学基础的人都应该能看懂上述算式的推导原理。

            根据式(2)和式(3),可以知道背景和前景的区域的平均灰度值为:

             

       上式中int表示取整操作。

           (3)根据式(4)及式(11)计算图像的模糊度;

           (4)令t=t+1,然后重新执行步骤2,直到t=gmax-1;

            (5)找到整个过程中的最小模糊度值对应的阈值t,并作为最佳的分割阈值。

         为了稍微加快点速度,上述式4中的计算可以在步骤1中用一查找表实现。

        四、参考代码:

    public static int GetHuangFuzzyThreshold(int[] HistGram)
    {
        int X, Y;
        int First, Last;
        int Threshold = -1;
        double BestEntropy = Double.MaxValue, Entropy;
        //   找到第一个和最后一个非0的色阶值
        for (First = 0; First < HistGram.Length && HistGram[First] == 0; First++) ;
        for (Last = HistGram.Length - 1; Last > First && HistGram[Last] == 0; Last--) ;
        if (First == Last) return First;                // 图像中只有一个颜色
        if (First + 1 == Last) return First;            // 图像中只有二个颜色
    
        // 计算累计直方图以及对应的带权重的累计直方图
        int[] S = new int[Last + 1];
        int[] W = new int[Last + 1];            // 对于特大图,此数组的保存数据可能会超出int的表示范围,可以考虑用long类型来代替
        S[0] = HistGram[0];
        for (Y = First > 1 ? First : 1; Y <= Last; Y++)
        {
            S[Y] = S[Y - 1] + HistGram[Y];
            W[Y] = W[Y - 1] + Y * HistGram[Y];
        }
    
        // 建立公式(4)及(6)所用的查找表
        double[] Smu = new double[Last + 1 - First];
        for (Y = 1; Y < Smu.Length; Y++)
        {
            double mu = 1 / (1 + (double)Y / (Last - First));               // 公式(4)
            Smu[Y] = -mu * Math.Log(mu) - (1 - mu) * Math.Log(1 - mu);      // 公式(6)
        }
    
        // 迭代计算最佳阈值
        for (Y = First; Y <= Last; Y++)
        {
            Entropy = 0;
            int mu = (int)Math.Round((double)W[Y] / S[Y]);             // 公式17
            for (X = First; X <= Y; X++)
                Entropy += Smu[Math.Abs(X - mu)] * HistGram[X];
            mu = (int)Math.Round((double)(W[Last] - W[Y]) / (S[Last] - S[Y]));  // 公式18
    for (X = Y + 1; X <= Last; X++) Entropy += Smu[Math.Abs(X - mu)] * HistGram[X]; // 公式8 if (BestEntropy > Entropy) { BestEntropy = Entropy; // 取最小熵处为最佳阈值 Threshold = Y; } } return Threshold; }

       代码其实还是很简单的。

       五、效果:

     针对一些图像,我们做了如下测试:

       

                原图                                二值图,阈值=175

       上图使用OSTU等经典算法都无法获得上图的理想效果。

           

                   原图                                   二值图,阈值=67

        上图和其他一些二值算法的效果也是非常类似的。

    *********************************作者: laviewpbt   时间: 2013.9.5    联系QQ:  33184777  转载请保留本行信息************************

  • 相关阅读:
    Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)
    Luogu 1314 【NOIP2011】聪明的质检员 (二分)
    Luogu 1315 【NOIP2011】观光公交 (贪心)
    Luogu 1312 【NOIP2011】玛雅游戏 (搜索)
    Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)
    Luogu 1514 引水入城 (搜索,动态规划)
    UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
    Luogu 1437 [HNOI2004]敲砖块 (动态规划)
    Luogu 1941 【NOIP2014】飞扬的小鸟 (动态规划)
    HDU 1176 免费馅饼 (动态规划)
  • 原文地址:https://www.cnblogs.com/Imageshop/p/3302850.html
Copyright © 2011-2022 走看看