从图像块生成概率

Generating probabilites from patches of image

我正在处理尺寸为 512x512 的图像。使用 einops 将图像分成块,块大小为 32。总的补丁数是 256,换句话说,我们得到一个大小为 256x1024.

的新“图像”

由于这张图片实际上是分割问题的掩码,所以图片实际上只包含 4 个值(4 classes):0 背景,1第一个 class,第二个 class 2,第三个 class.

3

我的目标是获取每个补丁,并为每个 class C 计算以下内容:

此补丁中的像素数/标记为 C 的像素数。

这应该给我一个大小为 4 的数组,其中第一个条目是补丁中的像素总数 (1024) 超过背景像素数(标记为 0),第二个、第三个和第四个条目是相同,但相应的 class.

理论上,我知道我需要遍历每个单独的补丁,然后计算当前补丁中每个 class 的像素数,然后除以 1024。这样做 256 会得到我想要的结果。问题是我有(非常)大量的图像需要执行此操作,512 的大小只是使问题更简单的示例,因此 for 循环是不可能的。

我知道我可以使用 numpy 得到我想要的结果。我尝试了两个:numpy.apply_over_axesnumpy.apply_along_axis 但我不知道哪个更适合这个任务,还有 numpy.where 我不知道它在这里如何应用。

这是我所做的:

from einops import rearrange
import numpy as np

labn = np.random.randint(4,size= (512,512))      # Every pixels in this image is of value: 0,1,2,3
to_patch = rearrange(labn, "(h p1) (w p2) -> (h w) (p1 p2)", p1=32, p2=32)
print(to_patch.shape) # (256,1024)

c0 = np.full(1024, 0)
c1 = np.full(1024, 1)
c2 = np.full(1024, 2)
c3 = np.full(1024, 3)

def f(a):
    _c0 = a == c0
    _c1 = a == c2
    _c2 = a == c2
    _c3 = a == c3
    pr = np.array([np.sum(_c0), np.sum(_c1), np.sum(_c2), np.sum(_c3)]) / 1024
    return pr

resf = np.apply_along_axis(f, 1, to_patch)
print(resf.shape) # (256, 4, 1024)

两件事:

  1. 我希望输出为 256x4,其中第二个轴上的每个数组总和为 1。
  2. 有没有 faster/better/pythonic 方法来做到这一点,最好是矢量化?

编辑:我忘了加总和,所以现在我确实得到了 256x4

有一个内置的函数来计算出现次数torch.histc,它类似于Python的collections.Counter

torch.histc(input, bins=100, min=0, max=0, *, out=None) → Tensor
Computes the histogram of a tensor.

The elements are sorted into equal width bins between min and max. If min and max are both zero, the minimum and maximum values of the data are used.

Elements lower than min and higher than max are ignored.

您需要指定bins的数量,这里是类C的数量。以及用于排序的 minmax 值。此外,它不适用于多维张量,因此生成的张量将包含输入张量的全局统计信息,而不管维度如何。作为一种可能的解决方法,您可以遍历补丁,每次调用 torch.histc,然后堆叠结果并规范化:

resf = torch.stack([torch.histc(patch, C, min=0, max=C-1) for patch in x]) / x.size(1)