làm thế nào để chuyển đổi một hình ảnh RGB sang mảng numpy?


113

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

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 giả sử nó là một đối tượng iplimage.


2
Nếu cvlà mô-đun OpenCV, thì bạn nên gắn thẻ nó như vậy. Liên kết này có thể hữu ích: opencv.willowgarage.com/documentation/python/…
Paul

Câu trả lời:


142

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

import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)

kết quả:

<type 'numpy.ndarray'>

94
Lưu ý rằng cv2.imread () trả về một mảng numpy trong BGR không phải RGB.
pnd

6
@pnd bình luận của bạn là thiêng liêng!
Eduardo Pignatelli

4
Để tham khảo trong tương lai: $ pip install opencv-pythonđể cài đặt opencv
Kyle C

2
TypeError: 'mode' is an invalid keyword argument for imread()
Rishabh Agrahari

8
OpenCV dường như đã bỏ modeđối số. Xem câu trả lời của tôi bên dưới để biết phương pháp cập nhật.
belvederef

73

PIL (Thư viện hình ảnh Python) và Numpy hoạt động tốt cùng 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 thành [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.

Hình ảnh RGB sẽ giống như sau:

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

1
Điều này không thành công với một lỗi TypeError: long() argument must be a string or a number, not 'PixelAccess'và khi xem tài liệu cho PixelAccesslớp của PIL , nó dường như không cung cấp các phương thức cho phép np.arraychuyển đổi dữ liệu cơ bản của nó thành một ndarrayđịnh dạng. Bạn cần phải bỏ qua việc sử dụng img.load()và chỉ xử lý với kết quả của Image.open(...).
ely

Img.load () giải quyết vấn đề bộ nhớ đệm kỳ lạ trong PIL. Dữ liệu sẽ không được tải cho đến khi cần một cách rõ ràng. Ví dụ này vẫn hoạt động với tôi ngoại trừ việc thay đổi "nhập Hình ảnh" thành "từ Hình ảnh nhập PIL" khi làm việc với Pillow (ngã ba PIL).
David Poole

Ủng hộ chỉ sử dụng PIL chứ không phải OpenCV. Tôi không chống lại OpenCV.
progyammer


19

Kể từ hôm nay, đặt cược tốt nhất của bạn là sử dụng:

img = cv2.imread(image_path)   # reads an image in the BGR format
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   # BGR -> RGB

Bạn sẽ thấy imgsẽ là một mảng kiểu numpy:

<class 'numpy.ndarray'>

12

Câu trả lời muộn, nhưng tôi thích imageiomô-đun hơn các lựa chọn thay thế khác

import imageio
im = imageio.imread('abc.tiff')

Tương tự như cv2.imread(), nó tạo ra một mảng numpy theo mặc định, nhưng ở dạng RGB.


7

Bạn cần 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)

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

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

3

Khi sử dụng câu trả lời từ David Poole, tôi nhận được Lỗi SystemError với các tệp PNG có thang màu xám và có thể là các tệp 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' )

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


2

Định dạng hình ảnh OpenCV hỗ trợ giao diện mảng numpy. Một chức năng trợ giúp có thể được thực hiện để hỗ trợ hình ảnh màu xám hoặc màu. Điều này có nghĩa là quá trình chuyển đổi BGR -> RGB có thể được thực hiện một cách thuận tiện với một lát nhỏ chứ không phải một bản sao đầy đủ của dữ liệu hình ảnh.

Lưu ý: đây là một thủ thuật sải bước, vì vậy việc sửa đổi mảng đầu ra cũng sẽ thay đổi dữ liệu hình ảnh OpenCV. Nếu bạn muốn một bản sao, hãy sử dụng .copy()phương thức trên mảng!

import numpy as np

def img_as_array(im):
    """OpenCV's native format to a numpy array view"""
    w, h, n = im.width, im.height, im.channels
    modes = {1: "L", 3: "RGB", 4: "RGBA"}
    if n not in modes:
        raise Exception('unsupported number of channels: {0}'.format(n))
    out = np.asarray(im)
    if n != 1:
        out = out[:, :, ::-1]  # BGR -> RGB conversion
    return out

1

Tôi cũng đã sử dụng imageio, nhưng tôi thấy máy móc sau hữu ích cho việc xử lý trước và sau:

import imageio
import numpy as np

def imload(*a, **k):
    i = imageio.imread(*a, **k)
    i = i.transpose((1, 0, 2))  # x and y are mixed up for some reason...
    i = np.flip(i, 1)  # make coordinate system right-handed!!!!!!
    return i/255


def imsave(i, url, *a, **k):
    # Original order of arguments was counterintuitive. It should
    # read verbally "Save the image to the URL" — not "Save to the
    # URL the image."

    i = np.flip(i, 1)
    i = i.transpose((1, 0, 2))
    i *= 255

    i = i.round()
    i = np.maximum(i, 0)
    i = np.minimum(i, 255)

    i = np.asarray(i, dtype=np.uint8)

    imageio.imwrite(url, i, *a, **k)

Lý do là tôi đang sử dụng numpy để xử lý hình ảnh, không chỉ hiển thị hình ảnh. Vì mục đích này, uint8s rất khó hiểu, vì vậy tôi chuyển đổi sang các giá trị dấu phẩy động từ 0 đến 1.

Khi lưu hình ảnh, tôi nhận thấy rằng mình phải tự mình cắt các giá trị nằm ngoài phạm vi, nếu không thì kết quả đầu ra thực sự xám. (Kết quả đầu ra màu xám là kết quả của việc imageio nén toàn bộ phạm vi nằm ngoài [0, 256), thành các giá trị nằm trong phạm vi.)

Có một vài điều kỳ lạ khác, mà tôi đã đề cập trong các bình luận.


1

Bạn có thể dễ dàng nhận được mảng hình ảnh rgb vô số bằng cách sử dụng numpyImage from PIL

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open('*image_name*') #These two lines
im_arr = np.array(im) #are all you need
plt.imshow(im_arr) #Just to verify that image array has been constructed properly

0

tải hình ảnh bằng cú pháp sau: -

from keras.preprocessing import image

X_test=image.load_img('four.png',target_size=(28,28),color_mode="grayscale"); #loading image and then convert it into grayscale and with it's target size 
X_test=image.img_to_array(X_test); #convert image into array
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.