1. 程式人生 > >模糊集理論在影象處理中的應用

模糊集理論在影象處理中的應用


本文選自:http://www.cnblogs.com/Imageshop/p/3302850.html,作者寫的非常不錯,包括另外一篇文章:http://www.cnblogs.com/Imageshop/p/3307308.html,感謝作者的辛勤勞動!自己整理過來備份。


這是篇很古老的論文中的演算法,發表與1994年,是清華大學黃良凱(Liang-kai Huang) 所寫,因此國外一些論文裡和程式碼裡稱之為Huang's fuzzy thresholding method。雖然古老也很簡單,但是其演算法的原理還是值得學習的。

該論文的原文可從此處下載: Image thresholding by minimizing the measure of fuzziness

     該論文結合了當時處於研究熱潮的模糊集理論,提出了一種具有較好效果的影象二值化演算法,本文主要是對其進行簡單的翻譯和註釋,並提供了測試程式碼。



程式碼:說明的是,原作者給出的是針對直方圖投影進行處理的函式,函式輸入引數是直方圖投影圖。

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;
}