【问题标题】:Finding the local maxima/peaks and minima/valleys of histograms查找直方图的局部最大值/峰值和最小值/谷值
【发布时间】:2012-11-21 14:01:15
【问题描述】:

好的,所以我有一个直方图(由整数数组表示),我正在寻找找到局部最大值和最小值的最佳方法。每个直方图应该有 3 个峰值,其中一个(第一个)可能比其他峰值高很多。

我想做几件事:

  1. 在第一个峰之后找到第一个“山谷”(为了在图中完全摆脱第一个峰)

  2. 在剩余的两个峰之间找到最佳的“谷”值来分离图片

    我已经知道如何通过实现 Otsu 的变体来执行第 2 步。 但我正在为第 1 步而苦苦挣扎

  3. 如果剩余两个峰之间的山谷不够低,我想发出警告。

此外,图像非常干净,几乎没有噪点

执行第 1 步和第 3 步的蛮力算法是什么?我可以找到一种实现 Otsu 的方法,但是在数学方面,蛮力正在逃离我。事实证明,关于像 otsu 这样的方法有更多的文档,而关于简单地寻找峰谷的文档更少。除了完成工作之外,我不寻求任何东西(即,它是一个临时解决方案,只需要在合理的时间范围内实施,直到我可以花更多时间在它上面)

我在 c# 中做这一切

任何有关采取哪些步骤的帮助将不胜感激! 太感谢了!

编辑:更多数据:

大多数直方图可能与第一个类似,第一个峰值代表背景。

【问题讨论】:

  • 能否提供一些示例数据?
  • 峰周围的区域看起来像正态分布吗?你可以例如将三个独立的正态分布拟合到您的数据中。然后,您可以使用标准偏差来确定截止点,以识别您的峰和谷。
  • 如何使用 k=3 的 k-means 算法来获得 3 个不同的集群?如果一切顺利,每个质心都应该对应一个峰值。
  • @EdwinG 您是否尝试过将直方图视为图像并构建凸包,然后对其进行分析?我记得读过一篇大约有 30 年历史的论文,它与我很快描述的这种方法相关。
  • 您可以尝试先平滑直方图(通过运行平均值或高斯卷积),然后应用数值导数(即取相邻值之间的差异)。例如,可以通过一阶导数的符号变化来检测极值。

标签: c#-4.0 image-processing histogram mathematical-optimization image-segmentation


【解决方案1】:

使用峰值测试。它是一种在两个局部最小值之间找到所有可能的峰值,并根据公式测量峰值的方法。如果峰值高于阈值,则接受峰值。

来源: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;
}

【讨论】:

    猜你喜欢
    • 2014-05-15
    • 2021-09-12
    • 1970-01-01
    相关资源
    最近更新 更多