numpy中的图像Mipmap?

时间:2013-01-27 16:54:04

标签: python numpy

我正在检查你是否有一个利用双线性过滤来调整2D numpy数组(这是一个图像)的整齐的numpy解决方案?

更具体地说,我的数组具有形状(宽度,高度,4)(如在rgba图像中)。降尺度也只在“偶数”步骤上完成:即从(w,h,4)到(w / 2,h / 2,4)到(w / 4,h / 4,4)等。

我已经浏览了很长一段时间但是每个人似乎都提到了imresize的scipy / PIL版本。

我想最小化python包的依赖数,因此只需要numpy。

在我用C ++实现它之前,我只是想用SO来检查。

1 个答案:

答案 0 :(得分:2)

我认为numpy中没有任何具体的解决方案,但是你应该能够有效地实现它而不必离开python的舒适度。如果我错了,请纠正我,但是当图像的大小可以被2整除时,双线性滤波器基本上与原始图像的平均4个像素相同,得到新像素的1个像素,对吧?好吧,如果你的图像大小是2的幂,那么代码如下:

from __future__ import division
import numpy as np
from PIL import Image

def halve_image(image) :
    rows, cols, planes = image.shape
    image = image.astype('uint16')
    image = image.reshape(rows // 2, 2, cols // 2, 2, planes)
    image = image.sum(axis=3).sum(axis=1)
    return ((image + 2) >> 2).astype('uint8')

def mipmap(image) :
    img = image.copy()
    rows, cols, planes = image.shape
    mipmap = np.zeros((rows, cols * 3 // 2, planes), dtype='uint8')
    mipmap[:, :cols, :] = img
    row = 0
    while rows > 1:
        img = halve_image(img)
        rows = img.shape[0]
        mipmap[row:row + rows, cols:cols + img.shape[1], :] = img
        row += rows
    return mipmap

img = np.asarray(Image.open('lena.png'))
Image.fromarray(mipmap(img)).save('lena_mipmap.png')

生成此输出:

enter image description here

原始图像为512x512,它在我的系统上运行:

In [3]: img.shape
Out[3]: (512, 512, 4)

In [4]: %timeit mipmap(img)
10 loops, best of 3: 154 ms per loop

如果一个奇数长度的某个方面出现,这将无法工作,但根据您想要处理这些情况的下采样的确切方式,您应该能够摆脱像素的完整行(或列) ,将图像重塑为(rows // 2, 2, cols // 2, 2, planes),以便img[r, :, c, :, p]为2x2值的矩阵,以进行插值以获得新的像素值。