2
votes

I found the previous answer related to a more general conversion from RGB image here: Convert image from PIL to openCV format

I would like to know the difference when an image has to be read as a grayscale format.

images = [None, None]

images[0] = Image.open('image1')
images[1] = Image.open('image2')

print(type(images[0]))

a = np.array(images[0])
b = np.array(images[1])

print(type(a))

im_template = cv2.imread(a, 0)
im_source = cv2.imread(b, 0)

I get the following output:

<class 'PIL.JpegImagePlugin.JpegImageFile'>
<class 'numpy.ndarray'>

Even though I am able to convert the image to ndarray, cv2 says: "bad argument type for built-in operation". I do not need an RGB to BGR conversion. What else should I consider while passing a cv2 read argument?

2
The first argument you sent to imread must be a string. Imread only open image from file. In python there is no OpenCV data type for manage the images, there is for some algorithms, but not for the image themself. Once you have converted your data to an numpy.ndarray every OpenCV function should work with it. - John_Sharp1318
I found this really helpful: "To use an OpenCV function, it is not really necessary to read it using Imread". So if I may, is it then valid to use all ndarrays as such to do the openCV functions such as filters? without detailed knowledge, I was under the impression that openCV reads images in BGR format (although my aim is to use it with grayscale) and PIL in RGB. Is this not going to create a colour mismatch later on? - abk

2 Answers

4
votes

You are making life unnecessarily difficult for yourself. If you want to load an image as greyscale, and use it with OpenCV, you should just do:

im = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

and that's all. No need to use PIL (which is slower), no need to use cvtColor() because you have already wasted all the memory reading it in BGR anyway.

If you absolutely want to read it using PIL (for some odd reason), use:

import numpy as np
from PIL import Image

# Read in and make greyscale
PILim = Image.open('image.jpg').convert('L')

# Make Numpy/OpenCV-compatible version
openCVim = np.array(PILim)

By the way, if you want to go back to a PIL image from an OpenCV/Numpy image, use:

PILim = Image.fromarray(openCVim)
2
votes

Since you already have loaded the image, you should use an image conversion function:

im_template = cv2.cvtColor(a, cv2.COLOR_RGB2GRAY)
im_source = cv2.cvtColor(b, cv2.COLOR_RGB2GRAY)