0

i am using below code to reshape my image. It's working for RGB image. But, it's not working for grey scale image.

from PIL import Image
import numpy as np
def load_image_into_numpy_array(image):
    (im_width, im_height) = image.size
    return np.array(image).reshape((im_height, im_width, 3)).astype(np.uint8)

image_path="color.jpg"
image = Image.open(image_path)
image_np = load_image_into_numpy_array(image)
image.close()

This is working image color.jpg

enter image description here

This is not working image grey.jpg

enter image description here

Both images shapes' are same.

image.size

(714, 714)

When I print image i found a differnce.

Working image print(image)

 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=714x714 at 0x7F95DB4D4BA8>

not working image print(image)

 <PIL.JpegImagePlugin.JpegImageFile image mode=L size=714x714 at 0x7F32B5430BA8>
  1. how to fix the issue?
  2. Is this because of mode changes?

Any help would be appreciable.

Error:

Traceback (most recent call last):
  File "checker.py", line 11, in <module>
    image_np = load_image_into_numpy_array(image)
  File "checker.py", line 5, in load_image_into_numpy_array
    return np.array(image).reshape((im_height, im_width, 3)).astype(np.uint8)
ValueError: cannot reshape array of size 509796 into shape (714,714,3)
Mohamed Thasin ah
  • 10,754
  • 11
  • 52
  • 111

3 Answers3

1

That function won't work on grayscale images, you need to edit the number of channels on the last dimension to (IM_HEIGHT, IM_WIDTH, 1). This because you aren't using RGB color channels anymore.

Try this:

def load_image_into_numpy_array(image):
    (im_width, im_height) = image.size
    return np.array(image).reshape((im_height, im_width, 1)).astype(np.uint8)
Sam Comber
  • 1,237
  • 1
  • 15
  • 35
1

You don't need any reshaping. If you want a 3-channel image in a Numpy array, just do:

import numpy as np
from PIL import Image

# Open image as PIL Image and ensure 3-channel RGB
im = Image.open('input.jpg').convert('RGB')

# Make into Numpy array
na = np.array(im)

You may find this answer about palette images helpful too.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
0

Another simple idea would be to concatenate the grayscale image thrice along the channel dimension (i.e. axis 2), if the incoming image has a shape tuple of length 2 as in your case:

def load_image_into_numpy_array(image):
    if len(image.shape) == 2:
        image = image[:, :, np.newaxis]
        image = np.concatenate([image]*3, axis=2)
    return np.array(image).astype(np.uint8)
kmario23
  • 57,311
  • 13
  • 161
  • 150