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.
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'>
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" )
Sie können auch matplotlib verwenden.
from matplotlib.image import imread
img = imread('abc.tiff')
print(type(img))
ausgabe: <class 'numpy.ndarray'>
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)
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.
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
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'>
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.
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.