Medienprogrammierung in Python – Bildverarbeitung (2)

Werbung
Termin 5:
Medienprogrammierung in Python
– Bildverarbeitung (2)
Grundlagen der Informatik
Wintersemester 2006/07
Prof. Bernhard Jung
Übersicht
‰
Medienprogrammierung mit Python / JES
„
‰
‰
‰
z.B. Erzeugung von Negativen, Grauwertkonvertierung, …
Jes-Debugger
for-Schleifen in Python
if-Anweisung in Python
Hauptlernziele:
• Verstehen zentraler Kontrollstrukturen der imperativen Programmierung
• for – Schleife
• if … else (bedingte Anweisung)
• Digitale Medien:
• Verständnis von Farb-, Grauwert-, und Binärbildern
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
1
Wiederholung –
Beispiel: Ändern von Pixel-Werten
>>> filename = pickAFile()
>>> mypic = makePicture(filename)
>>> show(mypic)
>>> setColor(getPixel(mypic, 10, 100),yellow)
>>> setColor(getPixel(mypic, 11, 100),yellow)
>>> setColor(getPixel(mypic, 12, 100),yellow)
>>> setColor(getPixel(mypic, 13, 100),yellow)
>>> setColor(getPixel(mypic, 14, 100),yellow)
>>> setColor(getPixel(mypic, 15, 100),yellow)
>>> repaint(mypic)
jetzt 6 gelbe Pixel hier
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Bildverarbeitung mit Schleifen
- Definition eines Python-Skripts
def decreaseRed(picture):
for p in getPixels(picture):
value = getRed(p)
setRed(p, value * 0.5)
„
Verringerung des Rot-Anteils
in jedem Pixel des Bilds
Æ for-Schleife
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
2
Schleifen in Python
„
Aufbau von Schleifen
‰
‰
for – Schlüsselwort, Name der Anweisung
Indexvariable p
„
‰
‰
„
„
‰
‰
Name der Variable kann frei gewählt werden
in – Schlüsselwort, fester Teil der Anweisung
Eine Sequenz bzw. Ausdruck der eine Sequenz liefert
getPixels(picture) liefert Liste aller Pixel
zur Erinnerung (Vorlesung 3): Sequenz = Liste, String, oder Tupel
Doppelpunkt ':'
Rumpf der Schleife
„
„
eingerückt
hier besteht der Rumpf aus 2 Anweisungen
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Schleifen in Python
„
for <variable> in <sequenz>:
<anweisungen>
for i in ['a','b','c']:
print i
1.
2.
3.
Schleifendurchlauf: i = 'a' Æ Ausgabe: a
Schleifendurchlauf: i = 'b' Æ Ausgabe: b
Schleifendurchlauf: i = 'c' Æ Ausgabe: c
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
3
Schleifen in Python
„
for <variable> in <sequenz>:
<anweisungen>
for i in [4,6,9]:
print i
1.
2.
3.
Schleifendurchlauf: i = 4 Æ Ausgabe: 4
Schleifendurchlauf: i = 6 Æ Ausgabe: 6
Schleifendurchlauf: i = 9 Æ Ausgabe: 9
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Der JES-Watcher (Debugger)
Start des Watchers
Prof. B. Jung
Hinzufügen einer zu
beobachtenden Variablen (hier: i)
Grundlagen der Informatik, WS 2006/07
4
Beispiel Bildverarbeitung –
Generierung von Sonnenuntergängen
„
Idee: Blau- und Grün-Anteile im Bild reduzieren (Rot wird so
dominanter)
def makeSunset(picture):
for p in getPixels(picture):
value=getBlue(p)
setBlue(p,value*0.7)
value=getGreen(p)
setGreen(p,value*0.7)
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Beispiel Bildverarbeitung –
Generierung von Sonnenuntergängen
„
die zuvor definierte Funktion makeSunset() ist natürlich auf
beliebige Bilder anwendbar
‰
dazu muss nur die Funktion nur mit einem anderen Input-Parameter
aufgerufen werden
def makeSunset(picture):
for p in getPixels(picture):
value=getBlue(p)
setBlue(p,value*0.7)
value=getGreen(p)
setGreen(p,value*0.7)
tu-baf.jpg
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
5
Die range()-Funktion
„
range()-Funktion
‰
‰
Generierung von Listen mit Elementen zwischen den beiden
Input-Parametern
optionaler dritter Input-Parameter bestimmt Inkrement
>>> print range(1,4)
[1, 2, 3]
>>> print range(-1,3)
[-1, 0, 1, 2]
>>> print range(1,10,2)
[1, 3, 5, 7, 9]
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Beispiel: range()-Funktion
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
6
Indizierung von Pixeln
„
Bild: Matrix von Pixeln
‰
‰
„
Breite von Bildern: w = getWidth(picture)
Höhe von Bildern: h = getHeight(picture)
Pixel können über ihren Index (x,y) referenziert werden
‰
pixel = getPixel( picture, x, y)
Æ Bildverarbeitung mittels geschachtelte Schleifen …
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Geschachtelte Schleifen
„
Schachtelung von Schleifen:
‰
Rumpf einer Schleife ist wiederum eine Schleife
def increaseRed2(picture):
for x in range(1, getWidth(picture)+1 ):
for y in range(1, getHeight(picture)+1 ):
px = getPixel(picture,x,y)
value = getRed(px)
setRed(px, value*1.1)
„
hier: spaltenweise Bearbeitung der Pixel
‰
Verarbeitungsreihenfolge der Indices
„
„
„
„
Prof. B. Jung
(1,1), (1,2), (1,3) ….
(2,1), (2,2), (2,3), …
(3,1), (3,2), …
…
Grundlagen der Informatik, WS 2006/07
7
Farbersetzung in Teilbereichen von
Bildern
def increaseRedInRange(picture, xmin, ymin, xmax, ymax):
for x in range(xmin, xmax+1):
for y in range(ymin, ymax+1):
px = getPixel(picture,x,y)
value = getRed(px)
setRed(px, value*1.2)
>>> increaseRedInRange(pic2, 78, 41, 158, 59)
Auswahl des Bildbereichs
mittels MediaTools
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Beispiel Bildverarbeitung –
Erzeugung von Negativen
„
R, G, B-Werte im Bereich 0 .. 255
Negativ eines Pixels, z.B. (5,10,25):
„
Negativ eines Bilds: Negativ aller Pixel
„
Æ (255-5, 255-10, 255-25) = (250, 245, 230)
def negative(picture):
for px in getPixels(picture):
red=getRed(px)
green=getGreen(px)
blue=getBlue(px)
negColor=makeColor( 255-red, 255-green, 255-blue)
setColor(px,negColor)
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
8
Grauwertbilder
„
Farbbilder:
‰
‰
‰
„
Grauwertbilder
‰
‰
„
Drei Farbkanäle (RGB)
8 Bit = 1 Byte (0…255) pro Kanal
Darstellung von insgesamt 224 Farben
1 Farbkanal zu 8 Bit = 1 Byte
d.h. Darstellung von 28 = 256 Grauwerten
Konvertierung Farb- Æ Grauwertbild
‰
z.B. Luminanz =
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Konvertierung zu Grauwertbildern in JES
„
„
Echte Grauwertbilder: Pro Pixel 1 Farbwert
In JES:
‰
setze R,G,B auf denselben Farbwert, z.B.
def grayscale(picture):
for p in getPixels(picture):
intensity = (getRed(p) + getGreen(p) + getBlue(p)) / 3
setColor(p,makeColor(intensity,intensity,intensity))
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
9
Konvertierung zu Grauwertbildern
„
Bisherige Methode zur Berechnung des Grauwerts von Pixeln ist nicht optimal
„
Psychologische Experimente legen nahe, dass Wahrnehmung von Farben bzgl. Luminanz
unterschiedlich ist
‰
‰
„
z.B. wird blau als "dunkler" wahrgenommen als rot
auch bei gleicher physikalischer Lichtintensität
Grauwert-Konvertierung mit wahrnehmungspsychologisch fundierter Gewichtung:
def grayscaleweighted(picture):
for px in getPixels(picture):
newRed = getRed(px) * 0.299
newGreen = getGreen(px) * 0.587
newBlue = getBlue(px) * 0.114
luminance = newRed+newGreen+newBlue
setColor(px,makeColor(luminance,luminance,luminance))
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Grauwertkonvertierung
einfache
Grauwertkonvertierung
Prof. B. Jung
gewichtete
Grauwertkonvertierung
Grundlagen der Informatik, WS 2006/07
10
Beispiel: Farbauffrischung für Dächer
- Bedingtes Verändern von Pixelwerten
„
„
Ziel: Intensivierung des Rot-Anteils von Dächern
Idee: Erhöhung des Rotanteils von Pixeln
‰
aber nur wenn diese schon rötlich sind
Æ if-Anweisung
def intensifyRed(picture):
for p in getPixels(picture):
value=getRed(p)
if ( value > 180 ):
setRed(p,value*1.5)
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
Python: If-Anweisung
vgl. Programmablaufplan (VL 2)
„
„
„
if ( <Bedingung> ):
<Anweisungen>
if ( <Bedingung> ):
<Anweisungen>
else:
<Anweisungen>
ja
A1
B
nein
A2
Aufbau:
‰
‰
if – Schlüsselwort
Bedingung – kann zu True oder False evaluiert werden
„
„
‰
‰
‰
auch komplexe Bedingungen, z.B. verknüpft mit and
if ( a >5 and a <10):
Doppelpunkt
Anweisungen, die ausgeführt werden, falls Bedingung gilt
optionaler else-Teil
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
11
Beispiel: if … else
„
„
Ziel: Überprüfung, welche Pixel bei der beabsichtigten bedingten Pixeleinfärbung
überhaupt eingefärbt werden wurden
Zeichne ursprüngl. "rötliche" Pixel weiß, alle anderen schwarz
Æ Resultierendes Bild hat nur noch zwei Farben (schwarz/weiß) Æ "Binärbild"
def intensifyRed3(picture):
for p in getPixels(picture):
value=getRed(p)
if ( value > 180 ):
setColor(p, white)
else:
setColor(p, black)
Æ alle Dächer, aber nicht nur!
Æ bessere Bedingung für Dachpixel???
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
"Posterisierung" – Reduktion der Anzahl
der Farben in einem Bild
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
12
"Posterisierung" - Methode
„
Ganze Bereiche von Farb-Anteilen werden auf einen
bestimmten Farbanteil abgebildet
‰
‰
‰
z.B. falls Rotanteil < 64 dann setze Rotanteil = 31
z.B. falls Rotanteil zwischen 64 und 128 dann Rotanteil = 95
…
„
Implementierung durch Reihe von if-Anweisungen
„
Resultierendes Bild hat deutlich weniger Farben
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
"Posterisierung"
def posterize(picture):
#loop through the pixels
for p in getPixels(picture):
#get the RGB values
red = getRed(p)
green = getGreen(p)
blue = getBlue(p)
#check and set red values
if(red < 64):
setRed(p, 31)
if(red > 63 and red < 128):
setRed(p, 95)
if(red > 127 and red < 192):
setRed(p, 159)
if(red > 191 and red < 256):
setRed(p, 223)
Prof. B. Jung
#check and set green values
if(green < 64):
setGreen(p, 31)
if(green > 63 and green < 128):
setGreen(p, 95)
if(green > 127 and green < 192):
setGreen(p, 159)
if(green > 191 and green < 256):
setGreen(p, 223)
#check and set blue values
if(blue < 64):
setBlue(p, 31)
if(blue > 63 and blue < 128):
setBlue(p, 95)
if(blue > 127 and blue < 192):
setBlue(p, 159)
if(blue > 191 and blue < 256):
setBlue(p, 223)
Grundlagen der Informatik, WS 2006/07
13
Kommentare in Python
„
Programmzeilen, die mit '#' beginnen sind Kommentare
#loop through the pixels
for p in getPixels(picture):
…
„
Kommentare können auch in der Mitte von Programmzeilen
beginnen
setRed(pixel, 255) # update Rot-Anteil des Pixels
„
Kommentare in Programmen dienen der Dokumentation des Codes
‰
Kommentare werden vom Python-Interpreter nicht ausgewertet
Prof. B. Jung
Grundlagen der Informatik, WS 2006/07
def getIntensity(p):
sum = getRed(p) + getGreen(p) + getBlue(p)
average = float(sum) / 3
# Bereich 0.0 .. 255.0
return average / 255 # Bereich 0.0 .. 1.0
# pink = (255, 128, 128)
# moduliere mit Intensität des Original-Pixels
def makePinkish(p):
i = getIntensity(p)
setRed(p, int(255 * i * 3) )
setGreen(p, int( getGreen(p) * i * 3) )
setBlue(p, int( getBlue(p) * i * 3) )
… und noch
ein Beispiel
(codiert mit viel
Ausprobieren)
def isGreenish(p):
r = getRed(p)
g = getGreen(p)
b = getBlue(p)
if g > r + 15 and g + 11 > b: return 1
return 0
def replaceGreenishInRange(picture, xmin, xmax, ymin, ymax):
for x in range(xmin,xmax):
for y in range(ymin,ymax):
pix = getPixel(picture,x,y)
if isGreenish(pix):
makePinkish(pix)
return picture
14
Herunterladen