Convert Image from Pil to Opencv Format

Convert image from PIL to openCV format

use this:

pil_image = PIL.Image.open('Image.jpg').convert('RGB') 
open_cv_image = numpy.array(pil_image)
# Convert RGB to BGR
open_cv_image = open_cv_image[:, :, ::-1].copy()

PIL image in grayscale to OpenCV format

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)

Convert opencv image format to PIL image format?

Yes OpenCV is more robust and flexible and can perform most of the image processing routines which are available out there, So probably this filter can be done with OpenCV> However, there may not be a straightforward API for that.

Anyways, as far as the conversion of image format from OpenCV to PIL is concerned you may use Image.fromarray as:

import cv2
import numpy as np
from PIL import Image

img = cv2.imread("path/to/img.png")

# You may need to convert the color.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)

# For reversing the operation:
im_np = np.asarray(im_pil)

But you must keep in mind that, OpenCV follows BGR convention and PIL follows RGB color convention, so to keep the things consistent you may need to do use cv2.cvtColor() before conversion.

How can i convert a PIL image to cv2 numpy array

I'm not quite sure what you mean by it doesn't keep its transparency. If you convert a PIL image with transparency using numpy.array() it should return a numpy array with shape width, height, 4 where the 4th channel will represent the alpha channel values. And after whatever processing you need to do, if you convert it back to a PIL image using Image.fromarray() and perhaps saving with Image.save() you should get back an image with the same transparency. Can't help you much more without seeing an actual snippet of the code and possibly the image.

Fixing inefficient image conversion from PIL image to OpenCV Mat

The problem is that your approach starts with a BGRA image format. That's a lot of data and its probably unnecessary. There might be more efficient ways of grabbing the screenshot and converting it to an OpenCV image. Here's an approach that takes about 56ms on my slow machine:

import ctypes
import datetime
import cv2
import numpy as np

from PIL import ImageGrab

# workaround to allow ImageGrab to capture the whole screen
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()

# measure running time
start_time = datetime.datetime.now()

# take a full screenshot of the desktop
image = np.array(ImageGrab.grab( bbox= (40, 0, 800, 600) ))

# convert from RGB to BGR order so that colors are displayed correctly
mat = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

# compute elapsed time
delta = datetime.datetime.now() - start_time
elapsed_time_ms = int(delta.total_seconds() * 1000)
print('* Elapsed time:', elapsed_time_ms, 'ms')

cv2.imshow('mat', mat)
cv2.waitKey()


Related Topics



Leave a reply



Submit