Opencv Mat:找到所有的山峰和山谷

时间:2014-01-16 12:44:42

标签: opencv image-processing

我想知道在2D灰度级Mat中找到所有峰和谷的最佳方法是什么?

我发现只有opencv函数在Mat中找到局部极值但不是所有的峰和谷。

所以我试着找出我自己的算法,但我希望有一种方法(已经存在或改进这种方法)使其更快

我的想法是:

为了找到所有的山峰:

  • 找到值为255的所有像素,将其标记为“峰值”和“已发现”
  • 找到值为254的所有像素,如果没有标记为已发现的邻居,则将其标记为峰值(并将其标记为已发现)
  • 做同样的事情直到0。

然后重做同样的事情,从0开始到255.

那么,你怎么看?

我想有更快的方法吗?

由于

PS:我这样做是为了尝试检测像这样的图像中的干细胞集落:sample

因为我认为在干细胞集落内会有更多的山峰和山谷(中间的大事)。但是我担心这不是一个很好的方法,因为我似乎在细胞集落内有多少峰而不是外面......

2 个答案:

答案 0 :(得分:2)

  1. 如果你想找到所有的局部峰值 - 这里是非常有效的算法: 对于每个像素,检查它是否是其8个相邻像素中的每一个的> =。如果是,请将其标记为局部最大值,否则不标记。您将通过图像一次性获得解决方案。
  2. 如果您不需要所有峰值,而是要说出比其他解决方案更高的5个峰值:找到最高峰并用黑色覆盖它,以及它的7x7邻域。现在重复这些步骤(找到全局最大值并抑制它)。将此过程重复5次,您将获得5个最高峰,它们之间的距离至少为7像素。这种算法不是很准确,但它很简单,快速,并且在很多情况下都能完成这项工作。
  3. 如果上述方法不够好,您可能需要重枪。你熟悉"形态重建"?如果没有,请谷歌搜索术语"洪水填充"算法并阅读它。它填补了当地的山谷和山峰。之后阅读有关形态重建的内容。它绝对可以解决您的问题,但如果您不使用GPU,则运行时间可能会很慢。

答案 1 :(得分:-1)

一个想法是:

  • 定义一个区域,其中只允许一个峰值(PeakArea)和一个峰值阈值。
  • 在图片上滑动一个具有峰面积大小的窗口。
  • 如果窗口中至少有一个像素超过阈值:将此区域中的最大像素标记为峰值,将所有其他像素标记为非峰值。

否则你会发现几乎每个Pixel都是一个峰值。