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?

md1hunox
quelle
Mögliches Duplikat: stackoverflow.com/questions/1650568/…
Tim
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() 
Abhishek Thakur
quelle
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)
Berthier Lemieux
quelle
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