图像中的numpy的Mipmap? [英] Mipmap of image in numpy?

查看:124
本文介绍了图像中的numpy的Mipmap?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与您一起检查是否有一个整洁的numpy解决方案,可以使用双线性过滤来缩小2D numpy数组的大小(这是一个图像)?

I'm checking with you if there is a neat numpy solution to resizing down a 2D numpy array (which is an image) using bilinear filtering?

更具体地说,我的数组具有形状(宽度,高度,4)(如rgba图像中所示).缩小比例也只能在偶数"步骤上完成:即从(w,h,4)到(w/2,h/2,4)到(w/4,h/4,4)等.

More specifically, my array has the shape (width, height, 4) (as in a rgba image). The downscaling is also only done on "even" steps: i.e. from (w, h, 4) to (w/2, h/2, 4) to (w/4, h/4, 4) etc.

我已经浏览了很长时间,但是每个人似乎都在参考imresize的scipy/PIL版本.

I've browsed around for quite some time now but everyone seems to refer to the scipy/PIL versions of imresize.

我想最大程度地减少对python包的依赖,因此只需要numpy.

I want to minimize the number of dependencies on python packages, hence the numpy only requirement.

我只想在用C ++进行实现之前先与SO进行检查.

I just wanted to check with SO before I go implement it in C++ instead.

推荐答案

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

I don't think there is any specific solution in numpy, but you should be able to implement it efficiently without leaving the comfort of python. Correct me if I'm wrong, but when the size of the image is divisible by 2, a bilinear filter is basically the same as averaging 4 pixels of the original image to get 1 pixel of the new one, right? Well, if your image size is a power of two, then the following code:

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')

产生此输出:

原始图片为512x512,它在我的系统中的以下位置运行:

With an original image of 512x512, it runs on my system in:

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的值矩阵,可以进行插值以获得新的像素值.

This will not work if an odd length of a side ever comes up, but depending on exactly how you want to handle the downsampling for those cases, you should be able to get rid of a full row (or column) of pixels, reshape your image to (rows // 2, 2, cols // 2, 2, planes), so that img[r, :, c, :, p] is a 2x2 matrix of values to interpolate to get a new pixel value.

这篇关于图像中的numpy的Mipmap?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆