Konvertieren Sie das Bild von PIL in das openCV-Format


94

Ich versuche, Bilder von PILin ein OpenCVFormat zu konvertieren. Ich benutze OpenCV 2.4.3. Hier ist, was ich bis jetzt versucht habe.

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

Aber ich denke, das Bild wird nicht in das CV-Format konvertiert. Das Fenster zeigt mir ein großes braunes Bild. Wo mache ich beim Konvertieren von Bildern von PILin ein CVFormat einen Fehler?

Warum muss ich auch tippen, cv.cvum auf Funktionen zuzugreifen?



Ich bezog mich auf die Frage, die Sie erwähnt haben, aber die dort gegebene Lösung scheint für mich nicht zu funktionieren
md1hunox

Ich denke, Sie müssen das Bild von RGB in BGR konvertieren. Überprüfen Sie, ob es funktioniert.
Froyo

Antworten:


162

benutze das:

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
Danke, können Sie mir bitte erklären, was die letzte Zeile im Detail macht?
md1hunox

17
Sie haben ein RGB-Bild, das wie in durch ein 3D-Array dargestellt wird ex = numpy.array([ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [0, 1, 2] ] ]). So ex[0]ist die erste Zeile Ihres Bildes, ex[0][0]ist die erste Spalte der ersten Zeile, ex[0][0][0]ist die rote Komponente des ersten Pixels, ex[0][0][1]ist die grüne Komponente und ex[0][0][2]ist die blaue Komponente. Da Sie anscheinend ein BGR-Bild benötigen (die umgekehrte Reihenfolge von RGB), invertieren Sie jedes Element, das ein Pixel wie in beschreibt ex[0][0][::-1]. Die letzte Zeile (mit Ausnahme der nutzlosen .copy) entspricht dieser Operation für das gesamte Bild.
mmgp

16
Dies ist möglicherweise nur eine geringfügige Leistungsverbesserung, aber cv2.cvtColor(open_cv_image, cv2.cv.CV_BGR2RGB) etwas effizienter.
GuillaumeDufay

Was war der Zweck von .convert ('RGB') in Ihrer Antwort? Ich arbeite mit einem 16-Bit-Graustufenbild (Bildmodus = I; 16). Bisher behält das nparray das Bild als einzelnes PIL.Image-Objekt bei. (dh ein Array mit nur einem Eintrag, dem ursprünglichen PIL.Image)
user391339

3
Wenn das Bild binär ist (z. B. gescanntes Binärbild TIF), ist das numpy-Array so, booldass Sie es nicht mit OpenCV verwenden können. In diesem Fall müssen Sie es in OpenCV-Maske konvertieren:if image.dtype == bool: image = image.astype(np.uint8) * 255
Maksym Ganenko

89

Dies ist die kürzeste Version, die ich finden konnte. Sie speichert / versteckt eine zusätzliche Konvertierung:

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

Wenn Sie eine Datei von einer URL lesen:

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
Beim Herunterladen von der URL würde ich gehen mit:import requests response = requests.get(url) opencvImage = imdecode(np.asarray(bytearray(response.content)), 1)
Lior

4
Wie konvertiere ich das Pil-Bild wieder in eine Matte?

Ihre Antwort gibt diesen Fehler zurück: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor
Färid Alijani

funktioniert. Warum gibt das nicht jeder in der Python-Welt seine Importe an?
pscheit
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.