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; 
} 
相关问题