【问题标题】:Generating probabilites from patches of image从图像块生成概率
【发布时间】:2021-11-05 13:29:27
【问题描述】:

我正在处理大小为512x512 的图像。使用einops 将图像分成块,块大小为32。总体上的补丁数量为256,换句话说,我们得到了一个大小为256x1024的新“图像”。

由于该图像实际上是分割问题的掩码,因此该图像实际上仅包含 4 个值(4 类):0 用于背景,1 用于第一类,2 用于第二类第三课,3

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

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

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

理论上,我知道我需要遍历每个补丁,然后计算当前补丁中每个类的像素数,然后除以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. 是否有更快/更好/pythonic 的方式来执行此操作,最好是矢量化的?

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

【问题讨论】:

    标签: python numpy image-processing pytorch einops


    【解决方案1】:

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

    torch.histc(input, bins=100, min=0, max=0, *, out=None) → Tensor
    计算张量的直方图。

    元素被分类到minmax 之间的等宽箱中。如果 minmax 都是零,数据的最小值和最大值 被使用了。

    低于min 和高于max 的元素将被忽略。

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

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

    【讨论】:

    • 所以我只需要使用这种方法遍历每一行?一旦我靠近我的电脑,我会看看这是否是我想要的:)
    • @user574362 上面的行将返回所需的结果,即每个C 类的patch-wise 统计数据,张量形状的256x4。跨度>
    • 嘿 Ivan,上面的行返回以下错误:RuntimeError: _th_histc not supported on CPUType for Long 这很奇怪,因为 to_patchdtypeint64。这一步是作为预处理完成的,而不是在我加载数据时完成的,所以它应该在 cpu 上而不是 gpu 上,所以我想知道它是否可以使用 numpy 完成(我可以使用 torch 但它不起作用)
    • 实际上,您需要转换为浮点数:只需将输入数组x 转换为x.float(),它应该可以工作。此外,您使用的是 CPU 还是 GPU 也没关系。
    • 我注意到这个方法没有给出一致的索引,例如,在某些补丁中,背景获取索引 2:tensor([0., 0., 1., 0.]),但在其他情况下,它获取索引 0:tensor([0.9912, 0.0000, 0.0000, 0.0088])。有没有办法让每个索引对应一个类?
    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    相关资源
    最近更新 更多