如何在给定的水平和垂直距离 (Python) 的二值图像中找到邻居

How to find neighbors in binary image with given horizontal and vertical distance (Python)

我有一张图片(或数百张)需要分析。目标是找到彼此靠近的所有黑点。

例如水平距离为 160 像素,垂直距离为 40 像素的所有黑点。

现在我只查看每个像素,如果有一个黑色像素,我会调用递归方法来找到它的邻居(如果你愿意,我也可以 post 代码)

可以用,但是速度很慢。目前脚本运行大约 3-4 分钟,具体取决于图像大小。

是否有一些 easy/fast 方法来完成这个(最好是 scikit-image 方法来帮助解决这个问题)我正在使用 Python.

编辑:我尝试使用 scikit.measure.find_contours,现在我有一个包含黑点轮廓的数组。现在我只需要找到这些轮廓附近的轮廓。

免责声明:我根本不精通 scikit 图像库,但我使用 MATLAB 解决了类似的问题,所以我在 scikit 中搜索了等效的方法,希望我的以下发现对您有所帮助。

首先,您可以使用 skimage.measure.label 其中 returns label_image,即所有连接区域都标有相同数字的图像。我相信您应该使用 background=255 调用此函数,因为根据您的描述,图像中的背景似乎是 while 区域(因此值为 255)。

这基本上是一幅图像,其中 background 像素被分配了值 0,构成每个(连接的)点的像素被分配了整数标签的值,因此所有一个点的像素将被标记为值 1,另一个点的像素将被标记为值 2,依此类推。下面我将交替使用 "spots" 和 "labelled regions"。

然后您可以调用 skimage.measure.regionprops,它将在上一步中获得的 label_image 作为输入。此函数 returns RegionProperties 的列表(每个标记区域一个),它是标记区域属性的摘要。

取决于你对

的定义

The goal is to find all black spots close to each other.

您可以使用 RegionProperties 的不同字段来帮助解决您的问题:

  • bbox 为您提供包含该标记区域的边界框坐标集,
  • centroid 给出该标记区域的质心像素坐标,
  • local_centroid 给出相对于边界框的质心 bbox

(注意还有 areabbox_area 属性,你可以使用它们来决定是否丢弃你可能不感兴趣的非常小的点,从而减少计算时间比较每对点的接近度)

如果您要进行粗略比较,那么比较每对标记区域之间的 centroidlocal_centroid 可能就足够了。

否则,您可以使用 bbox 坐标来测量任意两个区域的外边界之间的精确距离。

如果您想根据每对彼此最接近的区域的像素之间的精确距离做出决定,那么您可能会使用 coords 属性.

当您获得不同黑点的坐标时,无需计算所有黑色像素对之间的所有距离,您可以使用 cKDTree(在 scipy.spatial、http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.cKDTree.html#scipy.spatial.cKDTree 中)。使用 cKDTree 的确切方法取决于您的确切标准(例如,您可以使用 cKDTree.query_ball_tree 来了解是否存在一对属于两个不同标签的点,以及您给出的最大距离)。

KDTrees 是一种基于相邻点降低问题复杂性的好方法。如果你想使用 KDTrees,你需要重新缩放坐标,以便你可以使用一种经典范数来计算点之间的距离。

如果您的输入图像是二进制的,您可以按如下方式分离您感兴趣的区域:

  1. "grow" 预期距离的所有区域(实际上是它的一半,当你从 "both sides of the gap" 增长时)与 binary_dilation,其中 structure 是内核(例如矩形:http://scikit-image.org/docs/dev/api/skimage.morphology.html#skimage.morphology.rectangle),比方说,20x80 像素;
  2. 使用生成的蒙版作为 skimage.measure.label 的输入,为不同区域的像素分配不同的值;
  3. 将您的输入图像乘以上面创建的蒙版,使膨胀像素为零。

这是建议的方法在您的图像上的结果 kernel = rectange(5,5):

膨胀二值图像(第 1 步的输出):

上面的标记版本(第 2 步的输出):

乘法结果(第 3 步的输出):