Wenn Sie Farben durch PIL / Pillow ersetzen, können Sie am einfachsten Image.getpixel / Image.putpixel verwenden.
Image.getpixel / Image.putpixel ist jedoch so langsam, dass es einige Sekunden dauert, ein einzelnes Bild zu verarbeiten, was sehr langsam ist. Es gibt eine schnelle Ersetzungsmethode mit numpy, aber es erscheint dumm, die Anzahl der abhängigen Module beim Ersetzen von Farben zu erhöhen.
Daher habe ich mir eine Methode ausgedacht, um Farben mit hoher Geschwindigkeit nur durch PIL / Kissen zu ersetzen.
Ersetzen Sie als Beispiel die Kleidungsfarbe (255, 204, 0) im Bild unten durch (48, 255, 48).
Das Bild ist RGB 24-Bit ohne Alpha und der Code ist in Python2 geschrieben.
Verwenden Sie zunächst Image.split, um das Bild für jede Farbe in Bänder zu unterteilen.
from __future__ import unicode_literals, print_function, absolute_import
from PIL import Image, ImageChops
img = Image.open("sample.png ")
r, g, b = img.split()
Der Inhalt jedes RGB-Bandes ist wie folgt.
src_color = (255, 204, 0)
_r = r.point(lambda _: 1 if _ == src_color[0] else 0, mode="1")
_g = g.point(lambda _: 1 if _ == src_color[1] else 0, mode="1")
_b = b.point(lambda _: 1 if _ == src_color[2] else 0, mode="1")
Image.point ist eine Tabellenkonvertierungsmethode. Dieses Mal wird Lambda verwendet, um ein Bild zu generieren, das nur bestimmte Werte für jedes Band extrahiert.
Der Punkt ist, dass mode = "1" im Argument angegeben ist, und wenn "1" im Modus angegeben ist, wird ein Bild mit einer Farbtiefe von 1 Bit erzeugt. Dies ist der Prozess, der für die Konvertierung im später beschriebenen ImageChops-Modul erforderlich ist.
Der Inhalt jedes RGB-Bandes ist wie folgt.
Das ImageChops-Modul ist ein praktisches Modul, das verschiedene Compositing-Prozesse wie Additions-Compositing und Multiplikations-Compositing ausführen kann.
Dieses Mal wird die AND-Komposition mit ImageChops.logical_and ausgeführt. Diese Methode akzeptiert nur Bilder mit mode = "1".
mask = ImageChops.logical_and(_r, _g)
mask = ImageChops.logical_and(mask, _b)
Sie können eine Maske erstellen, die Pixel extrahiert, die in allen Bändern 1 sind (dh eine bestimmte Farbe).
Alles was Sie tun müssen, ist diese Maske zu verwenden, um die Farbe zu malen, die Sie ersetzen möchten.
dst_color = (48,255,48)
img.paste(Image.new("RGB", img.size, dst_color), mask=mask)
Ich habe die Verarbeitung mit dem Fall der Verwendung von getpixel / putpixel verglichen.
In [27]: %time replace_put_pixel(img, src_color, dst_color)
Wall time: 234 ms
In [28]: %time replace_fast(img, src_color, dst_color)
Wall time: 1.96 ms
Die getpixel / putpixel-Version hat 234 ms, während diese Methode 1,96 ms hat. Es ist mehr als 100 Mal schneller.
Recommended Posts