Ich versuche zu benutzen matplotlib
ein RGB-Bild einzulesen und in Graustufen umzuwandeln.
In Matlab benutze ich Folgendes:
img = rgb2gray(imread('image.png'));
Im matplotlib-Tutorial wird es nicht behandelt. Sie lesen nur das Bild ein
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
und dann schneiden sie das Array auf, aber das ist nicht dasselbe wie das Konvertieren von RGB in Graustufen, soweit ich weiß.
lum_img = img[:,:,0]
Es fällt mir schwer zu glauben, dass Numpy oder Matplotlib keine eingebaute Funktion zum Konvertieren von RGB in Grau haben. Ist dies nicht eine übliche Operation in der Bildverarbeitung?
Ich habe eine sehr einfache Funktion geschrieben, die mit dem importierten Bild imread
in 5 Minuten funktioniert . Es ist schrecklich ineffizient, aber deshalb habe ich auf eine integrierte professionelle Implementierung gehofft.
Sebastian hat meine Funktion verbessert, aber ich hoffe immer noch, die eingebaute zu finden.
Implementierung von matlab (NTSC / PAL):
import numpy as np
def rgb2gray(rgb):
r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
return gray
quelle
gray = np.mean(rgb, -1)
. Vielleichtrgb[...,:3]
da, wenn es tatsächlich rgba ist.gray = np.mean(rgb, -1)
funktioniert gut. Vielen Dank. Gibt es einen Grund, dies nicht zu verwenden? Warum sollte ich stattdessen die Lösungen in den folgenden Antworten verwenden?np.mean(rgb, -1)
.0.2989 * R + 0.5870 * G + 0.1140 * B
Ich gehe davon aus, dass dies die Standardmethode ist.Antworten:
Wie wäre es mit Pillow :
Mit matplotlib und der Formel
du könntest es tun:
quelle
matplotlib
aus einem anderen Grund verwenden muss, sollte er in der Lage sein, das eingebautecolorsys.rgb_to_yiq()
zu transformieren und ein Slice, um nur den Luma-Kanal zu erhalten..convert('LA')
? warum nicht.convert('gray')
? Scheint unnötig kryptisch. In der PIL-Dokumentation wird nichts über 'LA' für die Konvertierungsfunktion erwähnt.cannot write mode LA as JPEG
, musste ich den L-Modus verwenden, nicht LAimg = Image.open('image.png').convert('LA')
muss seinimg = Image.open('image.png').convert('L')
LA
Modus hat Leuchtkraft (Helligkeit) und Alpha. Wenn Sie denLA
Modus verwenden,greyscale.png
wird ein RGBA-Bild mit dem erhaltenen Alphakanal angezeigtimage.png
. Wenn Sie denL
Modus verwenden,greyscale.png
wird ein RGB-Bild (ohne Alpha) angezeigt.Sie können auch ein Scikit-Bild verwenden , das einige Funktionen zum Konvertieren eines Bildes bietet
ndarray
, zrgb2gray
.Anmerkungen : Die bei dieser Umrechnung verwendeten Gewichte sind für moderne CRT-Leuchtstoffe kalibriert: Y = 0,2125 R + 0,7154 G + 0,0721 B.
Alternativ können Sie das Bild in Graustufen lesen, indem Sie:
quelle
cmap
alsgray' then only the image is shown as gray in
pyplot.imshow () `verwenden? Irgendwelche Gedanken? Wo irre ich michDrei der vorgeschlagenen Methoden wurden mit 1000 RGBA-PNG-Bildern (224 x 256 Pixel), die mit Python 3.5 unter Ubuntu 16.04 LTS (Xeon E5 2670 mit SSD) ausgeführt wurden, auf Geschwindigkeit getestet.
Durchschnittliche Laufzeiten
pil :
1,037 Sekundenscipy:
1,040 Sekundensk :
2.120 SekundenPIL und SciPy ergaben identische
numpy
Arrays (im Bereich von 0 bis 255). SkImage gibt Arrays von 0 bis 1 an. Außerdem werden die Farben leicht unterschiedlich konvertiert (siehe Beispiel aus dem CUB-200-Datensatz).SkImage:
PIL :
SciPy :
Original:
Diff :
Code
Performance
quelle
Sie können die Bilddatei jederzeit von Anfang an als Graustufen mit
imread
OpenCV lesen :Wenn Sie das Bild als RGB lesen möchten, führen Sie eine Verarbeitung durch und konvertieren Sie es dann in Graustufen, die Sie
cvtcolor
von OpenCV aus verwenden können:quelle
0
Flagge istcv2.CV_LOAD_IMAGE_GRAYSCALE
.Der schnellste und aktuellste Weg ist die Verwendung von Pillow , installiert über
pip install Pillow
.Der Code lautet dann:
quelle
convert
eine konvertierte Kopie des Bildes zurückgegeben wirdDas Tutorial betrügt, weil es mit einem in RGB codierten Graustufenbild beginnt. Sie schneiden also nur einen einzelnen Farbkanal und behandeln ihn als Graustufen. Die grundlegenden Schritte, die Sie ausführen müssen, bestehen darin, den RGB-Farbraum in einen Farbraum umzuwandeln, der mit etwas codiert, das dem Luma / Chroma-Modell nahekommt, wie z. B. YUV / YIQ oder HSL / HSV. Anschließend wird der Luma-ähnliche Kanal abgeschnitten und als verwendet Ihr Graustufenbild.
matplotlib
scheint keinen Mechanismus für die Konvertierung in YUV / YIQ bereitzustellen, aber Sie können damit in HSV konvertieren.Versuchen Sie,
matplotlib.colors.rgb_to_hsv(img)
den letzten Wert (V) aus dem Array für Ihre Graustufen zu schneiden. Es ist nicht ganz dasselbe wie ein Luma-Wert, aber es bedeutet, dass Sie alles in tun könnenmatplotlib
.Hintergrund:
Alternativ können Sie PIL oder das integrierte Element verwenden
colorsys.rgb_to_yiq()
, um in einen Farbraum mit einem echten Luma-Wert zu konvertieren. Sie könnten auch All-In gehen und Ihren eigenen Luma-Konverter rollen, obwohl das wahrscheinlich übertrieben ist.quelle
Mit dieser Formel
Wir können es tun
Das GIMP , das Farbe in Graustufenbildsoftware konvertiert, verfügt jedoch über drei Algorithmen, um diese Aufgabe zu erledigen.
quelle
Wenn Sie NumPy / SciPy bereits verwenden, können Sie auch Folgendes verwenden :
scipy.ndimage.imread(file_name, mode='L')
quelle
scipy.ndimage.imread()
undscipy.misc.imread()
sind in SciPy 1.0.0 formal veraltet und werden in SciPy 1.2.0 dauerhaft entfernt . Während die Dokumentation von SciPyimageio.imread()
einen geeigneten Ersatz empfiehlt , ist die API dieser Funktion bis zur Absurdität ein absolutes Muss. Es bietet keine Unterstützung für die Graustufenkonvertierung und ist daher für viele Anwendungen - einschließlich unserer - ungeeignet.</sigh>
du könntest es tun:
quelle
Verwenden Sie img.Convert (), unterstützt "L", "RGB" und "CMYK". Modus
Ausgabe:
quelle
img = img.convert('L')
?Ich bin über Google auf diese Frage gekommen und habe nach einer Möglichkeit gesucht, ein bereits geladenes Bild in Graustufen umzuwandeln.
Hier ist eine Möglichkeit, dies mit SciPy zu tun:
quelle
img_gray = numpy.average(img, weights=[0.299, 0.587, 0.114], axis=2)
numpy.average
etwas schneller, aber praktisch nicht anders. Ihre Lösung ist klar und enthält relevante Informationen zu R, G, B, daher würde ich sie behalten. Mein Kommentar war eher eine zusätzliche Option, kein Ersatz.scipy.ndimage.imread()
undscipy.misc.imread()
sind in SciPy 1.0.0 formal veraltet und werden in SciPy 1.2.0 dauerhaft entfernt . Sie wollen wahrscheinlich nur Pillow builtin Graustufen - Konvertierung unterstützen verwenden (ala unutbu ‚s Antwort ), statt.Sie können
greyscale()
direkt für die Transformation verwenden.quelle