Für mein OCR-Projekt (siehe Ideen) brauche ich eine Klasse, die erkennt, ob ein Polygon ein Strich, ein Kreis, oder ein Rechteck ist.
Für die Unterscheidung ob Kreis oder Rechteck, will ich die Fourieranalyse einsetzen, für die ich aber eine geschlossene Kontur brauche.
Wenn die Eingabe aber nur eine Spirale ist, muss ich die irgendwie schließen und wenn sich die Kontur überschneidet, muss ich die überhängenden Ränder abschneiden.
Als nächstes kommt dann die Analyse. Wer Lust hat, an so einem Projekt mitzuarbeiten, könnte sich mal den Thread bei den Projektideen anschauen.
Nikolas
Zum anschauen gibts noch kleines Tkinter
(Habe ich was übersehen, oder gibts hier wirklich keine Anhänge?)
Code: Alles auswählen
from Tkinter import *
from createTestData import *
from polygonFunctions import Polygon
root = Tk()
canvas = Canvas(root,height=500,width=500,bg="white")
canvas.pack()
L = brachisto(100,20,100,300,300)
p=Polygon(L)
L=tuppel2List(L)
a=canvas.create_line(L)
p.processPolygon()
b=canvas.create_line(p.polygon,fill="red")
L = spirale(60,50,100,100,100)
p=Polygon(L)
L=tuppel2List(L)
a=canvas.create_line(L)
p.processPolygon()
b=canvas.create_line(p.polygon,fill="red")
root.mainloop()
Code: Alles auswählen
from math import sqrt
class Polygon():
def __init__(self,polygon):
self.polygon=polygon
self.functions = self.makeFunctions(polygon)
self.intersections = []
self.bestStartNeighbour = None
self.bestLastNeightbour = None
self.bestIntersection = None
self.ListOfIntersections = []
def processPolygon(self):
self.findIntersections()
if self.ListOfIntersections!=[]:
self.findBestIntersection()
self.closePolygonAtIntersection()
else:
self.findNeighbours()
self.closePolygonAtNeighbour()
def closePolygonAtNeighbour(self):
liste = self.polygon
length = len(liste)
start = self.bestStartNeighbour
last = self.bestLastNeighbour
if start[0]<last[0]: # wo ist der Nachbar näher?
#Ende wird abgeschnitten
L=liste[:start[1]]
L.append(liste[0])
else:
L=liste[last[1]:]
L.append(Liste[-1])
self.polygon = L
''' Knoten ausserhalb der Intersection werden entfernt und ein
zusätzlicher Knoten am Schnittpunkt hinzugefügt'''
def closePolygonAtIntersection(self):
inter = self.bestIntersection[0]
i=inter[0]
j=inter[1]
coordinate=inter[2]
# print i,j
newPolygon = self.polygon[i+1:j+1]
newPolygon.append(coordinate)
newPolygon.append(newPolygon[0]) # wird geschlossen
self.polygon = newPolygon
def findNeighbours(self):
# der nächster Nachbar für den Anfang muss in der anderen Hälfte
# des Polygons liegen
start = self.polygon[0]
liste = self.polygon
length = len(liste)
minimum = self.dist(start,liste[length / 2])
pos = length / 2
for i in range((length/2 +1),length):
d = self.dist(start,liste[i])
if d<minimum:
minimum=d
pos=i
# print "besser"
self.bestStartNeighbour = (minimum,pos)
print pos
# und nochmal fürs Ende:
last = liste[-1]
minimum = self.dist(last,liste[length / 2])
pos = length /2
for i in range(1,length / 2):
d=self.dist(last,liste[i])
if d<minimum:
# print "besser"
minimum=d
pos=i
self.bestLastNeighbour = (minimum,pos)
print pos
def findIntersections(self):
polygon = self.polygon
functions = self.functions
PointBetween = self.isPointBetween
length = len(polygon)
for i in range(length-2):
for j in range(i+1,length-1):
# print (i,j)
p1=polygon[i]
p2=polygon[i+1]
p3=polygon[j]
p4=polygon[j+1]
intersect = self.whereDoFunctionsIntersect(functions[i],functions[j])
if (PointBetween(intersect,p1,p2) and
PointBetween(intersect,p3,p4) ):
self.ListOfIntersections.append( (i,j,intersect) )
def whereDoFunctionsIntersect(self,f1,f2):
m1=f1[0]
m2=f2[0]
c1=f1[1]
c2=f2[1]
if (m2-m1)==0:
dm = 10**(-6)
else:
dm = (m2-m1)
x = (c1-c2)*1.0/dm
y = m1*x + c1
return (x,y)
# vorraussetzung: p liegt auf der Geraden durch
# a und b
def isPointBetween(self,p,a,b):
# Problem bei senkrechten Geraden! (ungenaue Berechnung!
# z.b. x_1=x_2=2 -> p nur grob 2-> False
xmin = min(a[0],b[0])
xmax = max(a[0],b[0])
ymin = min(a[1],b[1])
ymax = max(a[1],b[1])
x = (xmin<p[0]<xmax)
y = (ymin<p[1]<ymax)
return (x and y)
# finde die Intersection, die am wenigsten vom Polygon
# wegschneiden wird.
def findBestIntersection(self):
self.bestIntersection=None
liste = self.ListOfIntersections
if len(liste)==0: return None
s1 = liste[0]
maximum = s1[1]-s1[0]
pos = 0
for i in range(1,len(liste)):
dist = s[1]-s[0]
if dist>maximum:
maximum=dist
pos = i
self.bestIntersection = (self.ListOfIntersections[pos],maximum)
# Alle Kanten werden als y=mx+c dargestellt.
def makeFunctions(self,polygon):
assert len(polygon)>1
L=[]
length = len(polygon)
for i in range(length-1):
a=polygon[i]
b=polygon[i+1]
# Steigung:
dx = b[0]-a[0]
if dx == 0:
m=10**6
else:
m= ((b[1]-a[1])*1.0)/dx
c = b[1]-m*b[0]
L.append( (m,c) )
return L
def dist(self,a,b):
dx = a[0]-b[0]
dy = a[1]-b[1]
return sqrt(dx**2 + dy**2)
Code: Alles auswählen
from math import sin, cos, pi
import profile
# Punkt auf rollender Scheibe (closeAtIntersection)
def brachisto(r,vx,N,xoff,yoff):
L=[None]*N
phi = 2.0*pi/N
for i in range(N):
x = xoff+r*sin(i*phi)+vx*i*phi
y = yoff+r*cos(i*phi)
L[i]=(x,y)
return L
# Spirale: (closeAtNeighbour):
def spirale(rmax,rmin,N,xoff,yoff):
L=[None]*N
phi = 2.0*pi/N*1.2 #*x für Überhang
dr = (rmax-rmin)*1.0/N
for i in range(N):
r = rmin+i*dr
x = xoff + r*sin(i*phi)
y = yoff + r*cos(i*phi)
L[i]=(x,y)
return L
# radius, Punktanzahl, Mittelpunkt
def perfectCircle(r,N,x,y):
L=[None]*N
for i in range(N):
a = r*cos(i*2.0*pi/N)+x
b = r*sin(i*2.0*pi/N)+y
L[i] = (a,b)
return L
def perfectEllipse(rx,ry,N,x,y):
L=[None]*N
for i in range(N):
a = rx*cos(i*2.0*pi/N)+x
b = ry*sin(i*2.0*pi/N)+y
L[i]= (a,b)
return L
def tuppel2List(L):
res = []
for p in L:
res.append(p[0])
res.append(p[1])
return res
# profile.run("perfectCircle(50,500,100,100)")
# profile.run("perfectEllipse(50,50,500,100,100)")