8

Ok, więc mam histogram (reprezentowany przez tablicę int) i szukam najlepszego sposobu na znalezienie lokalnych maksimów i maksimów. Każdy histogram powinien mieć 3 wierzchołki, z których jeden (pierwszy) prawdopodobnie jest znacznie wyższy od pozostałych.Znajdowanie lokalnych maksimów/szczytów i minimów/dolin histogramów

chcę zrobić kilka rzeczy:

  1. Znajdź pierwszy „dolinę” Po raz pierwszy szczyt (aby pozbyć się pierwszego piku całkowicie na zdjęciu)

  2. znaleźć optymalna wartość "doliny" pomiędzy dwoma pozostałymi pikami w celu oddzielenia obrazu

    Już wiem, jak zrobić krok 2, wdrażając wariant Otsu. Ale zmagam się z krokiem 1

  3. W przypadku, gdy dolina pomiędzy dwoma pozostałymi szczytami nie jest wystarczająco niska, chciałbym dać ostrzeżenie.

Ponadto obraz jest bardzo czysty z małym hałasem stanowią

Jaki byłby algorytm brute-force turystyczne kroki 1 i 3? Mógłbym znaleźć sposób na wdrożenie Otsu, ale brutalna siła ucieka mi, matematycznie. Jak się okazuje, jest więcej dokumentacji na temat metod, takich jak otsu, a mniej na po prostu znalezienie szczytów i dolin. Nie szukam niczego więcej niż to, co dostaje pracę (to jest tymczasowe rozwiązanie, musi być możliwe do wdrożenia w rozsądnym czasie, aż będę mógł spędzać na nim więcej czasu)

Robię to wszystko w C#

Każda pomoc, od której należy wykonać czynność, zostanie doceniona! Dziękuję bardzo!

EDIT: kilka danych:

najbardziej histogram mogą być jak pierwsza, z pierwszego piku reprezentujących tło.

Histogram

Histogram 2

+0

mógłbyś podać kilka przykładowych danych proszę? – ose

+0

Czy obszar wokół szczytów wygląda tak, jakby był normalnie rozłożony? Możesz np. dopasuj trzy niezależne normalne dystrybucje do twoich danych. Następnie możesz użyć odchylenia standardowego, aby zdecydować o punktach odcięcia w celu zidentyfikowania szczytów i dolin. – Andreas

+0

Co powiesz na użycie k-środków Algortihm z k = 3, aby uzyskać 3 różne klastry? Każdy środek ciężkości powinien odpowiadać jednemu ze szczytów, jeśli wszystko pójdzie dobrze. – Reinhard

Odpowiedz

4

Zastosowanie peakiness testu. Jest to metoda znalezienia całego możliwego piku między dwoma lokalnymi minima i zmierzenia pikiczności w oparciu o formułę. Jeśli szczytowość jest wyższa niż wartość progowa, pik jest akceptowany.

Źródło: UCF CV CAP5415 lecture 9 slides

Poniżej jest mój kodu:

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; 
} 
Powiązane problemy