Ubah gambar dari PIL ke format openCV

95

Saya mencoba mengonversi gambar dari PILke OpenCVformat. Saya menggunakan OpenCV 2.4.3. inilah yang saya coba sampai sekarang.

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

Tapi saya pikir gambar tersebut tidak dapat diubah ke format CV. Jendela menunjukkan gambar coklat besar. Di manakah kesalahan saya dalam Mengonversi gambar dari PILke CVformat?

Juga, mengapa saya perlu mengetik cv.cvuntuk mengakses fungsi?

md1hunox.dll
sumber
Kemungkinan duplikat: stackoverflow.com/questions/1650568/…
Tim
Saya merujuk pada pertanyaan yang Anda sebutkan, tetapi solusi yang diberikan di sana tampaknya tidak berhasil untuk saya
md1hunox
Saya rasa Anda perlu mengubah gambar dari RGB ke BGR. periksa apakah berhasil.
Froyo

Jawaban:

163

Gunakan ini:

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
sumber
2
Terima kasih, Bisakah Anda menjelaskan kepada saya apa yang baris terakhir lakukan secara detail?
md1hunox
17
Anda memiliki gambar RGB yang diwakili oleh larik 3d, seperti pada ex = numpy.array([ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [0, 1, 2] ] ]). Begitu ex[0]juga baris pertama gambar Anda, ex[0][0]merupakan kolom pertama dari baris pertama, ex[0][0][0]merupakan komponen merah dari piksel pertama, ex[0][0][1]merupakan komponen hijau, dan ex[0][0][2]merupakan komponen biru. Karena Anda tampaknya membutuhkan gambar BGR (urutan kebalikan dari RGB), Anda membalikkan setiap elemen yang menggambarkan piksel seperti pada ex[0][0][::-1]. Baris terakhir (kecuali yang tidak berguna .copy) sama dengan operasi ini untuk keseluruhan gambar.
mmgp
16
Ini mungkin hanya sedikit peningkatan kinerja, tetapi cv2.cvtColor(open_cv_image, cv2.cv.CV_BGR2RGB) sedikit lebih efisien.
GuillaumeDufay
Apa tujuan .convert ('RGB') dalam jawaban Anda? Saya bekerja dengan gambar skala abu-abu 16 bit (mode gambar = I; 16) .. sejauh ini nparray menjaga gambar sebagai objek gambar PIL. (yaitu, larik dengan hanya satu entri, gambar PIL asli)
pengguna391339
3
Jika gambarnya biner (misalnya, biner yang dipindai TIF), maka array numpy akan menjadi booldan Anda tidak akan dapat menggunakannya dengan OpenCV. Dalam hal ini Anda perlu mengubahnya menjadi masker OpenCV:if image.dtype == bool: image = image.astype(np.uint8) * 255
Maksym Ganenko
91

Ini adalah versi terpendek yang dapat saya temukan, menyimpan / menyembunyikan konversi tambahan:

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

Jika membaca file dari 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)
Berthier Lemieux
sumber
1
Jika mengunduh dari url, saya akan pergi dengan:import requests response = requests.get(url) opencvImage = imdecode(np.asarray(bytearray(response.content)), 1)
Lior
4
bagaimana cara mengubah gambar pil ke mat lagi?
Jawaban Anda mengembalikan kesalahan ini: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor
Färid Alijani
bekerja. Mengapa semua orang di dunia python tidak menyatakan impornya?
pscheit