wake-up-neo.com

wie konvertiere ich ein RGB-Bild in ein Numpy-Array?

Ich habe ein RGB-Bild. Ich möchte es in Numpy Array konvertieren. Ich habe folgendes getan

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

Es erstellt ein Array ohne Form. Ich gehe davon aus, dass es sich um ein Bildobjekt handelt.

58
Shan

Sie können eine neuere OpenCV-Python-Schnittstelle verwenden (wenn ich mich nicht irre, ist sie seit OpenCV 2.2 verfügbar). Es verwendet nativ numpy Arrays:

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

ergebnis:

<type 'numpy.ndarray'>
80
Andrey Kamaev

PIL (Python Imaging Library) und Numpy arbeiten gut zusammen.

Ich benutze die folgenden Funktionen.

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 )

Das 'Image.fromarray' ist etwas hässlich, weil ich eingehende Daten in [0,255] abschneide, in Bytes konvertiere und dann ein Graustufenbild erzeuge. Ich arbeite meistens in Grau.

Ein RGB-Bild würde ungefähr so ​​aussehen:

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

Sie können auch matplotlib verwenden.

from matplotlib.image import imread

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

ausgabe: <class 'numpy.ndarray'>

21

Sie müssen cv.LoadImageM anstelle von cv.LoadImage verwenden:

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)
6
Justin Peel

Späte Antwort, aber ich habe das imageio-Modul den anderen Alternativen vorgezogen

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

Ähnlich wie cv2.imread() erzeugt es standardmäßig ein numpy-Array, jedoch in RGB-Form.

5
slizb
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
2
wim

Ab heute ist Ihre beste Wette zu verwenden:

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

Sie werden sehen, dass img ein numpy Array vom Typ ist:

<class 'numpy.ndarray'>
1
belvederef

Bei Verwendung der Antwort von David Poole erhalte ich einen SystemError mit Graustufen-PNGs und möglicherweise anderen Dateien. Meine Lösung ist:

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

Eigentlich würde img.getdata () für alle Dateien funktionieren, aber es ist langsamer, daher verwende ich es nur, wenn die andere Methode fehlschlägt.

1
daign

Ich habe auch imageio übernommen, aber ich fand die folgenden Maschinen für die Vor- und Nachbearbeitung nützlich:

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)

Der Grund ist, dass ich numpy für die Bildverarbeitung verwende, nicht nur Bilder. Zu diesem Zweck sind uint8s umständlich, daher konvertiere ich sie in Fließkommazahlen von 0 bis 1.

Beim Speichern von Bildern fiel mir auf, dass ich die Werte außerhalb des Bereichs selbst reduzieren musste, oder ich bekam eine wirklich graue Ausgabe. (Die graue Ausgabe war das Ergebnis der Komprimierung des gesamten Bereichs außerhalb von [0, 256] auf Werte innerhalb des Bereichs.)

Es gab auch ein paar andere Kuriositäten, die ich in den Kommentaren erwähnte.

0