PolygonKlasse zur Erstellung von geschlossenen Polygonen

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Hallo

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)")
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
Antworten