[PYTHON] PIL / Kissen Spickzettel

PIL / Pillow ist eine kompakte und schnelle Bildbibliothek für Python. Wir haben häufig verwendete Prozesse zusammengefasst (von Zeit zu Zeit aktualisiert).

Unterschied zwischen PIL und Kissen

Grundsätzlich gibt es keinen Grund, PIL zu verwenden. Pillow hat eine Fehlerbehebung für den Größenänderungsfilter und ist von höherer Qualität.

Über die Kissengeschwindigkeit

Pillow ist sehr schnell abgestimmt und läuft immer schneller als eine ähnliche Bibliothek, ImageMagick. "Getpixel" / "Putpixel" ist jedoch sehr langsam. Verwenden Sie es daher nur für die Bilderzeugung. Es gibt auch eine schnellere "Pillow-Simd". Es scheint ungefähr 4 bis 5 Mal schneller zu sein als das Originalkissen.

pillow-simd https://github.com/uploadcare/pillow-simd

Referenz

https://python-pillow.org/pillow-perf/

Bildmodusliste

Modus Erläuterung
1 Bei Verwendung für eine 1-Bit-Maske ist eine logische Berechnung möglich
L 8bit Graustufen
P Palettenmodus
RGB 8bit x 3
RGBA 8bit x 4 Transparenz(Alpha)Mit
CMYK 8bit x 4 Wird häufig zum Drucken verwendet
YCbCr Wird häufig für 8-Bit x 3-Videos verwendet
HSV Nur 8bit x 3 Kissen
RGBa RGB-Wert mit Alphakanal multiplizieren
LA Multiplizieren Sie den L-Wert mit dem Alpha-Kanal
I 32-Bit-Ganzzahl
F 32bit schwimmende Minderheit

Filtergröße ändern

Filter Downscaling-Qualität Upscaling-Qualität Performance
Image.NEAREST ⭐⭐⭐⭐⭐
Image.BOX ⭐⭐⭐⭐
Image.BILINEAR ⭐⭐⭐
Image.HAMMING ⭐⭐ ⭐⭐⭐
Image.BICUBIC ⭐⭐⭐ ⭐⭐⭐ ⭐⭐
Image.LANCZOS ⭐⭐⭐⭐ ⭐⭐⭐⭐

Bildmodul

Graustufen

img.convert("L")

mono.png

Graustufen unter Berücksichtigung des Alpha-Werts

alpha.convert("LA")

alpha.pngla.png

Übrigens berücksichtigt convert ('L') den Alpha-Wert nicht.

alpha.convert("L")

alpha.pngl.png

HSV-Umstellung

img.convert("HSV")

Nur Kissen können in HSV-Farbraum umgewandelt werden. Es besteht aus drei Komponenten: Farbton, Sättigung und Wert. Das Folgende ist ein Beispiel für das Verschieben des Farbrads.

h, s, v = img.convert("HSV").split()
_h = ImageMath.eval("(h + 128) % 255", h=h).convert("L")
Image.merge("HSV", (_h, s, v)).convert("RGB")

hsv.png

CIE XYZ-Konvertierung

CIE XYZ ist ein Farbraum, der so angepasst ist, dass der euklidische Abstand zwischen den Farben dem vom Menschen wahrgenommenen Unterschied entspricht.

rgb2xyz = (
    0.412453, 0.357580, 0.180423, 0,
    0.212671, 0.715160, 0.072169, 0,
    0.019334, 0.119193, 0.950227, 0
)
img.convert("RGB", rgb2xyz)

Binarisierung

gray = img.convert("L")                     #In Graustufen konvertieren
gray.point(lambda x: 0 if x < 230 else x)   #Wenn der Wert 230 oder weniger beträgt, ist er 0.

bin.png

Das Bild aufhellen / abdunkeln

img.point(lambda x: x * 1.5)    # 1.Mach es 5 mal heller
img.point(lambda x: x * 0.5)    # 1 /Verdunkeln Sie auf 2

ligter.pngdarker.png

Sepia

Konvertieren Sie das Bild in Graustufen und dann in Sepia.

gray = img.convert("L")
Image.merge(
    "RGB",
    (   
        gray.point(lambda x: x * 240 / 255),
        gray.point(lambda x: x * 200 / 255),
        gray.point(lambda x: x * 145 / 255)
    )
)

cepia.png

Gamma-Korrektur

Die Gammakorrektur kann auch mithilfe einer Nachschlagetabelle mit sehr hoher Geschwindigkeit konvertiert werden. Unter der Annahme, dass src = Eingabefarbe, γ = Gammawert und g = Verstärkungswert ist, lautet die Gammakorrekturformel wie folgt.

dst = \biggl(\frac{src}{255}\biggr)^{1/γ} \times g \times 255
def gamma_table(gamma_r, gamma_g, gamma_b, gain_r=1.0, gain_g=1.0, gain_b=1.0):
    r_tbl = [min(255, int((x / 255.) ** (1. / gamma_r) * gain_r * 255.)) for x in range(256)]
    g_tbl = [min(255, int((x / 255.) ** (1. / gamma_g) * gain_g * 255.)) for x in range(256)]
    b_tbl = [min(255, int((x / 255.) ** (1. / gamma_b) * gain_b * 255.)) for x in range(256)]
    return r_tbl + g_tbl + b_tbl

img.point(gamma_table(1.2, 0.5, 0.5))

gamma.png

Beschleunigung des in Schleifen verwendeten Punkts

Es ist besser, "Lambda" nicht in der Schleife an "Image.point" zu übergeben. Es ist schneller, es im Voraus zu erweitern, da das an "Point" übergebene Argument nur eine Konvertierungstabelle ist.

for ...:
   img.point(lambda x: x * 100)

#Der untere Prozess ist gleich dem oberen Prozess, aber schneller
table = [x * 100 for x in range(256)] * len(img.getbands())
for ...:
    img.point(table)

getbbox Image.getbbox gibt den kleinsten Wert ungleich Null im Bild zurück, ein Bild mit allen 0-Werten gibt None zurück.

Randschnitt der Alpha-Komponente

alpha = Image.open("alpha.png ")

crop = alpha.split()[-1].getbbox()
alpha.crop(crop)

範囲を選択_003.png範囲を選択_004.png

Gleiche Pixelprüfung

Wenn die beiden Bilder gleich sind, gibt "ImageChops.difference" alle 0 Bilder zurück. Wenn "getbbox" "None" ist, kann dies als gleich beurteilt werden.

ImageChops.difference(img1, img2).getbbox() is None

Größe ändern

img.resize((128, 128), Image.LANCZOS)

resize.png

Miniaturansicht

Im Gegensatz zur Größenänderung behalten Miniaturansichten ihr Seitenverhältnis bei. Beachten Sie, dass "Thumbnail" aus irgendeinem Grund eine destruktive Methode ist, sondern "Image.copy". Es ist daher eine gute Idee, ein Duplikat zu erstellen.

img.thumbnail((128, 128), Image.LANCZOS)
img.size
# (128, 79)

thumb.png

Drehung

Wenn Sie für das Argument "Erweitern" "Wahr" angeben, wird das Bild erweitert, wenn es beim Drehen wächst.

img.rotate(90, expand=True)

rotate90.png

Mosaikverarbeitung

Die Mosaikverarbeitung kann mit "Image.LINEAR" verkleinert und vergrößert werden. Wenn Sie sie jedoch nach dem Anwenden der Gaußschen Unschärfe verkleinern, handelt es sich um ein weiches Mosaik.

#Gezacktes Mosaik
img.resize([x // 8 for x in img.size]).resize(img.size)

#Wenden Sie Gaußsche Unschärfe für ein weiches Mosaik an
gimg = img.filter(ImageFilter.GaussianBlur(4))
gimg.resize([x // 8 for x in img.size]).resize(img.size)

mozaic2.pngmozaic.png

Alpha-Mischung

Image.blend(img,effect_img, 0.5)

B9BSxGZmEQpmAAAAAElFTkSuQmCC.pngkL+ySM465ToAlAAAAAElFTkSuQmCC.pngblend.png

Subtraktive Farbe

img.quantize(4)    #Reduziert auf 4 Farben

quantize.png

Alpha-Bild einfügen

Um ein Bild mit Alpha einzufügen, geben Sie das Bild mit Alpha im Argument "Maske" von "Image.paste" an.

img.paste(alpha, mask=alpha)

paste.png

Zählen Sie die verwendeten Farben

Image.getcolors, das die verwendeten Farben zählt, kann ohne Argument nicht mehr als 255 Farben zählen. Bei Bildern, die mehr als 255 Farben verwenden, ist es sicher, die Anzahl der Pixel als Argument zu übergeben. [^ 1]

[^ 1]: 2017-02-07 Behoben Es war 'Image.getcount', aber es ist korrekt 'Image.getcolors', ich werde es reparieren.

img.getcolors(img.size[0] * img.size[1])

Histogramm

Gibt eine Liste von Bildfarbhistogrammen zurück. Da jedes Band kontinuierlich zurückgegeben wird, werden im RGB-Modus 256 x 3 = 768 Elemente zurückgegeben.

img.histogram()

Farbersatz

Es gibt keine Methode zum Ersetzen von Farben. Wenn Sie Farben ersetzen möchten, lesen Sie bitte den folgenden Artikel.

Ersetzen Sie Bildfarben schnell durch PIL / Kissen

ImageOps-Modul

Negative / positive Umkehrung

ImageOps.invert(img)

nega.png

Nach links / rechts / nach oben / unten drehen

ImageOps.mirror(img)    #Horizontal spiegeln
ImageOps.flip(img)      #auf den Kopf stellen

mirror.pngflip.png

Färbung

Färbt ein Graustufenbild mit einem Pixelwert von 0 bis "Schwarz" und einem Pixelwert von 255 bis "Weiß".

gray = ImageOps.grayscale(img)
ImageOps.colorize(gray, black=(0, 0, 0), white=(255, 255, 0))

mono.png → colorize.png

Posterisieren

Reduziert die Bittiefe des Bildes auf den Wert des Arguments, um die Farbe zu vereinfachen.

ImageOps.posterize(img, 2)

posterize.png

Solarisieren

Invertiert alle Pixelwerte über dem Schwellenwert. Ich weiß nicht, wo ich es verwenden soll.

ImageOps.solarize(img, 128)

solarize.png

Ausgleichen

Gleichen Sie das Bildhistogramm aus. Wenden Sie eine nichtlineare Zuordnung auf das Eingabebild an, um eine gleichmäßige Verteilung der Graustufenwerte im Ausgabebild zu erstellen.

ImageOps.equalize(img)

equalize.png

ImageChops-Modul

Das ImageChops-Modul ist ein Modul, das Kanäle bearbeitet.

B9BSxGZmEQpmAAAAAElFTkSuQmCC.pngkL+ySM465ToAlAAAAAElFTkSuQmCC.png

Das Bild links ist das betroffene Bild, und das Bild rechts ist das Bild für den Effekt. In diesem Kapitel werden diese beiden Bilder als Beispiele verwendet.

Ausweichen (linear) / Subtraktion

ImageChops.add(img, effect_img)         # img + effect_img
ImageChops.subtract(img, effect_img)    # img - effect_img

wE7Grw7M8iQMgAAAABJRU5ErkJggg==.pngX+81Pf98mz2EwAAAABJRU5ErkJggg==.png

Mod Betrieb

ImageChops.add_modulo(img, effect_img)         # img + effect_img % MAX
ImageChops.subtract_modulo(img, effect_img)    # img - effect_img % MAX

addm.pngsubm.png

Multiplizieren / Bildschirm

ImageChops.multiply(img, effect_img)
ImageChops.screen(img, effect_img)

8yo3kAAAAASUVORK5CYII=.pngP8BtLqhlqZTLrgAAAAASUVORK5CYII=.png

Vergleich (hell) / Vergleich (dunkel)

ImageChops.lighter(img, effect_img)
ImageChops.darker(img, effect_img)

X+81Pf98mz2EwAAAABJRU5ErkJggg==.pngwDMatqtY+79MgAAAABJRU5ErkJggg==.png

Absoluter Differenzwert

ImageChops.difference(img, effect_img)

diff.png

Versatz

ImageChops.offset(img, 100, 100)

offset.png

ImageFilter-Modul

Führt eine Faltung durch (Faltungsberechnung). Verschiedene Bildkonvertierungen werden durchgeführt, indem die als Kernel bezeichnete Matrix neu angeordnet wird.

Parameter Erläuterung
size Kernelgröße
scale Teilen Sie nach der Matrixoperation durch diesen Wert
offset Addiere diesen Wert nach der Matrixoperation
kernel Faltungsmatrix

Referenz

https://github.com/python-pillow/Pillow/blob/6e7553fb0f12025306b2819b9b842adf6b598b2e/PIL/ImageFilter.py

ImageFilter.BLUR

img.filter(ImageFilter.BLUR)

# size: (5, 5),
# scale: 16,
# offset: 0,
# kernel:(
#     1,  1,  1,  1,  1,
#     1,  0,  0,  0,  1,
#     1,  0,  0,  0,  1,
#     1,  0,  0,  0,  1,
#     1,  1,  1,  1,  1
# )

bluer.png

ImageFilter.DETAIL

img.filter(ImageFilter.DETAIL)

# size: (3, 3), 
# scale: 6,
# offset: 0,
# kernel: (
#     0, -1,  0,
#     -1, 10, -1,
#     0, -1,  0
# )

detail.png

ImageFilter.SHAPEN

img.filter(ImageFilter.SHARPEN)

# size: (3, 3),
# scale: 16,
# offset: 0,
# kernel: (
#     -2, -2, -2,
#     -2, 32, -2,
#     -2, -2, -2
# )

shapen.png

ImageFilter.CONTOUR

img.filter(ImageFilter.CONTOUR)

# size: (3, 3),
# scale: 1,
# offset: 255,
# kernel: (
#     -1, -1, -1,
#     -1,  8, -1,
#     -1, -1, -1
# )

contour.png

ImageFilter.EDGE_ENHANCE / ImageFilter.EDGE_ENHANCE_MORE

img.filter(ImageFilter.EDGE_ENHANCE)

# size: (3, 3),
# scale: 2,
# offset: 0,
# kernel: (
#     -1, -1, -1,
#     -1, 10, -1,
#     -1, -1, -1
# )

img.filter(ImageFilter.EDGE_ENHANCE_MORE)

# size: (3, 3),
# scale: 1,
# offset: 0,
# kernel: (
#     -1, -1, -1,
#     -1,  9, -1,
#     -1, -1, -1
# )

edge.pngedge_more.png

ImageFilter.EMBOSS

img.filter(ImageFilter.EMBOSS)

# size: (3, 3),
# scale: 1,
# offset: 128,
# kernel: (
#     -1,  0,  0,
#     0,  1,  0,
#     0,  0,  0
# )

emboss.png

ImageFilter.FIND_EDGES

img.filter(ImageFilter.FIND_EDGES)

# size: (3, 3),
# scale: 1,
# offset: 0,
# kernel: (
#     -1, -1, -1,
#     -1,  8, -1,
#     -1, -1, -1
# )

edge.png

ImageFilter.SMOOTH / ImageFilter.SMOOTH_MORE

img.filter(ImageFilter.SMOOTH)
# size: (3, 3),
# scale: 13,
# offset: 0,
# kernel: (
#     1,  1,  1,
#     1,  5,  1,
#     1,  1,  1
# )
# 

img.filter(ImageFilter.SMOOTH_MORE)
# size: (5, 5),
# scale: 100,
# offset: 0,
# kernel: (
#     1,  1,  1,  1,  1,
#     1,  5,  5,  5,  1,
#     1,  5, 44,  5,  1,
#     1,  5,  5,  5,  1,
#     1,  1,  1,  1,  1
# )

smooth.pngsmooth_more.png

Gaußsche Unschärfe

Gaußsche Unschärfeにより画面の平滑化します。

img.filter(ImageFilter.GaussianBlur(1.0))
img.filter(ImageFilter.GaussianBlur(1.5))
img.filter(ImageFilter.GaussianBlur(3.0))

gb10.pnggb15.pnggb30.png

Expansion / Kontraktion

"MaxFilter" heißt Dilatation und "MinFilter" heißt Erosion.

img.filter(ImageFilter.MinFilter())
img.filter(ImageFilter.MaxFilter())

min.pngmax.png

Referenz

Expansion / Kontraktion / Öffnen / Schließen

Medianfilter

MedianFilter wird häufig verwendet, um Rauschen zu entfernen, und seine Konturen sind weniger unscharf als bei Gauß-Filtern.

img.filter(ImageFilter.MedianFilter())

noise.pngmedian.png

Referenz

Rauschentfernung

Modusfilter

Wählt den am häufigsten verwendeten Pixelwert in einem Feld der angegebenen Größe aus. Pixelwerte, die nur ein- oder zweimal auftreten, werden ignoriert. ~~ Ich weiß nicht, wo ich es verwenden soll. Siehe ~~ Fotos mit Pillow's Mode Filter wie Gemälde aussehen lassen.

img.filter(ImageFilter.ModeFilter(5))

rank.png

Bildverbesserungsmodul

Einstellung der Farbbalance

enhancer = ImageEnhance.Color(img)
enhancer.enhance(0.0)    #Schwarz und weiß
enhancer.enhance(0.5)    #  ↕
enhancer.enhance(1.0)    #Das Originalbild

col0.pngcol05.pngsample.png

Kontrasteinstellung

enhancer = ImageEnhance.Contrast(img)
enhancer.enhance(0.0)    #Graues Bild
enhancer.enhance(0.5)    #  ↕
enhancer.enhance(1.0)    #Das Originalbild

con0.pngcon5.pngsample.png

Helligkeitsanpassung

enhancer = ImageEnhance.Brightness(img)
enhancer.enhance(0.0)    #Schwarzes Bild
enhancer.enhance(0.5)    #  ↕
enhancer.enhance(1.0)    #Das Originalbild

br0.pngbr5.pngsample.png

Schärfeeinstellung

enhancer = ImageEnhance.Sharpness(img)
enhancer.enhance(0.0)    #Verschwommenes Bild
enhancer.enhance(0.5)    #  ↕
enhancer.enhance(1.0)    #Das Originalbild
enhancer.enhance(1.5)    #  ↕
enhancer.enhance(2.0)    #Scharfes Bild

sha0.pngsample.pngsample.png

ImageMath-Modul

Das "ImageMath" -Modul ist ein Modul, mit dem Sie Operationen zwischen Pixeln schreiben können, als wären sie numerische Operationen. Wenn Sie es beherrschen, können Sie problemlos komplizierte Bildverarbeitungen schreiben.

Da nur ein einziges Band verarbeitet werden kann, ist das Konvertieren von Bildern wie RGB problematisch. Daher empfiehlt es sich, die folgende Hilfsfunktion vorzubereiten.

def _blend_f(img1, img2, func):
    blend_eval = "convert(func(float(a), float(b)), 'L')"
    bands = [
        ImageMath.eval(
            blend_eval,
            a=a,
            b=b,
            func=func
        )
        for a, b in zip(img1.split(), img2.split())
    ]
    return Image.merge(img1.mode, bands)

Referenz

Implementieren Sie Zeichenmodi wie PhotoShop mit hoher Geschwindigkeit mit PIL / Pillow

Overlay

def _over_lay(a, b):
    _cl = 2 * a * b / 255
    _ch = 2 * (a + b - a * b / 255) - 255
    return _cl * (a < 128) + _ch * (a >= 128)

_blend_f(img, effect_img, _over_lay)

overlay.png

Sanftes Licht

def _soft_light(a, b):
    _cl = (a / 255) ** ((255 - b) / 128) * 255
    _ch = (a / 255) ** (128 / b) * 255
    return _cl * (b < 128) + _ch * (b >= 128)

_blend_f(img, effect_img, _soft_light)

softlight.png

Hartes Licht

def _hard_light(a, b):
    _cl = 2 * a * b / 255
    _ch = 2.0 * (a + b - a * b / 255.0) - 255.0
    return _cl * (b < 128) + _ch * (b >= 128)

_blend_f(img, effect_img, _hard_light)

hardlight.png

Verwenden Sie den Photoshop-Zeichenmodus

Ich erstelle ein Modul namens "Image4Layer", das den Zeichenmodus von Photoshop implementiert.

https://github.com/pashango2/Image4Layer

Die Installation ist einfach mit Pip, Kissen (PIL) muss vorinstalliert sein, um zu laufen.

$pip install image4layer

Es ist einfach zu bedienen und ein Beispiel für das Zusammensetzen im Farbausweichmodus.

from PIL import Image
from image4layer import Image4Layer

source = Image.open("ducky.png ")
backdrop = Image.open("backdrop.png ")

Image4Layer.color_dodge(backdrop, source)

color_dodge.png

GIF schreiben

Sie können mehrere GIFs (GIF-Animationen) schreiben.

im.save(out, save_all=True, append_images=[im1, im2, ...])

Dies ist ein Beispiel für die Erstellung eines einfachen animierten GIF.

imgs = []
for i in range(100):
    imgs.append(img.point(lambda x: x * (1.0 - (i/100))))
    
img.save("anime.gif", save_all=True, append_images=imgs, loop=True)

animation.gif

Referenz

http://pillow.readthedocs.io/en/4.0.x/handbook/image-file-formats.html?highlight=seek#saving

Umstellung auf QImagae

Beim Konvertieren von PyQt in QImage wird das Modul "ImageQt" verwendet.

ImageQt.ImageQt(img)

Wenn Sie PySide verwenden, wird die folgende Methode empfohlen.

from PySide.QtGui import *
import io

img_buffer = io.BytesIO()
base.save(img_buffer, "BMP")
qimage = QImage()
qimage.loadFromData(img_buffer.getvalue(), "BMP")

Es mag wie ein verschwenderischer Prozess erscheinen, aber Pillow / PySide kümmert sich um die problematischen Teile wie die RGB → BGR-Konvertierung und das Problem der Y-Achsen-Inversion.

Referenz

Gegenseitige Konvertierung zwischen PIL.Image und PyQt4.QtGui.QImage

PSNR

Ein Indexwert, der PSNR mit zwei Bildern vergleicht. Derzeit ist SSIM besser als PSNR, aber PSNR wird auch häufig verwendet. Je höher der Wert, desto besser die Bildqualität. Bei der Messung des Grads der Verschlechterung der Komprimierung ist das PSNR zwischen 30 und 50 die Standardqualität.

Die Formel lautet wie folgt: MSE ist der durchschnittliche quadratische Fehler und MAX ist 255.

PSNR = 10 \times \log 10\frac{MAX^2}{MSE}

Die Funktion zum Auffinden von PSNR lautet wie folgt: Sie können PSNR mit hoher Geschwindigkeit finden, indem Sie das Modul "ImageStat" verwenden.

def psnr(img1, img2):
    diff_img = ImageChops.difference(img1, img2)
    stat = ImageStat.Stat(diff_img)
    mse = sum(stat.sum2) / len(stat.count) / stat.count[0]
    return 10 * math.log10(255 ** 2 / mse)

Es ist derzeit schwierig, SSIM mit PIL / Pillow mit hoher Geschwindigkeit zu finden. Verwenden Sie daher besser das Modul pyssim oder OpenCV.

Referenz

[Spitzen-Signal-Rausch-Verhältnis - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%94%E3%83%BC%E3%82%AF%E4%BF%A1%E5%8F % B7% E5% AF% BE% E9% 9B% 91% E9% 9F% B3% E6% AF% 94)

Extraktion von Strichzeichnungen

gray = img.convert("L")
gray2 = gray.filter(ImageFilter.MaxFilter(5))
senga_inv = ImageChops.difference(gray, gray2)
senga = ImageOps.invert(senga_inv)

senga.png

Ich bezog mich auf die Methode von hier, die sehr wunderbar ist.

Recommended Posts

PIL / Kissen Spickzettel
Curry Spickzettel
SQLite3 Spickzettel
pyenv Spickzettel
conda Befehl Spickzettel
ps Befehl Spickzettel
Spark API Spickzettel
Python3 Spickzettel (Basic)
PySpark Cheet Sheet [Python]
Python-Spickzettel
Tox Einstellungsdatei Spickzettel
Bildverarbeitung mit PIL (Pillow)
numpy Speicher wiederverwenden Spickzettel
[Python3] Standardeingabe [Cheet Sheet]
Data Science Cheet Sheet (Python)
Slack API Anhänge Spickzettel
Python Django Tutorial Cheet Sheet
Scikit lernen Algorithmus Spickzettel
Apache Beam Cheet Sheet [Python]
Persönlicher Spickzettel von Google Test / Mock
CPS-Spickzettel (Continuous Delivery Style)
Kissen
Python-Spickzettel (für C ++ erfahren)
Curry-Spickzettel [Listenversion des Beschreibungsbeispiels]
Generieren Sie mit Pillow (PIL) viele Einzelzeichenbilder.
Verwenden Sie PIL oder Pillow mit Cygwin Python
AtCoder Spickzettel in Python (für mich)
Blender Python Mesh Datenzugriffsprüfblatt
Cheet Sheet (Python) des Mathematical Optimization Modeler (PuLP)
Ersetzen Sie Bildfarben schnell durch PIL / Kissen