首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scipy标签侵蚀

Scipy标签侵蚀
EN

Stack Overflow用户
提问于 2011-12-21 02:57:57
回答 1查看 488关注 0票数 4

如何将标记区域周围的像素环保存在numpy数组中?

在一个简单的例子中,我会减去侵蚀。当标签接触时,这种方法就不起作用了。如何从A获取B

代码语言:javascript
复制
A = array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

B = array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0],
           [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0],
           [0, 0, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0],
           [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

我使用的是具有多个标签的大型数组,因此不能在每个标签上进行单独的侵蚀。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-21 12:36:09

新答案

实际上,我只是想到了一个更好的方法:

代码语言:javascript
复制
B = A * (np.abs(scipy.ndimage.laplace(A)) > 0)

作为完整的示例:

代码语言:javascript
复制
import numpy as np
import scipy.ndimage

A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

B = A * (np.abs(scipy.ndimage.laplace(A)) > 0)

我认为这应该适用于所有情况(像A这样的“标记”数组,至少……)。

如果您担心性能,可以将其分成几个部分,以减少内存开销:

代码语言:javascript
复制
B = scipy.ndimage.laplace(A)
B = np.abs(B, B) # Preform abs in-place
B /= B  # This will produce a divide by zero warning that you can safely ignore
B *= A  

这个版本要详细得多,但应该使用更少的内存。

旧答案

我想不出用通常的scipy.ndimage函数一步完成这件事的好方法。(我觉得tophat过滤器应该能做你想要的事情,但我不太明白。)

但是,正如您所提到的,执行多个单独的侵蚀是一种选择。

即使在非常大的数组上,如果您使用find_objects提取每个标签的子区域,然后只对子区域进行侵蚀,您也应该获得合理的性能。

例如:

代码语言:javascript
复制
import numpy as np
import scipy.ndimage

A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
              [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

regions = scipy.ndimage.find_objects(A)

mask = np.zeros_like(A).astype(np.bool)

for val, region in enumerate(regions, start=1):
    if region is not None:
        subregion = A[region]
        mask[region] = scipy.ndimage.binary_erosion(subregion == val)

B = A.copy()
B[mask] = 0

这会产生以下结果:

代码语言:javascript
复制
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0],
       [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0],
       [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0],
       [0, 0, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0],
       [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

对于大型数组,性能应该是合理的,但它将在很大程度上取决于不同标记对象跨越的区域有多大,以及您拥有的标记对象的数量……

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8580518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档