8

好吧,我有一個直方圖(用一列整數表示),我正在尋找找到局部最大值和最小值的最佳方法。每個直方圖應該有3個峯值,其中一個(第一個)可能比其他峯值高得多。找到直方圖的局部最大值/峯值和最小值/谷值

我想要做的幾件事情:

  1. 找到的第一個「谷」之後的第一個高峯(爲了獲得在畫面完全擺脫了第一個高峯)

  2. 找到在剩下的兩個峯值之間的最佳「谷值」將圖片分開

    我已經知道如何通過實現Otsu的變體來執行第2步。 但我正在努力與第1步

  3. 如果在其餘兩個峯之間的山谷不夠低,我想提出警告。

此外,圖像噪音小挺乾淨佔

是什麼蠻力算法來執行步驟1和3?我可以找到實現大津的方法,但是數學上來說,這種蠻力正在逃避我。事實證明,有更多關於做otsu方法的文檔,而不是簡單地找到高峯和低谷。我不是在尋找任何東西,而不僅僅是完成任何工作(即它是一個臨時解決方案,只能在合理的時間段內實施,直到我可以花費更多時間)

我正在做所有這些在c#

任何幫助,採取的步驟將不勝感激! 非常感謝!

編輯:一些更多的數據:

最直方圖可能是像第一個,與表示背景的第一峯值。

Histogram

Histogram 2

+0

你能給一些示例數據嗎? – ose

+0

峯周圍的區域是否看起來像正常分佈?你可以例如使三個獨立的正態分佈符合您的數據。然後,您可以使用標準偏差來確定截止點以確定您的山峯和山谷。 – Andreas

+0

使用k = 3的k-means Algortihm來獲得3個不同的簇是怎樣的?如果事情順利的話,每個質心應該對應一個峯值。 – Reinhard

回答

4

使用peakiness測試。這是一種找到兩個局部最小值之間的所有可能峯值的方法,並根據公式測量峯值。如果峯值高於閾值,峯值被接受。

來源:UCF CV CAP5415 lecture 9 slides

下面是我的代碼:

public static List<int> PeakinessTest(int[] histogram, double peakinessThres) 
{ 
    int j=0; 
    List<int> valleys = new List<int>(); 

    //The start of the valley 
    int vA = histogram[j]; 
    int P = vA; 

    //The end of the valley 
    int vB = 0; 

    //The width of the valley, default width is 1 
    int W = 1; 

    //The sum of the pixels between vA and vB 
    int N = 0; 

    //The measure of the peaks peakiness 
    double peakiness=0.0; 

    int peak=0; 
    bool l = false; 

    try 
    { 
     while (j < 254) 
     { 

      l = false; 
      vA = histogram[j]; 
      P = vA; 
      W = 1; 
      N = vA; 

      int i = j + 1; 

      //To find the peak 
      while (P < histogram[i]) 
      { 
       P = histogram[i]; 
       W++; 
       N += histogram[i]; 
       i++; 
      } 


      //To find the border of the valley other side 
      peak = i - 1; 
      vB = histogram[i]; 
      N += histogram[i]; 
      i++; 
      W++; 

      l = true; 
      while (vB >= histogram[i]) 
      { 
       vB = histogram[i]; 
       W++; 
       N += histogram[i]; 
       i++; 
      } 

       //Calculate peakiness 
      peakiness = (1 - (double)((vA + vB)/(2.0 * P))) * (1 - ((double)N/(double)(W * P))); 

      if (peakiness > peakinessThres & !valleys.Contains(j)) 
      { 
       //peaks.Add(peak);       
       valleys.Add(j); 
       valleys.Add(i - 1); 
      } 

      j = i - 1; 
     } 
    } 
    catch (Exception) 
    { 
     if (l) 
     { 
      vB = histogram[255]; 

      peakiness = (1 - (double)((vA + vB)/(2.0 * P))) * (1 - ((double)N/(double)(W * P))); 

      if (peakiness > peakinessThres) 
       valleys.Add(255); 

       //peaks.Add(255); 
      return valleys; 
     } 
    } 

     //if(!valleys.Contains(255)) 
     // valleys.Add(255); 

    return valleys; 
} 
相關問題