How to resize an image using imageio?
Asked Answered
M

1

7

Consider an image img of type imageio.core.util.Array.

The shape of img is (256, 256, 3). I want to resize it to (128, 128, 3).

I tried at least the following three:

img.resize(img_res, pilmode="RGB")
img.resize(img_res)
img = cv2.resize(img, self.img_res)

Here img_res = (128, 128).

None of them worked well. How can I resize my image to the desired size?

Maice answered 15/1, 2021 at 9:17 Comment(1)
Please try and improve your code so it is complete and runnable in alignment with Stack Overflow MCRE stackoverflow.com/help/minimal-reproducible-exampleIngeringersoll
J
19

According to the documentation on imageio.core.util.Array, Array is "a subclass of np.ndarray [...]". Thus, when calling resize on some img of type Array, the actual call goes to np.ndarray.resize – which IS NOT np.resize! That's important here.

From the documentation on np.ndarray.resize:

Raises:

ValueError

If a does not own its own data [...]

That's why, some code like

import imageio

img = imageio.imread('path/to/your/image.png')
img.resize((128, 128))

will fail in that way:

Traceback (most recent call last):
    img.resize((128, 128))
ValueError: cannot resize this array: it does not own its data

That error seems to be bound to the Array class, because the following code also fails with the same error message:

from imageio.core.util import Array
import numpy as np

img = Array(np.zeros((200, 200, 3), np.uint8))
img.resize((128, 128))

Obviously, the Array class only stores a view to some not directly accessible NumPy array, maybe some internal memory buffer!?

Now, let's see possible workarounds:

Actually, using np.resize like

import imageio
import numpy as np

img = imageio.imread('path/to/your/image.png')
img = np.resize(img, (128, 128, 3))

is not a good choice, because np.resize is not designed to properly resize images. So, the result is distorted.

Using OpenCV works fine for me:

import cv2
import imageio

img = imageio.imread('path/to/your/image.png')
img = cv2.resize(img, (128, 128))

Keep in mind, that OpenCV uses BGR ordering, while imageio uses RGB ordering – that's important when also using cv2.imshow for example.

Using Pillow also works without problems:

import imageio
from PIL import Image

img = imageio.imread('path/to/your/image.png')
img = Image.fromarray(img).resize((128, 128))

Finally, there's also skimage.transform.resize:

import imageio
from skimage.transform import resize

img = imageio.imread('path/tp/your/image.png')
img = resize(img, (128, 128))

Pick one that best fits your needs!

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
imageio:       2.9.0
NumPy:         1.19.5
OpenCV:        4.5.1
Pillow:        8.1.0
scikit-image:  0.18.1
----------------------------------------
Jablon answered 20/1, 2021 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.