Dies ist eine alte Version des Dokuments!
Abschließend zum Mathesis-Modul hatten wir in den letzten zwei Blockterminen die Möglichkeit, unsere Projekte zu beenden, zu verbessern und/oder den nötigen Feinschliff hinzuzufügen und das Ergebnis unseren Kommilitonen vorzustellen.
Unser Ziel für diese Tage waren zum einen, eine reibungslos funktionierenden Code präsentieren zu können, sowie eine kreative Ausgabe unseres „Bildbearbeitungsprogramms“ zu generieren.
Kreative Ausgabe:
Unsere Ursprüngliche Idee war es, nicht nur turtle das aufgenommene und bearbeitete Bild nachzeichnen zu lassen, sondern während dieser Nachzeichnung einen Code zu übergeben, der aus der einfachen Linie ein Muster/Mäander machen sollte. Dabei haben sich die folgenden Probleme ergeben:
Bei welchen Punkt startet die Turtle?
Was passiert bei einer Kurve oder dem Abbrechen einer Kontour?
Wie wird der nächste Punkt nach einer Unterbrechung gewählt?
Wie schaffen wir es aus einer Geraden eine Kurve zu machen?
Wie verhindern wir es, dass, trotz Ausfilterung, nicht aussagekräftige Punkte ausgelassen werden, ohne dass die aussagekräftigen Punkte ebenfalls ignoriert werden?
An welche Stelle/in welche Klasse gehört der Code, der die kreative Ausgabe generiert?
Wir haben letztendlich angefangen, einen simplen Versuchscode zu schreiben und diesen in unseren Hauptcode einzubauen, damit das erst ein mal funktioniert. Das haben wir auch hinbekommen (siehe turtleworld im code).
Finale Version mit kreativer Ausgabe:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt from scipy import misc, ndimage, signal import cv2 import skimage.color as color import turtle import pickle from skimage.measure import find_contours minimum=int(raw_input("Minimum: ")) percentile=int(raw_input("Staerke der Kanten (max bis 100): ")) cap = cv2.VideoCapture(0) res, bild = cap.read() imgray = color.rgb2gray(bild) res = [] for value in np.linspace(np.min(imgray), np.max(imgray),30): res.extend(find_contours(imgray,value)) cap.release() def Isolux(): res2 = [] for cont in res: if cont.shape[0]>minimum: res2.append(cont) return res2 res2 = Isolux() #unsere Liste der gewünschten Contours res2 (zu Kurze ausgefiltert) bild=ndimage.filters.gaussian_filter(bild,1.5) b=ndimage.filters.sobel(imgray, axis=-1) #Verschiebungsbild x b2=ndimage.filters.sobel(imgray, axis=0) #Verschiebungsbild y a=np.sqrt(b[1:,:]**2+b2[:-1,:]**2) #b und b2 werden zum Kantenbild a verrechnet median2 = np.percentile(a,percentile) z = a.shape[0] #y z2 = range(0,z) s = a.shape[1] #x s2 = range(0,s) alle_koordinaten = [] for i in z2: for j in s2: alle_koordinaten.append((i,j)) kandidaten = [ p for p in alle_koordinaten if a[p[0],p[1]]>median2 ] contouren = res2 #Liste in Listen kant = kandidaten Schwellw = np.median(a) beste_Werte = [] def check(cont, Kant): hell = 0. for pkt in cont: try: #try, da es hier oft zu Rundungsfehlern kommt hell += a[int(round(pkt[0])),int(round(pkt[1]))] except: pass if hell > Schwellw*len(cont): return True else: return False for cont in contouren: if check(cont, a): beste_Werte.append(cont) else: pass def smooth(kont): for i in range(1,len(kont)-1): kont[i]=1/3.*(kont[i-1]+kont[i]+kont[i+1]) class MyTurtle(turtle.Turtle): def turn_and_move(self,p): self.setheading(self.towards(p)) self.goto(p) class turtle_world(object): def __init__(self,bild): #pencv speichert die Bilder als BGR! self.screen=turtle.Screen() self.xsize=bild.shape[1] self.ysize=bild.shape[0] turtle.screensize(self.xsize,self.ysize) self.t=MyTurtle() self.t.pensize(1) self.t.pencolor("black") self.t.shape("turtle") self.t.speed(0) self.t.tracer(0,delay=0) def image_to_turtle(self,point): '''Rechnet die Koordinaten des Bild-Arrays auf die Turtle-Koordinaten um. Returns: Koordinatentupel.''' return (point[1]-(self.xsize//2),(self.ysize//2)-point[0]) def turtle_to_image(self,point): '''Rechnet die Turtle-Koordinaten auf Bild-Array-Koordinaten um. Returns: numpy-Vektor mit Bildkoordinaten''' return np.array([self.ysize//2-point[1], point[0]+self.xsize//2]) def bewege_turtle_auf_bild(bild,kontouren): '''Lässt Turtle auf Hintergrundbild laufen. Dabei ist bild ein BGR-Bild (opencv-Farbbild) und kontouren eine Liste von Listen von Punkten.''' tw=turtle_world(bild) for kontour in kontouren: tw.t.penup() for p in kontour: tw.t.turn_and_move(tw.image_to_turtle(p)) tw.t.pendown() turtle.update() no = int(raw_input("Geben Sie eine natuerliche Zahl ein: ")) m = np.array([[0,-1],[1,0]]) l = [] l2 = [] if no > 0: for i in range(no): tw.t.pendown() pos = turtle.position() gradient = np.array((b[int(pos[0]),int(pos[1])],b2[int(pos[0]),int(pos[1])])) #b 0 1 b2 0 1 winkel = np.arctan2(gradient[0],[1])*180/np.pi tw.t.setheading(winkel+90) tw.t.pencolor("red") tw.t.pensize(2) tw.t.fd(50) tw.t.lt(45) tw.t.fd(50) l.append(pos) else: print "Das ist keine natuerliche Zahl!" turtle.update() def main(): bild_farbbild=cv2.cvtColor(np.uint8(imgray),cv2.cv.CV_GRAY2BGR) kontouren=beste_Werte bewege_turtle_auf_bild(bild_farbbild,kontouren) return 0 main()
—- (Beschreibung, turtle world)
Eine ausgeklügelten, kreativeren Code haben wir nicht mehr schreiben können. Hier der Hinweis an eventuelle Nachfolger: Tobt euch aus!