Termin 6: Medienprogrammierung in Python – Bildverarbeitung (3) Grundlagen der Informatik Wintersemester 2006/07 Prof. Bernhard Jung Übersicht Definition von Funktionen in Python Globale und lokale Namensräume von Variablen Parameterübergabe Rekursive Funktionen Medienprogrammierung mit Python / JES Prof. B. Jung verschiedene einfachere Algorithmen (Rotieren, Spiegeln von Bildern) Kombinieren von Bildern, z.B. Bluescreening Vektorgrafikelemente zu Bitmaps hinzufügen Grundlagen der Informatik, WS 2006/07 1 Beispiel für bildgebende Verfahren im Bereich Geo / Engineering: Georadar Alle Bilder: www.geosphereinc.com Nachweis von Benzintanks im Boden Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Aufruf von Funktionen Format des Ausrufs: funktion(arg1, arg2, …) Funktionen akzeptieren i.d.R. nur eine bestimmte Anzahl von Argumenten Die übergebenen Argumente müssen von einem bestimmten Typ sein Beispiel: Standardfunktion len() – Länge von Strings, Listen, Tupeln, Dictionaries Fehlerhafte Aufrufe Korrekte Aufrufe len(1) – 1 ist eine Zahl und besitzt keine Länge len("eins", "zwei") – Die Funkion len() akzeptiert nur ein Argument len("Wort") Æ 4 len([1,2,3,4]) Æ 4 len("sha" + 4 * "la") Æ 11 (Auswertung des Ausdrucks ergibt String) len( (1, 2, (3,4) ) ) Æ 3 (Tupel mit 3 Elementen) Manche Funktionen akzeptieren eine variable Anzahl von Parametern z.B. min(1,2,3,4,5) Æ 1 Prof. B. Jung Grundlagen der Informatik, WS 2006/07 2 Definition von Funktionen def funktionsname(arg1, arg2, …): anweisungsblock Funktionskopf Schlüsselwort def, Funktionsname, Parameterliste in Klammern, Doppelpunkt Funktionskörper Anweisungsblock, d.h. Folge von Anweisungen mit Schlüsselwert return kann ein Rückgabewert festgelegt werden eingerückt! Rückgabewert kann auch Tupel, Liste oder anderes Objekt sein def summiereBis(n): sum = 0 for i in range(1,n+1): sum = sum + i return sum Prof. B. Jung def sumAndMultiplyTo(n): sum = 0 prod = 1 for i in range(1,n+1): sum = sum + i prod = prod * i return (sum,prod) Grundlagen der Informatik, WS 2006/07 Ausführung von Funktionen Globale und lokale Namensräume Definition einer lokalen Variable x Definition globaler Variablen x, y lokale Variablen sind nur innerhalb der Funktionsdefinition sichtbar, d.h. können außerhalb nicht verwendet werden innerhalb von Funktionen sind lokale und globale Variablen sichtbar bei Namensgleichheit einer lokalen mit einer globalen Variable wird die lokale Variable ausgewertet Prof. B. Jung def f(): x = 2 print "x in Funktion f(): ", x print "y in Funktion f(): ", y # Hauptprogramm x = 1 y = 1 f() print "x in Hauptprogramm: ", x print "y in Hauptprogramm: ", y >>> x in y in x in y in >>> Funktion f(): 2 Funktion f(): 1 Hauptprogramm: 1 Hauptprogramm: 1 Grundlagen der Informatik, WS 2006/07 3 Ausführung von Funktionen Globale und lokale Namensräume def f(): x = 2 print "Globaler Namensraum von f(): ", globals() print "Lokaler Namensraum von f(): ", locals() Standardfunktionen # Hauptprogramm x = y = 1 f() >>> Globaler Namensraum von f(): {'f': <function f at 0x00B45830>, '__builtins__': <module '__builtin__' (built-in)>, 'x': 1, 'y': 1, '__name__': '__main__', '__doc__': None} Lokaler Namensraum von f(): {'x': 2} Prof. B. Jung In JES enthält globaler Namensraum eine Vielzahl weiterer Funktionen! Grundlagen der Informatik, WS 2006/07 Ausführung von Funktionen Globale und lokale Namensräume Innerhalb von Funktionen können globale Variablen gelesen, aber nicht ohne Weiteres verändert werden Zur Veränderung einer globalen Variable innerhalb einer Funktion dient die global-Anweisung (teilt Python mit, dass Zuweisung an eine globale Variable erfolgen soll) Prof. B. Jung def verdopple(): global x x = x * 2 # Hauptprogramm x = 10 verdopple() print x >>> 20 >>> Grundlagen der Informatik, WS 2006/07 4 Ausführung von Funktionen Parameterübergabe (1) Auf formale Parameter, d.h. Namen der Parameter im Funktionskopf, kann im Funktionskörper wie auf lokale Variablen zugegriffen werden Bei Aufruf der Funktion halbiere() wird der Parameter innerhalb der Funktion an eine andere Variable gebunden Sind die als Parameter übergebene Objekte unveränderbar – z.B. Zahlen, Strings, Tupel – dann haben Veränderungen innerhalb der Funktion keine Auswirkungen auf Objekte außerhalb Prof. B. Jung def halbiere(zahl): zahl = float(zahl) zahl = zahl / 2 return zahl >>> >>> 2.5 >>> 5 >>> >>> >>> >>> 2.5 >>> n = 5 halbiere(n) n # n bleibt unverändert n = halbiere(n) print n Grundlagen der Informatik, WS 2006/07 Ausführung von Funktionen Parameterübergabe (2) Veränderbare Objekte, z.B. Listen, können, wenn sie als Argumente einer Funktion übergeben werden, in dieser Funktion modifiziert werden (die Veränderungen sind auch außerhalb der Funktion wirksam)! z.B. auch Bilder in JES! def quadriere(l): for i in range( len(l) ): l[i] = l[i] * l[i] # Hauptprogramm liste = [1,2,3,4,5] print liste quadriere( liste ) print liste Programmlauf: >>> [1, 2, 3, 4, 5] [1, 4, 9, 16, 25] >>> Prof. B. Jung Grundlagen der Informatik, WS 2006/07 5 (Wiederholung): Die wichtigsten Datentypen in Python Datentypen Kollektionen Zahlen Ganze Zahlen float complex 12.852 1+2j Unveränderbar int 123 long 123456789L Sequenzen NoneType None Abbildungen Mengen Veränderbar str unicode tuple ‘Wort‘ u‘Wort‘ (1, ‘a‘, [2]) Prof. B. Jung bool True, False set dict set( [1,2]) (‘A‘:65, ‘B‘:66) list [1, ‘a‘, [2]] frozenset frozenset( [1,2]) Grundlagen der Informatik, WS 2006/07 Voreingestellte Parameter Manche Funktionen haben optionale Parameter, die bei Funktionsaufruf weggelassen werden können In der Funktionsdefinition werden für diese Default-Werte angegeben: def funktionsname(arg1=wert1, arg2=wert2, …): def wertetabelle(anzahl=3, schritt=0.5): x = 0.0 for i in range(anzahl): print x, ' ', x*x x = x + schritt >>> wertetabelle() 0.0 0.0 0.5 0.25 1.0 1.0 >>> Prof. B. Jung >>> wertetabelle(3,1) 0.0 0.0 1.0 1.0 2.0 4.0 >>> >>> wertetabelle(5) 0.0 0.0 0.5 0.25 1.0 1.0 1.5 2.25 2.0 4.0 >>> Grundlagen der Informatik, WS 2006/07 6 Schlüsselwort-Argumente Bisher: Aufruf von Funktionen mit Positionsargumenten In Python auch möglich: Aufruf mittels Schlüsselwort-Argumente der Form Reihenfolge der Argumente bei Aufruf entsprechend Funktionsdefinition funktionsname(arg1=wert1, arg2=wert2, …) def wertetabelle(anzahl=3, schritt=0.5): x = 0.0 for i in range(anzahl): print x, ' ', x*x x = x + schritt >>> wertetabelle(schritt=0.1) 0.0 0.0 0.1 0.01 0.2 0.04 >>> Prof. B. Jung >>> wertetabelle(schritt=0.1, anzahl=5) 0.0 0.0 0.1 0.01 0.2 0.04 0.3 0.09 0.4 0.16 Grundlagen der Informatik, WS 2006/07 Rekursive Funktionen Rekursive Funktion: Funktion, die sich selbst aufruft z.B. Fakultät: n! = 1 * 2 * … * n rekursive Formulierung der Fakultätsfunktion: 1! = 1 n! = n * (n-1)!, n > 1 >>> 120 3628800 2432902008176640000 >>> Prof. B. Jung def fak(n): if n == 1: return 1 else: return n * fak(n-1) # Hauptprogramm print fak(5) print fak(10) print fak(20) Grundlagen der Informatik, WS 2006/07 7 Rekursive Funktionen Fibonacci-Folge: 1, 1, 2, 3, 5, 8, 13, … def fib(n): if n == 1 or n==2: return 1 else: return fib(n-1) + fib(n-2) Rekursive Formulierung Basisfall: fib(1) = 1 Basisfall: fib(2) = 1 Rekursionsfall (n>2): fib(n) = fib(n-1) + fib(n-2) Prof. B. Jung mit Rückgabe als Liste: def fib1(n): if n == 1: return [1] elif n== 2: return [1,1] else: bisher = fib1(n-1) i = bisher[n-2] + bisher[n-3] return bisher + [i] Grundlagen der Informatik, WS 2006/07 Dokumentation von Funktionen Docstrings Unterhalb des Funktionskopfes sollte ein Kommentar in dreifachen Anführungszeichen angebracht werden Dieser Docstring der Funktion kann im interaktiven Modus mit der help()-Funktion zum Vorschein gebracht werden def fak(n): """Berechnung der Fakultaet einer Zahl. Eingabe: eine Zahl n Ausgabe: Fakultaet n! der Zahl Autor: Bernhard Jung, 15.11.2005 """ if n == 1: return 1 else: return n * fak(n-1) Prof. B. Jung >>> help(fak) Help on function fak in module __main__: fak(n) Berechnung der Fakultaet einer Zahl. Eingabe: eine Zahl n Ausgabe: Fakultaet n! der Zahl Autor: Bernhard Jung, 15.11.2005 Grundlagen der Informatik, WS 2006/07 8 Bildverarbeitung mit JES – Einige Funktionen getWidth(pic), getHeight(pic) – liefern Breite, Höhe eines Bilds makePicture(filename) – erzeugt Bild aus Dateinamen (.jpg) makeEmptyPicture(width, heigth) – erzeugt leeres (schwarzes) Bild getPixel(pix,x,y) – liefert Pixel an Position (x,y) getColor(pixel) – liefert Farbe des Pixels setColor(pixel, color) – setzt Farbe eines Pixels Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Transponieren von Bildern Idee: Pixel (x,y) wird an Position (y,x) im neuen Bild kopiert Æ Rotation + Spiegelung def transposePicture(origPic): w = getWidth(origPic) h = getHeight(origPic) newPic = makeEmptyPicture(h,w) for x in range(1, w+1): for y in range(1, h+1): pixel1 = getPixel(origPic, x, y) color = getColor(pixel1) pixel2 = getPixel(newPic, y, x) setColor(pixel2, color) return newPic Prof. B. Jung Grundlagen der Informatik, WS 2006/07 9 Vertikales "Spiegeln" Berechne Mitte des Bildes in x-Richtung (mirrorpoint) Für jede Bildzeile: kopiere Pixel an (mirrorpoint + offset, y) nach (mirrorpoint – offset, y) Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Vertikales "Spiegeln" def mirrorVertical(source): mirrorpoint = int(getWidth(source) / 2) for y in range(1, getHeight(source)): for xOffset in range(1, mirrorpoint): pright = getPixel(source, xOffset + mirrorpoint, y) pleft = getPixel(source, mirrorpoint - xOffset, y) c = getColor(pright) setColor(pleft, c) return source Prof. B. Jung Grundlagen der Informatik, WS 2006/07 10 Horizontales "Spiegeln" def mirrorHorizontal(source): mirrorpoint = int(getHeight(source) / 2) for yOffset in range(1, mirrorpoint): for x in range(1, getWidth(source)): pbottom = getPixel(source, x, yOffset + mirrorpoint) ptop = getPixel(source, x , mirrorpoint - yOffset) setColor(pbottom, getColor(ptop)) return source Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Kombinieren von Bildern z.B. alle bläulichen Pixel eines Bildes durch Hintergrund ersetzen def bluescreen(source,bg): for p in getPixels(source): if (getRed(p)+getGreen(p) < getBlue(p)): x = getX(p) y = getY(p) pixel = getPixel(bg,x,y) col = getColor(pixel) setColor(p,col) return source Prof. B. Jung Grundlagen der Informatik, WS 2006/07 11 Bitmaps und Vektorgrafik Bisher: Bitmap-Bilder (Rastergrafik) Bild ist Matrix von Pixeln .jpg, .bmp, .png, .gif, … Digitalkamera, Scanner Vektorgrafik Anweisungen zum Zeichnen verschiedener einfacher Formen Linien, Rechtecke, Text, … z.B. Freehand, Ilustrator, CorelDraw, …Postscript, TrueType Fonts, … Vorteil z.B. stufenlose Skalierung möglich Bitmaps können um Vektorgrafik-Elemente angereichert werden JES: Grafikbibliotheken wandeln Vektorgrafik in Pixeldarstellung um addText(pic,x,y,string) addLine(x1,y1,x2,y2) addRect(x,y,w,h) addRectFilled(x,y,w,h,color) Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Vektorgrafikelemente Pixel einzeln setzen: def verticalLines(pic): for x in range(1,getWidth(pic),5): for y in range(1,getHeight(pic)+1): setColor(getPixel(pic,x,y),black) oder Linien (Vektorgrafik) zeichnen def verticalLines(pic): for x in range(1,getWidth(pic),5): addLine(pic, x, 1, x, getHeight(pic)) def horizontalLines(pic): for y in range(1,getHeight(pic),5): addLine(pic, 1, y , getWidth(pic), y) Prof. B. Jung Grundlagen der Informatik, WS 2006/07 12 Vektorgrafikelemente def title(pic,string): addText(pic,40,15,string) >>> pic = makePicture(file) >>> title(pic, "Willkommen in Freiberg") >>> show(pic) >>> Prof. B. Jung Grundlagen der Informatik, WS 2006/07 Vektorgrafikelemente def coolpic(): pic = makeEmptyPicture(250,250) for i in range(25,1,-1): color = makeColor(i*10,i*5,i) addRectFilled(pic,0,0,i*10,i*10,color) return pic Prof. B. Jung Grundlagen der Informatik, WS 2006/07 13 Vektorgrafikelemente def makeWhitePicture(width=640, height=480): pic = makeEmptyPicture(width,height) for p in getPixels(pic): setColor(p,white) return pic def coolpic2(): pic = makeWhitePicture(640,480) for i in range(25,1,-1): addRect(pic, i, i, i*3, i*4) addRect(pic, 100+i*4, 100+i*3, i*8, i*10) return pic Prof. B. Jung Grundlagen der Informatik, WS 2006/07 14