====== Das Modul kontouren.py ======
Der Code (mit noch zu implementierender Funktion finde_kanten) kurz
aufgeschlüsselt.
Zunächst Importe und eine nützliche Definition:
import cv2
import numpy as np
import scipy.signal as sig
import scipy
from scipy import misc
from bildoperationen import *
## Liste der Richtungen um einen Pixel im Uhrzeigersinn "Moore-neighbourhood"
## Die wird man bei der Implementierung der Funktion finde_kontour() gebrauchen
## können
nachbarn=[ np.array([-1,-1]) ,\
np.array([-1,0]),\
np.array([-1,1]),\
np.array([0,1]),\
np.array([1,1]),\
np.array([1,0]),\
np.array([1,-1]),\
np.array([0,-1])]
Die Funktion **parametrisiere_kanten(...)** ist bereits implementiert:
def parametrisiere_kanten(bild,schwelle,mindestlaenge=100,anzahl_versuche=10,max_kontouren=100):
'''Funktion sucht Kontouren/Kanten. Sie liefert zurück
eine Liste von Kontouren der Laenge zahl_kontouren.
Eine Kontour wiederum ist eine Liste von Punkten, als
Kantenzug zu interpretieren.
Erst wird über den Schwellenwert ein Schwarzweissbild
berechnet, dann werden daraus Kontouren bestimmt.
'''
bildsw=schwarzweiss(bild, schwelle)
cv2.imshow("sw",bildsw)
cv2.waitKey(0)
zeilen,spalten=bildsw.shape
kontouren=[]
liste_der_weissen_punkte=[ [i,j] for i in range(zeilen//8,7*zeilen//8)\
for j in range(spalten//8, 7*spalten//8) if bildsw[i,j]>0.5]
#menge_der_weissen_punkte=set(liste_der_weissen_punkte)
for k in range(anzahl_versuche):
### Es werden solange Anfangspunkte gesucht, bis zu diesen auch
### eine moegliche Kantenrichtung gehoert. Isolierte Punkte haben
### diese Eigenschaft nicht.
print "Kontour Nr. ", k
richtung=None
while richtung==None:
### Waehlt zufaellig einen weißen Punkt aus dieser Liste:
anf=np.array(liste_der_weissen_punkte[np.random.randint(len(liste_der_weissen_punkte))])
### Anfangsrichtung bestimmen
## Bestimme die Richtung mit dem hellsten Grauwert
wertmax=0.
for i in range(len(nachbarn)):
if bild[tuple(nachbarn[i]+anf)]>wertmax:
richtung=i
wertmax= bild[tuple(nachbarn[i]+anf)]
##################################################
# Achtung: Ein Bildpunkt bild[i,j] liegt in der i. Zeile und der j. Spalte.
# Die Zeichenbefehle von opencv benennen denselben Punkt (x,y), wobei
# x=j und y=i
#cv2.circle(bild,(anf[1],anf[0]),4,(200,200,0))
#cv2.imshow("Weißer Punkt", bild)
#ch=cv2.waitKey(0)
kont=finde_kontour(bildsw,anf, richtung)
if len(kont)>=mindestlaenge:
kontouren.append(kont)
kontouren=sorted(kontouren,key=lambda x:-len(x))
if len(kontouren)>100:
kontouren=kontouren[:100]
return kontouren
Die noch zu implementierende Funktion, die bisher (fast) nichts tut.
def finde_kontour(bildsw,anf,richtung):
'''Findet eine einzelne Kontour zum Anfangspunkt anf und zur Anfangsrichtung
richtung. Löscht die weißen Punkte, die zu der gefundenen Kontour gehören aus bildsw.'''
## Diese Funktion ist noch nicht implementiert
kontour=[anf,anf+nachbarn[richtung]]
#print "Gefunden: Kontour der Laenge: ",len(kontour)
return kontour
Und die Testsektion:
def main():
'''Testunit: testet Algorithmus am Testbild 'Lena' '''
global l, kontouren
l=misc.lena()
bild_kanten=gradient(glaetten(l/255.,5))
kontouren=parametrisiere_kanten(bild_kanten, 60./255., mindestlaenge=50,anzahl_versuche=3000)
bild_farbbild=cv2.cvtColor(np.uint8(l),cv2.cv.CV_GRAY2BGR)
if len(kontouren)>0:
for kontour in kontouren:
cv2.polylines(bild_farbbild,[np.array(kontour)[:,::-1]],False,(0,0,255))
cv2.imshow("Beispiel: ",bild_farbbild)
cv2.waitKey(0)
return 0
if __name__ == '__main__':
main()