Chuyển đổi hình ảnh từ PIL sang định dạng openCV


95

Tôi đang cố gắng để chuyển đổi hình ảnh từ PILđể OpenCVđịnh dạng. Tôi đang sử dụng OpenCV 2.4.3. đây là những gì tôi đã cố gắng cho đến bây giờ.

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

Nhưng tôi nghĩ rằng hình ảnh không được chuyển đổi sang định dạng CV. Cửa sổ cho tôi thấy một hình ảnh lớn màu nâu. Nơi tôi đi sai trong chuyển đổi hình ảnh từ PILđể CVđịnh dạng?

Ngoài ra, tại sao tôi cần gõ cv.cvđể truy cập các chức năng?



Tôi đề cập đến câu hỏi mà bạn đề cập, nhưng giải pháp đưa ra có doesnt dường như làm việc cho tôi
md1hunox

Tôi nghĩ bạn cần chuyển đổi hình ảnh từ RGB sang BGR. kiểm tra xem nó có hoạt động không.
Froyo

Câu trả lời:


163

dùng cái này:

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
Cảm ơn, Bạn có thể vui lòng giải thích cho tôi chi tiết dòng cuối cùng làm gì được không?
md1hunox

17
Bạn có một hình ảnh RGB được đại diện bởi một mảng 3d, như trong ex = numpy.array([ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [0, 1, 2] ] ]). Vì vậy, ex[0]là dòng đầu tiên của hình ảnh của bạn, ex[0][0]là cột đầu tiên của dòng đầu tiên, ex[0][0][0]là thành phần màu đỏ của pixel đầu tiên, ex[0][0][1]là thành phần màu xanh lá cây, và ex[0][0][2]là thành phần màu xanh. Vì bạn dường như cần một hình ảnh BGR (thứ tự nghịch đảo của RGB), bạn đảo ngược từng phần tử mô tả một pixel như trong ex[0][0][::-1]. Dòng cuối cùng (ngoại trừ phần vô dụng .copy) tương đương với thao tác này cho toàn bộ hình ảnh.
mmgp

16
Nó có thể chỉ là một cải thiện hiệu suất nhỏ, nhưng cv2.cvtColor(open_cv_image, cv2.cv.CV_BGR2RGB) hiệu quả hơn một chút.
GuillaumeDufay

Mục đích của .convert ('RGB') trong câu trả lời của bạn là gì? Tôi đang làm việc với hình ảnh thang độ xám 16 bit (chế độ hình ảnh = I; 16) .. cho đến nay nparray đang giữ hình ảnh dưới dạng một đối tượng PIL.Image duy nhất. (tức là một mảng chỉ có một mục nhập, PIL.Image ban đầu)
user391339

3
Nếu hình ảnh là nhị phân (ví dụ: nhị phân được quét TIF), thì mảng numpy sẽ là boolvà do đó bạn sẽ không thể sử dụng nó với OpenCV. Trong trường hợp này bạn cần phải chuyển nó sang OpenCV mặt nạ:if image.dtype == bool: image = image.astype(np.uint8) * 255
Maksym Ganenko

92

Đây là phiên bản ngắn nhất mà tôi có thể tìm thấy, lưu / ẩn một chuyển đổi bổ sung:

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

Nếu đọc tệp từ 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
Nếu tải xuống từ url, tôi sẽ đi với:import requests response = requests.get(url) opencvImage = imdecode(np.asarray(bytearray(response.content)), 1)
Lior

4
làm cách nào để chuyển đổi lại hình ảnh pil thành mat?

câu trả lời của bạn trả về lỗi này: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor
Färid Alijani

làm. Tại sao tất cả mọi người trong thế giới trăn không nói rõ nhập khẩu của nó?
pscheit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.