Перетворити зображення з PIL у формат openCV


95

Я намагаюся перетворити зображення PILу OpenCVформат. Я використовую OpenCV 2.4.3. ось те, що я намагався досі.

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

Але я думаю, що зображення не перетворюється у формат CV. Вікно показує мені велике коричневе зображення. Де я помиляюся при перетворенні зображення PILу CVформат?

Крім того, чому мені потрібно вводити текст cv.cvдля доступу до функцій?


Можливий дублікат: stackoverflow.com/questions/1650568/…
Тім

Я посилався на запитання, яке ви згадали, але наведене там рішення, здається, не працює для мене
md1hunox

Думаю, вам потрібно перетворити зображення з RGB на BGR. перевірте, чи працює.
Froyo

Відповіді:


163

використовуй це:

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
Дякую, чи можете ви пояснити мені, що докладно робить останній рядок?
md1hunox

17
У вас є зображення RGB, представлене тривимірним масивом, як у ex = numpy.array([ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [0, 1, 2] ] ]). Так ex[0]само перший рядок вашого зображення, ex[0][0]перший стовпець першого рядка, ex[0][0][0]червоний компонент першого пікселя, ex[0][0][1]зелений компонент та ex[0][0][2]синій компонент. Оскільки вам, мабуть, потрібне зображення BGR (зворотний порядок RGB), ви інвертуєте кожен елемент, що описує піксель, як у ex[0][0][::-1]. Останній рядок (крім марного .copy) є еквівалентом цієї операції для всього зображення.
mmgp

16
Це може бути лише незначне покращення продуктивності, але cv2.cvtColor(open_cv_image, cv2.cv.CV_BGR2RGB) трохи ефективніше.
Гійом

Якою була мета .convert ('RGB') у вашій відповіді? Я працюю з 16-бітовим зображенням у градаціях сірого (режим зображення = I; 16) .. поки що nparray зберігає зображення як єдиний об'єкт PIL.Image. (тобто масив лише з одним записом, оригінальний PIL.Image)
user391339

3
Якщо зображення є двійковим (наприклад, відсканованим двійковим файлом TIF), тоді масив numpy буде, boolі тому ви не зможете використовувати його з OpenCV. У цьому випадку вам потрібно перетворити його на маску OpenCV:if image.dtype == bool: image = image.astype(np.uint8) * 255
Максим Ганенко

91

Це найкоротша версія, яку я міг знайти, зберігаючи / приховуючи додаткове перетворення:

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

При читанні файлу з 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
Якби завантажував з url, я б пішов із:import requests response = requests.get(url) opencvImage = imdecode(np.asarray(bytearray(response.content)), 1)
Ліором

4
як знову перетворити зображення pil в мат?

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor
Ваша

робіт. Чому в світі пітонів усі не заявляють про свій імпорт?
pscheit
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.