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.