首页 文章

Python:通过非整数因子下采样2D numpy数组

提问于
浏览
6

我需要通过非整数因子(例如100x100阵列到45x45阵列)对2D numpy数组进行下采样,以执行局部平均,就像Photoshop / gimp会为图像执行此操作一样 . 我需要双精度 . 目前的选择不能很好 .

  • 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 .

我错过了其他选择吗?

1 回答

  • 1

    我最后写了一个小函数,使用 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
    

相关问题