0

So, I have the following code for resizing an image using nearest neighbor interpolation. The solution seems straightforward to me using 2 for loops, but I can't think of any way to do this while taking advantage of numpy to avoid those pesky loops. Here is my code:

def scale(img, factor):
    # Calculate new image shape and create new image with it.
    height, width = img.shape[:2]
    new_height, new_width = (int(height * factor), int(width * factor))[:2]
    scaled_img = np.zeros([new_height, new_width])

    # Iterate over all pixels and set their values based on the input image.
    for x in range(new_height):
        for y in range(new_width):
            scaled_img[x, y] = img[int(x / factor), int(y / factor)]

    return scaled_img

Any input on how to avoid the for loops?

3 Answers 3

2

You can calculate the mapping of indices of new image to old indices and then use numpy.ix_ to unite them

import numpy as np

def scale(img, factor):
    """
    >>> img = np.arange(9).reshape(3, 3)
    >>> print(img)
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    >>> print(scale(img, 1.67))
    [[0 0 1 1 2]
     [0 0 1 1 2]
     [3 3 4 4 5]
     [3 3 4 4 5]
     [6 6 7 7 8]]
    """
    x_indices = (np.arange(int(img.shape[1] * factor)) / factor).astype(int) # [0 0 1 1 2]
    y_indices = (np.arange(int(img.shape[0] * factor)) / factor).astype(int)
    return img[np.ix_(y_indices, x_indices)]
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, that is a very clever solution. Thank you!
2

I would avoid writing this code entirely and use the Pillow image processing library to resize the image. Not sure about the performance, but I would think they would have optimized such basic tasks quite well.

Comments

0

While the first answer is really great from a "how do I do this in numpy" point of view, I'd second Nils L's answer: if what you're wanting to do is resize an image, then you're likely much better off using one of the image processing libraries.

Pillow works well, as does ndimage: http://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.zoom.html#scipy.ndimage.zoom

Both will likely be faster than numpy, and also give you a lot more options in the details of how you want the resizing to work, and let you do different interpolation methods if that's what you need.

1 Comment

Thanks for the heads-up, but this is for an assignment and I was mostly wondering how to avoid using for loops with numpy in general ^^

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.