Convertir imagen de formato PIL a openCV


95

Estoy tratando de convertir una imagen PILa OpenCVformato. Estoy usando OpenCV 2.4.3. esto es lo que he intentado hasta ahora.

>>> from PIL import Image
>>> import cv2 as cv
>>> pimg = Image.open('D:\\traffic.jpg')                           #PIL Image
>>> cimg = cv.cv.CreateImageHeader(pimg.size,cv.IPL_DEPTH_8U,3)    #CV Image
>>> cv.cv.SetData(cimg,pimg.tostring())
>>> cv.cv.NamedWindow('cimg')
>>> cv.cv.ShowImage('cimg',cimg)
>>> cv.cv.WaitKey()

Pero creo que la imagen no se convierte al formato CV. La ventana me muestra una gran imagen marrón. ¿Dónde me equivoco al convertir una imagen PILa CVformato?

Además, ¿por qué necesito escribir cv.cvpara acceder a las funciones?



Me referí a la pregunta que mencionaste, pero la solución dada allí no parece funcionar para mí
md1hunox

Creo que necesitas convertir la imagen de RGB a BGR. compruebe si funciona.
Froyo

Respuestas:


163

utilizar esta:

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() 

2
Gracias, ¿podría explicarme en detalle qué hace la última línea?
md1hunox

17
Tiene una imagen RGB representada por una matriz 3d, como en ex = numpy.array([ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [0, 1, 2] ] ]). Entonces, ex[0]es la primera línea de su imagen, ex[0][0]es la primera columna de la primera línea, ex[0][0][0]es el componente rojo del primer píxel, ex[0][0][1]es el componente verde y ex[0][0][2]es el componente azul. Dado que aparentemente necesita una imagen BGR (el orden inverso de RGB), invierte cada elemento que describe un píxel como en ex[0][0][::-1]. La última línea (excepto las inútiles .copy) es el equivalente de esta operación para toda la imagen.
mmgp

16
Puede ser solo una ligera mejora en el rendimiento, pero cv2.cvtColor(open_cv_image, cv2.cv.CV_BGR2RGB) es un poco más eficiente.
GuillaumeDufay

¿Cuál fue el propósito de .convert ('RGB') en su respuesta? Estoy trabajando con una imagen en escala de grises de 16 bits (modo de imagen = I; 16) ... hasta ahora, nparray mantiene la imagen como un solo objeto PIL.Image. (es decir, una matriz con una sola entrada, el PIL.Image original)
user391339

3
Si la imagen es binaria (por ejemplo, binaria escaneada TIF), entonces la matriz numpy lo será, boolpor lo que no podrá usarla con OpenCV. En este caso, debe convertirlo a la máscara OpenCV:if image.dtype == bool: image = image.astype(np.uint8) * 255
Maksym Ganenko

90

Esta es la versión más corta que pude encontrar, guardando / ocultando una conversión adicional:

pil_image = PIL.Image.open('image.jpg')
opencvImage = cv2.cvtColor(numpy.array(pil_image), cv2.COLOR_RGB2BGR)

Si lee un archivo de una URL:

import cStringIO
import urllib
file = cStringIO.StringIO(urllib.urlopen(r'http://stackoverflow.com/a_nice_image.jpg').read())
pil_image = PIL.Image.open(file)
opencvImage = cv2.cvtColor(numpy.array(pil_image), cv2.COLOR_RGB2BGR)

1
Si descarga desde la url, iría con:import requests response = requests.get(url) opencvImage = imdecode(np.asarray(bytearray(response.content)), 1)
Lior

4
¿Cómo convierto la imagen pil a mat de nuevo?

Nuestra respuesta devuelve este error: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor
Färid Alijani

trabajos. ¿Por qué todo el mundo en el mundo de las pitones no declara sus importaciones?
pscheit
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.