jak przekonwertować obraz RGB na tablicę numpy?


Odpowiedzi:


142

Możesz użyć nowszego interfejsu Pythona OpenCV (jeśli się nie mylę, jest dostępny od OpenCV 2.2). Natywnie używa tablic numpy:

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

wynik:

<type 'numpy.ndarray'>

95
Uważaj, cv2.imread () zwraca tablicę numpy w BGR, a nie w RGB.
2017

6
@pnd Twój komentarz jest święty!
Eduardo Pignatelli

4
Na przyszłość: $ pip install opencv-pythonaby zainstalować opencv
Kyle C

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

8
Wydaje się, że OpenCV porzucił modeargument. Zobacz moją odpowiedź poniżej, aby uzyskać zaktualizowaną metodę.
belvederef

73

PIL (Python Imaging Library) i Numpy dobrze ze sobą współpracują.

Używam następujących funkcji.

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” jest trochę brzydki, ponieważ przycinam przychodzące dane do [0,255], konwertuję na bajty, a następnie tworzę obraz w skali szarości. Pracuję głównie w kolorze szarym.

Obraz RGB wyglądałby tak:

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

1
To kończy się błędem TypeError: long() argument must be a string or a number, not 'PixelAccess'i patrząc na dokumentację PixelAccessklasy PIL , nie wydaje się, aby zawierała ona metody, które umożliwiłyby np.arraykonwersję danych źródłowych do ndarrayformatu. Musisz pominąć użycie img.load()i zająć się tylko wynikiem Image.open(...).
ely

Img.load () rozwiązuje dziwny problem z buforowaniem w PIL. Dane nie zostaną załadowane, dopóki nie będą wyraźnie potrzebne. Przykład nadal działa dla mnie z wyjątkiem zmiany opcji „import Image” na „from PIL import Image” podczas pracy z Pillow (widelcem PIL).
David Poole

Głosuj za użyciem tylko PIL, a nie OpenCV. Nie jestem jednak przeciwny OpenCV.
progyammer


19

Na dzień dzisiejszy najlepiej jest użyć:

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

Zobaczysz imgtablicę numpy typu:

<class 'numpy.ndarray'>

12

Późna odpowiedź, ale wolę imageiomoduł od innych alternatyw

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

Podobnie jak cv2.imread()domyślnie tworzy tablicę numpy, ale w postaci RGB.


7

Musisz użyć cv.LoadImageM zamiast 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)

Wielkie dzięki ... Czy mógłbyś mi również pomóc dowiedzieć się, że jeśli utworzę obraz za pomocą 'cv.CreateImage (szerokość, wysokość, kanały)' ... Jak można go przekonwertować na tablicę numpy?
Shan

Myślę, że musisz zamiast tego użyć cv.CreateMat lub cv.CreateMat i skopiować z obrazu na matę za pomocą cv.CvtColor lub czegoś podobnego. Spójrz na link, który Paul zamieścił powyżej.
Justin Peel,

3

Korzystając z odpowiedzi Davida Poole'a, otrzymuję błąd SystemError z plikami PNG w skali szarości i być może innymi plikami. Moje rozwiązanie to:

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

Właściwie img.getdata () działałoby dla wszystkich plików, ale jest wolniejsze, więc używam go tylko wtedy, gdy inna metoda zawodzi.


2

Format obrazu OpenCV obsługuje interfejs tablicy numpy. Można utworzyć funkcję pomocniczą obsługującą obrazy w skali szarości lub kolorowe. Oznacza to, że konwersja BGR -> RGB może być wygodnie wykonana za pomocą numpy plaster, a nie pełnej kopii danych obrazu.

Uwaga: jest to sztuczka krokowa, więc modyfikacja tablicy wyjściowej spowoduje również zmianę danych obrazu OpenCV. Jeśli chcesz kopię, użyj .copy()metody na tablicy!

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

Przyjąłem również imageio, ale znalazłem następujące maszyny przydatne do przetwarzania wstępnego i końcowego:

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)

Powodem jest to, że używam numpy do przetwarzania obrazu, a nie tylko do wyświetlania obrazu. W tym celu uint8 są niewygodne, więc konwertuję na wartości zmiennoprzecinkowe z zakresu od 0 do 1.

Podczas zapisywania obrazów zauważyłem, że musiałem sam wyciąć wartości spoza zakresu, w przeciwnym razie otrzymałem naprawdę szary wynik. (Szary wynik był wynikiem kompresji imageio pełnego zakresu, który był poza [0, 256), do wartości znajdujących się w tym zakresie).

Było też kilka innych dziwactw, o których wspomniałem w komentarzach.


1

Możesz łatwo uzyskać tablicę numpy obrazu rgb używając numpyiImage 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

załaduj obraz, używając następującej składni: -

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.