I'm trying to take a small image and make a large ("pixelated") version of it using Python. I've tried using the nearest neighbor resizing methods in both scipy
and PIL.Image
and both output the same wrong result. Here's an example when trying to upsample an image by a factor of 3:
import numpy as np
from scipy.misc import imresize
from PIL import Image
img = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
img_nn_scipy = imresize(img, (9, 9), interp='nearest')
img_nn_pil = np.array(Image.fromarray(img).resize((9, 9), Image.NEAREST))
print img_nn_scipy
print img_nn_pil
Both print statements output the same result:
[[1 1 1 2 2 2 2 3 3]
[1 1 1 2 2 2 2 3 3]
[1 1 1 2 2 2 2 3 3]
[4 4 4 5 5 5 5 6 6]
[4 4 4 5 5 5 5 6 6]
[4 4 4 5 5 5 5 6 6]
[4 4 4 5 5 5 5 6 6]
[7 7 7 8 8 8 8 9 9]
[7 7 7 8 8 8 8 9 9]]
I expected that each number in the original image would now be replaced by a 3x3 block all containing the same value. Instead, the blocks have varying sizes, and only the 1
block is 3x3.
Is there a reason for this? Is there a way to reasonably solve this in Python?
Thanks!
Try the latest Pillow instead of PIL.
In [1]: import numpy as np
...: from PIL import Image
...:
In [2]: img = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
In [3]: img_nn_pil = np.array(Image.fromarray(img).resize((9, 9), Image.NEAREST))
In [4]: print img_nn_pil
[[1 1 1 2 2 2 3 3 3]
[1 1 1 2 2 2 3 3 3]
[1 1 1 2 2 2 3 3 3]
[4 4 4 5 5 5 6 6 6]
[4 4 4 5 5 5 6 6 6]
[4 4 4 5 5 5 6 6 6]
[7 7 7 8 8 8 9 9 9]
[7 7 7 8 8 8 9 9 9]
[7 7 7 8 8 8 9 9 9]]
This was just a bug that was fixed.