8

좋아, 히스토그램 (int 배열로 표시)이 있으며 로컬 최대 값 및 최소값을 찾는 가장 좋은 방법을 찾고 있습니다. 각 히스토그램에는 3 개의 피크가 있어야하며 그 중 하나 (아마도 첫 번째 피크)는 다른 피크보다 훨씬 높습니다.히스토그램의 로컬 최대 값/최대 값 및 최저값 찾기

  1. 최초의 "계곡"(그림에서 모두 첫 번째 피크를 제거하기 위해) 첫 번째 피크를 다음

  2. 는 찾기 찾기 :

    나는 여러 가지 일을 할 나머지 두 개의 피크 사이의 최적의 "계곡"값을 사용하여 그림을 구분합니다.

    이미 Otsu 변형을 구현하여 2 단계를 수행하는 방법을 알고 있습니다. 하지만 1 단계에서 고민 중입니다.

  3. 두 개의 남은 봉우리 사이의 계곡이 충분히 낮지 않은 경우 경고를 보내고 싶습니다.

또한, 이미지는 1 단계와 3을 할 수있는 무차별 알고리즘이 될 것입니다 무엇

설명하기 위해 약간의 노이즈가 매우 깨끗? 나는 오츠 (Otsu)를 구현할 수있는 방법을 찾을 수 있었지만, 짐승 같은 힘이 나를 수학적으로 벗어나고있다. 밝혀진 바와 같이 오츠 (otsu)와 같은 방법을 수행하는 데 대한 문서가 많으며 단순히 봉우리와 계곡을 찾는 데 그다지 도움이되지 않습니다. 나는 무엇이든 일자리를 얻는 것보다 더 많은 것을 찾고 있지 않다. (즉, 일시적인 해결책이다. 더 많은 시간을 할애 할 때까지 합리적인 시간 틀에 구현할 수 있어야한다.)

나는이 모든 것을 C#

어떤 조치를 취해야합니까? 정말 고마워요!

EDIT : 좀 더 많은 데이터 :

가장 히스토그램 배경을 나타내는 제 1 피크와 제처럼 될 가능성이있다.

Histogram

Histogram 2

+0

당신이 몇 가지 예제 데이터를 제공 할 수주십시오? – ose

+0

봉우리 주변이 일반 분포처럼 보입니까? 예 : 세 개의 독립적 인 정규 분포를 데이터에 맞추십시오. 그런 다음 표준 편차를 사용하여 절점을 결정하여 봉우리와 계곡을 식별 할 수 있습니다. – Andreas

+0

3 개의 다른 클러스터를 얻기 위해 k = 3 인 Algorithm을 사용하는 것은 어떻습니까? 일이 잘 진행되면 각 중심점이 봉우리 중 하나와 일치해야합니다. – Reinhard

답변

4

사용 (Peakiness)의 테스트. 이 방법은 두 개의 로컬 미니 마 사이에서 가능한 피크를 모두 찾아 수식을 기반으로 피크를 측정하는 방법입니다. 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; 
}