我有基本的2-D numpy数组,我想将它们“缩减”到更粗糙的分辨率。是否有一个简单的numpy或scipy模块可以轻松地做到这一点?我还应该注意,这个数组是通过Basemap模块在地理上显示的。
示例:
答案 0 :(得分:13)
scikit-image
已经在这里实现了downsampling
的工作版本,但如果我理解正确的话,他们会回避调用它downsampling
,因为它不是DSP的下采样: / p>
http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce
但它运行良好,它是我在Python中找到的唯一可以处理图像中downsampler
的{{1}}。我很快就对这个巨大的图像进行了下采样。</ p>
答案 1 :(得分:10)
下采样时,插值是错误的。始终使用汇总方法。
我使用块手段来执行此操作,使用“因子”来降低分辨率。
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
例如,使用因子5(5x5块)的(100,200)形状阵列导致(20,40)阵列结果:
ar = np.random.rand(20000).reshape((100, 200))
block_mean(ar, 5).shape # (20, 40)
答案 2 :(得分:4)
imresize和ndimage.interpolation.zoom看起来像他们做你想做的事情
我之前没有尝试过imresize,但这里是我如何使用ndimage.interpolation.zoom
a = np.array(64).reshape(8,8)
a = ndimage.interpolation.zoom(a,.5) #decimate resolution
a然后是一个4x4矩阵,其中有插值
答案 3 :(得分:2)
因为OP只想要一个courser分辨率,我想我会分享我在每个维度减少一半像素数的方法。我取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]
答案 4 :(得分:2)
xarray的“粗略”方法可以对xarray.Dataset或xarray.DataArray进行降采样
例如:
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")
答案 5 :(得分:1)
这可能不是你想要的,但我想我会提到它的完整性。
您可以尝试安装scikits.samplerate
(docs),这是libsamplerate的Python包装器。它提供了漂亮,高质量的重采样算法 - 但据我所知,它只适用于1D。您可能首先沿着一个轴再沿着另一个轴重新采样2D信号,但我认为这可能会抵消高质量重采样的好处。
答案 6 :(得分:1)
这将获取任何分辨率的图像,并通过获取图像数组的第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)
答案 7 :(得分:0)
最简单的方法:
您可以使用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)
具有输出:
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]]