【发布时间】: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_axes 和 numpy.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)
两件事:
- 我希望输出为
256x4,其中沿第二个轴的每个数组的总和为 1。 - 是否有更快/更好/pythonic 的方式来执行此操作,最好是矢量化的?
编辑:我忘了加上总和,所以现在我得到了256x4。
【问题讨论】:
标签: python numpy image-processing pytorch einops