[PYTHON] Ersetzen Sie Bildfarben schnell durch PIL / Kissen

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

sample.png  result.png

Das Bild ist RGB 24-Bit ohne Alpha und der Code ist in Python2 geschrieben.

Trennen Sie Bilder nach Farbe

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.

r.png g.png b.png

Binarisieren Sie für jede bestimmte Farbe in Image.point

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.

_r.png _g.png _b.png

UND setzt jedes Band zusammen, um eine Maske zu erzeugen

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

mask.png

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)

Verarbeitungsgeschwindigkeit

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

Ersetzen Sie Bildfarben schnell durch PIL / Kissen
Bildverarbeitung mit PIL (Pillow)
Bildverarbeitung mit PIL
Erstellen Sie mit Python + PIL ein Dummy-Image.
Generieren Sie mit Pillow (PIL) viele Einzelzeichenbilder.
Verwenden Sie PIL oder Pillow mit Cygwin Python
Ich habe versucht, mit Pillow mit dem Bild zu spielen
Verarbeiten Sie Bilder in Python ganz einfach mit Pillow
Erstellen Sie eine Bildkompositions-App mit Flask + Pillow
PIL-Installation mit Pip
PIL / Kissen Spickzettel
Bilderkennung mit Keras
Bildverarbeitung mit Python
Konvertieren Sie den Farbraum von RGB nach CIELAB mit PIL (Pillow)