[英]Python: downsample 2D numpy array by a non-integer factor
I need to downsample a 2D numpy array by a non-integer factor (eg 100x100 array to a 45x45 array) in a way that performs local averaging, just like Photoshop/gimp would do that for an image. 我需要通过非整数因子(例如,100x100阵列到45x45阵列)对2D numpy数组进行下采样,以执行局部平均,就像Photoshop / gimp会为图像执行此操作一样。 I need double precision.
我需要双精度。 Current options can't do it well.
目前的选择不能很好。
scipy.ndimage.zoom
does not perform averaging, and basically uses nearest-neighbor sampling (see previous question scipy.ndimage.interpolation.zoom uses nearest-neighbor-like algorithm for scaling-down ) scipy.ndimage.zoom
不执行平均,并且基本上使用最近邻居采样(参见上一个问题scipy.ndimage.interpolation.zoom使用最接近邻居的算法进行缩小 )
scipy.misc.imresize
converts an array to an int8; scipy.misc.imresize
将数组转换为int8; I need more precision and floating point 我需要更高的精度和浮点数
skimage.transform.rescale
also uses nearest-neighbor and forwards you to skimage.transform.downscale_local_mean
for local averaging, skimage.transform.rescale
也使用最近邻居并将你转发到skimage.transform.downscale_local_mean
进行局部平均,
skimage.transform.downscale_local_mean
can only perform integer scaling factor (and pads image with zeros if the factor is non-integer). skimage.transform.downscale_local_mean
只能执行整数缩放因子(如果因子是非整数,则用零skimage.transform.downscale_local_mean
图像)。 Integer scaling factor is a trivial numpy excersice. 整数缩放因子是一个微不足道的numpy excersice。
Did I miss any other options? 我错过了其他选择吗?
I ended up writing a small function that upscales the image using scipy.ndimage.zoom
, but for downscaling it first upscales it to be the multiple of the original shape, and then downscales by block-averaging. 我最后写了一个小函数,使用
scipy.ndimage.zoom
升级图像,但是为了缩小它,它首先将它升级为原始形状的倍数,然后通过块平均缩小。 It accepts any other keyword arguments for scipy.zoom
( order
and prefilter
) 它接受
scipy.zoom
任何其他关键字参数( order
和prefilter
)
I'm still looking for a cleaner solution using available packages. 我仍在寻找使用可用软件包的更清洁的解决方案。
def zoomArray(inArray, finalShape, sameSum=False, **zoomKwargs):
inArray = np.asarray(inArray, dtype = np.double)
inShape = inArray.shape
assert len(inShape) == len(finalShape)
mults = []
for i in range(len(inShape)):
if finalShape[i] < inShape[i]:
mults.append(int(np.ceil(inShape[i]/finalShape[i])))
else:
mults.append(1)
tempShape = tuple([i * j for i,j in zip(finalShape, mults)])
zoomMultipliers = np.array(tempShape) / np.array(inShape) + 0.0000001
rescaled = zoom(inArray, zoomMultipliers, **zoomKwargs)
for ind, mult in enumerate(mults):
if mult != 1:
sh = list(rescaled.shape)
assert sh[ind] % mult == 0
newshape = sh[:ind] + [sh[ind] / mult, mult] + sh[ind+1:]
rescaled.shape = newshape
rescaled = np.mean(rescaled, axis = ind+1)
assert rescaled.shape == finalShape
if sameSum:
extraSize = np.prod(finalShape) / np.prod(inShape)
rescaled /= extraSize
return rescaled
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.