2015-12-06 88 views
4

我需要以非整数因子(例如100x100数组到45x45数组)的方式对2D numpy数组进行降采样,以执行本地求平均值的方式,就像Photoshop /瘸子会为图像做到这一点。我需要双精度。目前的选择无法做得很好。Python:使用非整数因子对2D numpy数组进行缩减采样

  • scipy.ndimage.zoom不进行平均化,并基本上采用 最近邻取样(参见前面的问题scipy.ndimage.interpolation.zoom uses nearest-neighbor-like algorithm for scaling-down

  • scipy.misc.imresize转换数组的INT8;我需要更多的 精度和浮点

  • skimage.transform.rescale也使用近邻和转发你skimage.transform.downscale_local_mean当地平均,

  • skimage.transform.downscale_local_mean只能用零执行整数比例因子(和衬垫图像如果所述因子非整数)。整数比例因子是一个简单的numpy excersice。

我错过任何其他选项吗?

+0

不是最优雅,我不知道这里的数学,但如果你只是想要的东西,我的工作会由9(900X900),将其放大,然后通过20(45X45),所以你可以做在步骤 – user4421975

+0

这两个步骤中按整数缩放我目前使用向上缩放到最终大小的最接近的乘数(在这种情况下为135),然后通过块平均缩小比例。它的工作原理,但它是一个丑陋的,特别是对于巨大的矩阵。 –

回答

0

我最终编写了一个小函数,它使用scipy.ndimage.zoom来放大图像的大小,但对于缩小,它首先将它放大为原始形状的倍数,然后通过块平均缩小。它接受任何其他关键字参数scipy.zoomorderprefilter

我仍然在寻找一个使用可用软件包的更干净的解决方案。

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