2

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

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

只是图像的一小部分

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

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

有没有一些简单/快速的方法来完成这个(最好是一个 scikit-image 方法来帮助)我正在使用 Python。

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

4

3 回答 3

2

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

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

于 2016-08-10T14:23:52.573 回答
1

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

  1. “增长”所有区域的预期距离(实际上是一半,因为你从“间隙的两侧”增长)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 的输出):

在此处输入图像描述

于 2016-08-11T07:39:46.853 回答
1

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

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

这本质上是一个图像,其中background像素被分配了值0,构成每个(连接的)点的像素被分配了一个整数标签的值,因此一个点的所有像素都将被标记为 value 1,另一个点的像素点将标有值2,依此类推。下面我将交替提及“斑点”和“标记区域”。

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

取决于你的定义

目标是找到彼此靠近的所有黑点。

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

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

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

如果您正在寻找粗略比较,那么比较每对标记区域之间的centroidor可能就足够了。local_centroid

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

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

于 2016-08-10T10:43:40.837 回答