Python中的下采样数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18666014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:22:42  来源:igfitidea点击:

Downsample array in Python

pythonimage-processingnumpyscipygdal

提问by wuffwuff

I have basic 2-D numpy arrays and I'd like to "downsample" them to a more coarse resolution. Is there a simple numpy or scipy module that can easily do this? I should also note that this array is being displayed geographically via Basemap modules.

我有基本的二维 numpy 数组,我想将它们“下采样”到更粗糙的分辨率。是否有一个简单的 numpy 或 scipy 模块可以轻松做到这一点?我还应该注意到,这个数组是通过 Basemap 模块在地理上显示的。

SAMPLE: enter image description here

样本: 在此处输入图片说明

回答by Hammer

imresizeand ndimage.interpolation.zoomlook like they do what you want

imresizendimage.interpolation.zoom看起来他们做你想做的

I haven't tried imresize before but here is how I have used ndimage.interpolation.zoom

我之前没有尝试过 imresize 但这里是我如何使用 ndimage.interpolation.zoom

a = np.array(64).reshape(8,8)
a = ndimage.interpolation.zoom(a,.5) #decimate resolution

a is then a 4x4 matrix with interpolated values in it

a 是一个 4x4 矩阵,其中包含内插值

回答by lmjohns3

This might not be what you're looking for, but I thought I'd mention it for completeness.

这可能不是你要找的,但我想我会提到它的完整性。

You could try installing scikits.samplerate(docs), which is a Python wrapper for libsamplerate. It provides nice, high-quality resampling algorithms -- BUT as far as I can tell, it only works in 1D. You might be able to resample your 2D signal first along one axis and then along another, but I'd think that might counteract the benefits of high-quality resampling to begin with.

您可以尝试安装scikits.samplerate( docs),它是 libsamplerate 的 Python 包装器。它提供了很好的、高质量的重采样算法——但据我所知,它只适用于 1D。您可以先沿着一个轴然后沿着另一个轴重新采样 2D 信号,但我认为这可能会抵消高质量重新采样的好处。

回答by Mike T

When downsampling, interpolation is the wrong thing to do. Always use an aggregated approach.

下采样时,插值是错误的做法。始终使用聚合方法。

I use block means to do this, using a "factor" to reduce the resolution.

我使用块方法来做到这一点,使用“因子”来降低分辨率。

import numpy as np
from scipy import ndimage

def block_mean(ar, fact):
    assert isinstance(fact, int), type(fact)
    sx, sy = ar.shape
    X, Y = np.ogrid[0:sx, 0:sy]
    regions = sy/fact * (X/fact) + Y/fact
    res = ndimage.mean(ar, labels=regions, index=np.arange(regions.max() + 1))
    res.shape = (sx/fact, sy/fact)
    return res

E.g., a (100, 200) shape array using a factor of 5 (5x5 blocks) results in a (20, 40) array result:

例如,使用因子 5(5x5 块)的 (100, 200) 形状数组导致 (20, 40) 数组结果:

ar = np.random.rand(20000).reshape((100, 200))
block_mean(ar, 5).shape  # (20, 40)

回答by K.-Michael Aye

scikit-imagehas implemented a working version of downsamplinghere, although they shy away from calling it downsamplingfor it not being a downsampling in terms of DSP, if I understand correctly:

scikit-image已经实现了downsamplinghere的一个工作版本,尽管downsampling如果我理解正确的话,他们不会因为它不是DSP方面的下采样而避免调用它:

http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce

http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce

but it works very well, and it is the only downsamplerthat I found in Python that can deal with np.nanin the image. I have downsampled gigantic images with this very quickly.

但是效果很好,而且是downsampler我在Python中发现的唯一可以处理np.nan图像的。我已经非常快速地对巨大的图像进行了下采样。

回答by Josh Albert

Because the OP just wants a courser resolution, I thought I would share my way for reducing number of pixels by half in each dimension. I takes the mean of 2x2 blocks. This can be applied multiple times to reduce by factors of 2.

因为 OP 只想要一个更清晰的分辨率,我想我会分享我将每个维度的像素数减少一半的方法。我取 2x2 块的平均值。这可以应用多次以减少 2 倍。

from scipy.ndimage import convolve
array_downsampled = convolve(array, 
                 np.array([[0.25,0.25],[0.25,0.25]]))[:array.shape[0]:2,:array.shape[1]:2]

回答by Kolibril

Easiest way: You can use the array[0::2]notation, which only considers every second index. E.g.

最简单的方法:您可以使用array[0::2]表示法,它只考虑每隔一个索引。例如

array= np.array([[i+j for i in range(0,10)] for j in range(0,10)])
down_sampled=array[0::2,0::2]

print("array \n", array)
print("array2 \n",down_sampled)

has the output:

有输出:

array 
[[ 0  1  2  3  4  5  6  7  8  9]
 [ 1  2  3  4  5  6  7  8  9 10]
 [ 2  3  4  5  6  7  8  9 10 11]
 [ 3  4  5  6  7  8  9 10 11 12]
 [ 4  5  6  7  8  9 10 11 12 13]
 [ 5  6  7  8  9 10 11 12 13 14]
 [ 6  7  8  9 10 11 12 13 14 15]
 [ 7  8  9 10 11 12 13 14 15 16]
 [ 8  9 10 11 12 13 14 15 16 17]
 [ 9 10 11 12 13 14 15 16 17 18]]
array2 
[[ 0  2  4  6  8]
 [ 2  4  6  8 10]
 [ 4  6  8 10 12]
 [ 6  8 10 12 14]
 [ 8 10 12 14 16]]

回答by Q2Learn

This will take an image of any resolution and return only a quarter of its size by taking the 4th index of the image array.

这将获取任何分辨率的图像,并通过获取图像数组的第 4 个索引仅返回其大小的四分之一。

import cv2
import numpy as np

def quarter_res_drop(im):

    resized_image = im[0::4, 0::4]
    cv2.imwrite('resize_result_image.png', resized_image)

    return resized_image

im = cv2.imread('Your_test_image.png', 1)

quarter_res_drop(im)

回答by blaylockbk

xarray's "coarsen" method can downsample a xarray.Dataset or xarray.DataArray

xarray 的 "coarsen" 方法可以对 xarray.Dataset 或 xarray.DataArray 进行下采样

For example:

例如:

import xarray as xr
import numpy as np
import matplotlib.pyplot as plt

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15,5))

# Create a 10x10 array of random numbers
a = xr.DataArray(np.random.rand(10,10)*100, dims=['x', 'y'])

# "Downscale" the array, mean of blocks of size (2x2)
b = a.coarsen(x=2, y=2).mean()

# "Downscale" the array, mean of blocks of size (5x5)
c = a.coarsen(x=5, y=5).mean()


# Plot and cosmetics
a.plot(ax=ax1)
ax1.set_title("Full Data")

b.plot(ax=ax2)
ax2.set_title("mean of (2x2) boxes")

c.plot(ax=ax3)
ax3.set_title("mean of (5x5) boxes")

enter image description here

在此处输入图片说明