2011-10-14 75 views
36

Tôi có hình ảnh RGB. Tôi muốn chuyển nó thành mảng numpy. Tôi đã làm như saulàm thế nào để chuyển đổi một hình ảnh RGB thành mảng numpy?

im = cv.LoadImage("abc.tiff") 
a = numpy.asarray(im) 

nó tạo ra một mảng không có hình dạng. Tôi cho rằng đó là đối tượng iplimage.

Cách thực hiện?

Cảm ơn

+2

Nếu 'cv' là module OpenCV, sau đó bạn nên tag nó như vậy. Liên kết này có thể giúp: http://opencv.willowgarage.com/documentation/python/cookbook.html#numpy-and-opencv – Paul

Trả lời

55

Bạn có thể sử dụng giao diện OpenCV python mới hơn (nếu tôi không nhầm nó có sẵn từ OpenCV 2.2). Nó natively sử dụng mảng NumPy:

import cv2 
im = cv2.imread("abc.tiff") 
print type(im) 

kết quả:

<type 'numpy.ndarray'> 
+1

cv2 là giao diện mới và dễ sử dụng hơn rất nhiều. Nó được thiết kế để biểu diễn chặt chẽ hơn các lớp C++. – Neon22

+6

Hãy coi chừng rằng cv2.imread() trả về một mảng có nhiều mảng trong BGR chứ không phải RGB. – pnd

+0

Nó có hoạt động với hình ảnh jpg, png và gif không? –

6

Bạn cần phải sử dụng cv.LoadImageM thay vì cv.LoadImage:

In [1]: import cv 
In [2]: import numpy as np 
In [3]: x = cv.LoadImageM('im.tif') 
In [4]: im = np.asarray(x) 
In [5]: im.shape 
Out[5]: (487, 650, 3) 
+0

Cảm ơn rất nhiều ... Bạn có thể vui lòng giúp tôi trong việc tìm ra rằng nếu tôi tạo một hình ảnh bằng cách sử dụng 'cv.CreateImage (chiều rộng, chiều cao, kênh)' ... Làm thế nào nó có thể được chuyển đổi thành mảng numpy? – Shan

+0

Tôi nghĩ rằng bạn cần phải sử dụng cv.CreateMat thay vào đó hoặc sử dụng cv.CreateMat và sao chép từ hình ảnh vào mat bằng cách sử dụng cv.CvtColor hoặc một số điều tương tự. Hãy xem liên kết mà Paul đã đăng ở trên. –

2
def opencv_image_as_array(im): 
    """Interface image from OpenCV's native format to a numpy array. 

    note: this is a slicing trick, and modifying the output array will also change 
    the OpenCV image data. if you want a copy, use .copy() method on the array! 
    """ 
    import numpy as np 
    w, h, n = im.width, im.height, im.channels 
    modes = {1:"L", 3:"RGB"}#, 4:"RGBA"} 
    if n not in modes: 
    raise StandardError('unsupported number of channels: {0}'.format(n)) 
    out = np.asarray(im) if n == 1 else np.asarray(im)[:,:,::-1] ## BGR -> RGB 
    return out 
32

PIL (Python Imaging Library) và NumPy làm việc tốt với nhau.

Tôi sử dụng các chức năng sau.

from PIL import Image 
import numpy as np 

def load_image(infilename) : 
    img = Image.open(infilename) 
    img.load() 
    data = np.asarray(img, dtype="int32") 
    return data 

def save_image(npdata, outfilename) : 
    img = Image.fromarray(np.asarray(np.clip(npdata,0,255), dtype="uint8"), "L") 
    img.save(outfilename) 

'Image.fromarray' hơi xấu vì tôi cắt dữ liệu đến [0,255], chuyển đổi thành byte, sau đó tạo hình ảnh thang độ xám. Tôi chủ yếu làm việc với màu xám.

Một RGB hình ảnh sẽ là một cái gì đó như:

outimg = Image.fromarray(ycc_uint8, "RGB") 
outimg.save("ycc.tif") 
+0

Lỗi này không thành công, đối số 'TypeError: long() phải là một chuỗi hoặc một số, không phải là 'PixelAccess'' và xem tài liệu cho lớp' PixelAccess' của PIL, nó dường như không cung cấp các phương thức cho phép' np.array' để chuyển đổi dữ liệu cơ bản của nó thành định dạng 'ndarray'. Bạn cần bỏ qua việc sử dụng 'img.load()' và chỉ xử lý kết quả của 'Image.open (...)'. – ely

+0

Hàm img.load() hoạt động xung quanh vấn đề bộ đệm ẩn trong PIL. Dữ liệu sẽ không được tải cho đến khi cần thiết.Ví dụ này vẫn hoạt động đối với tôi ngoại trừ việc thay đổi "Import Image" thành "from PIL import Image" khi làm việc với Pillow (nhánh PIL). –

1

Khi sử dụng câu trả lời từ David Poole tôi nhận được một SystemError với quy mô xám PNG và các file có thể khác. Giải pháp của tôi là:

import numpy as np 
from PIL import Image 

img = Image.open(filename) 
try: 
    data = np.asarray(img, dtype='uint8') 
except SystemError: 
    data = np.asarray(img.getdata(), dtype='uint8') 

Thực tế img.getdata() sẽ hoạt động cho tất cả các tệp nhưng chậm hơn, vì vậy tôi chỉ sử dụng khi phương thức khác không thành công.

+0

Điều này không hoạt động ở tất cả – mskw

5

Bạn cũng có thể sử dụng matplotlib cho việc này.

import matplotlib.image as mpimg 

img = mpimg.imread('abc.tiff') 
print(type(img)) 

đầu ra: <class 'numpy.ndarray'>

+1

Điều này rất đơn giản. Tôi thích nó :) –

Các vấn đề liên quan