image image


image

Spaß mit Processing.py: (Falsch-) Farbpaletten an ein bestehendes Bild anpassen

Es wird Zeit, daß ich mein erstes Projekt vorstelle, das ich – inspiriert von den hier vorgestellten, von Kevin Workman in P5.js realisierten »Happy Coding« Tutorials – in Processing.py programmiert habe. Es ist das Beispiel mit den Farbpaletten. Darin werden die Farben eines Photos auf eine (beliebige) Farbpalette reduziert.

Es funktioniert ähnlich dem POSTERIZE-Filter von Processing, nur daß in diesem Fall die Farben nicht im Bild vorhanden sein müssen, sondern es können beliebige Farbpaletten als Grundlage genommen werden. Dabei werden die Farben des Bildes der Farbe der Palette zugeordnet, die den geringsten Abstand zum Original besitzt. Dadurch ensteht so etwas wie ein Falschfarbenbild.

Die eigentliche Berechnung der neuen Farben findet in der Funktion get_palette_color(img_color) statt:

def get_palette_color(img_color):
    min_distance = 999999    
    img_r = red(img_color)
    img_g = green(img_color)
    img_b = blue(img_color)
    for c in palette:
        palette_r = red(c)
        palette_g = green(c)
        palette_b = blue(c)
        
        color_distance = dist(img_r, img_g, img_b,
                              palette_r, palette_g, palette_b)
        if color_distance < min_distance:
            target_color = c
            min_distance = color_distance
    return(target_color)

Die Distanz der Originalfarb-Tripel (RGB) zu den Paletten-Farb-Tripel wird berechnet und die Farbe mit dem kleinsten Abstand zur Originalfarbe wird dem Farbpixel zugewiesen. Dabei kommt mein kleiner, betagter Laptop ganz schön ins Schwitzen und es kann durchaus ein paar Sekunden dauern, bis das neue Bild auf dem Monitor angezeigt wird.

Als Referenz- und Testbild habe ich mein schon oft genutztes historisches Aktphoto aus dem 19. Jahrhundert verwendet, auch um zu sehen, ob irgendwelche prüden Tugendwächter in den sozialen Medien (jetzt mit Uploadfilter) das Bild durchgehen lassen oder ob es zensiert wird. Bis jetzt gab es allerdings noch keine Beanstandungen.

Genuary 23

Als erstes Beispiel habe ich die Palette »Genuary 23« von Kevin Workman benutzt, die ihn selber an einen Sonnenuntergang erinnert. Das Ergebnis sind tatsächlich warme, sonnige Farben.

image

genuary23 = ["#264653", "#2a9d8f", "#e9c46a", "#f4a261", "#e76f51"]

Riley 1

Ein ähnliches Ergebnis liefert meine Farbpalette Bridget Riley (1):

image

riley1 = [color(4, 21, 31), color(1, 155, 183), color(226, 107, 67), color(60, 76, 97),
          color(144, 166, 215), color(240, 192, 68), color(240, 245, 248)]

Riley 2

Fällt dagegen der Orange-Ton aus der Farbpalette hinaus, wie bei meiner Farbpalette [Bridget Riley (2)], dann entsteht ein Bild, das die Bezeichnung »Falschfarben« zu Recht verdient:

image

riley2 = [color(230, 230, 230), color(235, 200, 55), color(115, 165, 215),
          color(155, 195, 80), color(230, 135, 170), color(230, 80, 70),  
          color(65, 80, 150)]

Coding Train

Lustig und knallig bonbonbunt wird das Ergebnis, wenn ich die Coding Train Farbpalette darauf anwende:

image

codingtrain = ["#f05025", "#f89e50", "#f8ef22", "#31c5f4", "#f063a4",
               "#9252a1", "#817ac6", "#62c777"]

Vaporwave

Dann habe ich einige der Paletten mit einer Waporwave-ähnlichen Ästhetik eingesetzt, die Danny Antaki urspünglich für die Matplotlib entwickelt hatte. Zuerst die Palette Waporwave mit einem leicht gruseligen Ergbnis:

image

vaporwave    = ["#94d0ff", "#8795e8", "#966bff", "#ad8cff",
                "#c774e8", "#c774a9", "#ff6ad5", "#ff6a8b",
                "#ff8b8b", "#ffa58b", "#ffde8b", "#cdde8b",
                "#8bde8b", "#20de8b"]

Jazzcup

Dann die Palette Jazzcup, die den Akt in ein blaues Neonlicht taucht:

image

jazzcup      = ["#392682", "#7a3a9a", "#3f86bc", "#28ada8",
                "#83dde0"]

Seapunk

Und zuletzt die Palette Seapunk, die ein blau-grünes Ergebnis liefert:

image

seapunk      = ["#532e57", "#a997ab", "#7ec488", "#569874",
                "#296656"]

Precs Colors

Auch in dem Buch »Mastering Matplotlib« von Duncan M. McGreggor werden einige Farbpaletten vorgestellt (ich berichtete). Davon verwendet habe ich einmal die Palette PrecsColors, die eigentlich für die Visualisierung von Niederschlagsmengen und ähnlichem – von staubtrocken bis klitschnaß – gedacht war. Das Bild ähnelt einer aufgehellten Version von Seapunk:

image

precsColors = ["#f2d98f", "#f8ed39", "#a7cf38", "#7fc242",
               "#4680c2", "#3a53a3", "#6e4a98"]

Super Hero Theme

Und last but not least habe ich die Farben des SuperHero-Themes für Bootstrap von Thomas Park verwendet. Hier schließt sich der Kreis, denn das Ergebnis ähnelt wieder stark dem Genuary23-Ergebnis vom ersten Versuch:

image

superColors = ["#df691b", "#5cb85c", "#5bc0de",
               "#f0ad4e", "#d9534f", "#4e5d6c"]

Unter jedem Photo habe ich die Farbpalette als Python-Liste angegeben. Aber die Welt ist voller (auch gemeinfreier) Photos und Farbpaletten. Daher lade ich Euch hier zu eigenen Experimenten ein.

Quellcode

Damit Ihr experimentieren könnt, hier der vollständige Quellcode des Sketches:

# Nach einer Idee von Kevin Workman
# (https://happycoding.io/examples/p5js/images/image-palette)

WIDTH = 800
HEIGHT = 640

palette = ["#264653", "#2a9d8f", "#e9c46a", "#f4a261", "#e76f51"]

def setup():
    global img
    size(WIDTH, HEIGHT)
    this.surface.setTitle("Image Palette")
    img = loadImage("akt.jpg")
    image(img, 0, 0)
    noLoop()

def draw():
    global y, img
    for x in range(width/2):
        for y in range(height):
            img_color = img.get(x, y)
            palette_color = get_palette_color(img_color)
            set(x + width/2, y, palette_color)

def get_palette_color(img_color):
    min_distance = 999999    
    img_r = red(img_color)
    img_g = green(img_color)
    img_b = blue(img_color)
    for c in palette:
        palette_r = red(c)
        palette_g = green(c)
        palette_b = blue(c)
        
        color_distance = dist(img_r, img_g, img_b,
                              palette_r, palette_g, palette_b)
        if color_distance < min_distance:
            target_color = c
            min_distance = color_distance
    return(target_color)

Natürlich gibt es ihn auch in meinem GitHub-Repositorium. Habt Spaß damit!


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung

Diese Spalte wurde absichtlich leergelassen!


Werbung


image  image  image
image  image  image


image