【问题标题】:How to find neighbors in binary image with given horizontal and vertical distance (Python)如何在给定水平和垂直距离的二进制图像中找到邻居(Python)
【发布时间】:2016-08-10 07:40:08
【问题描述】:

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

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

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

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

是否有一些简单/快速的方法来完成此任务(最好是 scikit-image 方法来提供帮助)我正在使用 Python。

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

【问题讨论】:

    标签: python scikit-image neighbours


    【解决方案1】:

    当您获得不同黑点的坐标时,您可以使用 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,您需要重新调整坐标,以便您可以使用经典规范之一来计算点之间的距离。

    【讨论】:

    • 这对于获取不同区域的距离非常好,而且与我自己的方法相比也非常快。唯一的问题是,我只能得到半径范围内的距离。但需要水平和垂直的距离是不同的。例如 x 轴为 100 像素,y 轴为 40 像素。你知道有一种方法可以这么快地找到一个方向的距离吗?
    【解决方案2】:

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

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

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

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

    取决于你的定义

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您的回答。 coords 属性正是我所需要的。现在我只需要得到每个像素之间的垂直/水平距离。但我认为这不应该是一个问题。
    【解决方案3】:

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

    1. 使用binary_dilation“增长”所有区域的预期距离(实际上是一半,因为你从“间隙的两侧”增长),其中structure是一个内核(例如矩形:@987654321 @) 的,比方说,20x80 像素;
    2. 使用生成的掩码作为skimage.measure.label 的输入,为不同区域的像素分配不同的值;
    3. 将您的输入图像乘以上面创建的遮罩,使膨胀像素为零。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-05-18
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      相关资源
      最近更新 更多