【问题标题】:Find distance between all pairs of pixels in an image查找图像中所有像素对之间的距离
【发布时间】:2021-02-17 08:16:29
【问题描述】:

问题

我有一个形状为(H, W)numpy.array,用于存储图像的像素强度。我想生成一个新的形状(H, W, H, W) 数组,它存储图像中每对像素之间的欧几里得距离(像素之间的“空间”距离;而不是它们的强度差异)。

解决方案尝试

以下方法完全符合我的要求,但速度很慢。我正在寻找一种快速的方法来做到这一点。

d = numpy.zeros((H, W, H, W)) # array to store distances.
for x1 in range(H):
    for y1 in range(W):
        for x2 in range(H):
            for y2 in range(W):
                d[x1, y1, x2, y2] = numpy.sqrt( (x2-x1)**2 + (y2-y1)**2 )

额外细节

这里有更多关于我的问题的详细信息。解决上述简单问题的方法可能足以让我弄清楚其余部分。

  • 就我而言,图像实际上是 3D 医学图像(即形状为 (H, W, D)numpy.array)。
  • 3D 像素可能不是立方体(例如,每个像素可能代表 1 毫米 x 2 毫米 x 3 毫米的体积)。

【问题讨论】:

  • 所以您要计算像素坐标之间的距离,而不是像素本身的强度?
  • 像素本身可能有不同的体积?
  • @Jensun 这是一个 3D 医学图像,其中每个 3D 像素(“体素”)代表一个小体积。这些体积是矩形棱柱,但它们可能不是立方体。所有的体素都具有相同的形状。
  • 必须计算体素质心之间的距离吗?
  • @Jensun 是的,在质心之间。

标签: python performance numpy linear-algebra


【解决方案1】:

我们可以使用np.ogrid 设置带有1D 范围数组的开放网格,可以在相同的迭代器符号中对其进行操作以实现矢量化解决方案,这将利用broadcasting 来实现性能。提升:

X1,Y1,X2,Y2 = np.ogrid[:H,:W,:H,:W]
d_out = numpy.sqrt( (X2-X1)**2 + (Y2-Y1)**2 )

要保存在两个开放的网格上:

X,Y = np.ogrid[:H,:W]
d_out = numpy.sqrt( (X[:,:,None,None]-X)**2 + (Y[:,:,None,None]-Y)**2 )

如果我们正在处理大型数组,请考虑使用numexpr 进一步提升:

import numexpr as ne

d_out = ne.evaluate('sqrt( (X2-X1)**2 + (Y2-Y1)**2 )')

【讨论】:

  • 我尝试了这些,它们似乎都有效,并且比我的循环方法更快。我有一个更大的问题是图像太大而无法实际进行此计算或存储结果 - 例如100x100x100 的图像将具有 ~10^6 像素和 ~10^12 像素对。我将您的答案标记为已接受,因为我认为它回答了我提出的问题。
猜你喜欢
  • 2021-05-26
  • 1970-01-01
  • 2018-12-07
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 2017-04-06
相关资源
最近更新 更多