2012-03-27 6 views
0

Ich habe eine Reihe von Daten mit "#" und "." es so etwas wie dieses zeigen zum Beispiel:wählen Sie den größeren Ball

...........#############.............................. 
.........################..................#######.... 
........##################................#########... 
.......####################..............###########.. 
........##################................#########... 
.........################..................#######.... 
...........#############.............................. 

ich einen Algorithmus erstellen möchten, die die größere Kugel finden und löschen Sie den kleineren. Ich dachte daran, die längste Sequenz von "#" zu verwenden, um zu wissen, was der Durchmesser ist.

Also habe ich habe so etwas wie dies:

x = 0 
longest_line = 0 
for i in range(0, nbLine) : 
    for j in range(0, nbRaw) : 
     if data[i, j] = red : 
      x = x+1 
      if data[i, j+1] != red: 

Und ich weiß nicht, was als nächstes zu tun ..

+0

Könntest du mehr darüber erklären, wie du solche Bälle hast? (keine sexuellen Witze, die ich verspreche) –

+0

Welche Annahmen können Sie treffen? Werden die Bälle immer zentriert sein? Werden sie immer Bälle sein, oder könnten sie manchmal unregelmäßige Formen haben? Wie willst du 2 Bälle gleicher Größe handhaben? Haben die Kugeln immer mindestens einen Abstand zueinander oder könnten sie direkt aneinander stoßen? –

+0

Es ist durch Bildverarbeitung, mit PIL, jedes Mal, wenn ich etwas rot habe, drucke ich '#', und alles andere ist '.' – Tsunaze

Antwort

3

Ich würde so etwas wie ein segmentation algorithm verwenden, und dann einfach die zählt Anzahl der Pixel in jedem Objekt. Dann lösche einfach den kleineren, was einfach sein sollte, da du eine Markierung des Objekts hast.

Die Segmentierungsalgorithmen funktionieren normalerweise so.

  1. Führen Sie einen Raster-Scan durch, indem Sie oben links beginnen und nach unten rechts arbeiten.
  2. Wie Sie ein # sehen, wissen Sie, dass Sie ein Objekt haben. Überprüfen Sie die Nachbarn.
  3. Wenn die Nachbarn einen zuvor zugewiesenen Wert haben, weisen Sie diesen Wert zu
  4. Wenn es mehrere Werte gibt, legen Sie das in eine Art von Tabelle, die Sie nach der Verarbeitung vereinfachen werden.

Also, für ein sehr einfaches Beispiel:

...##... 
.######. 
...##... 

Ihre Verarbeitung wird wie folgt aussehen:

00011000 
02111110 
00011000 

Bei einem Umsatz, so dass: 2 => 1

Bewerben die Nachschlagetabelle, und alle Objekte werden mit einem 1-Wert markiert. Dann zählen Sie einfach die Anzahl der Pixel und Sie sind fertig.

Ich werde die Umsetzung Ihnen überlassen ;-)

+0

Wie wird dies den Fall behandeln, wenn Kreise nebeneinander stehen (dh ohne "." Dazwischen)? –

+0

@ TejasP: Es würde nicht funktionieren, es sei denn, Sie können eine Art Filterung durchführen, die nicht von der Position abhängt. – PearsonArtPhoto

2
  1. Erhalten Sie Ihre Daten in ein schöneres Arraystruktur
  2. Perform connected component labelling
  3. Zählen Sie die Anzahl der Elemente mit jedem Etikett (das Hintergrund Etikett ignoriert)
  4. das Etikett mit der größten Anzahl von Elementen wählen
2

haben Sie olways haben nur 2 Formen wie das? Denn in diesem Fall könnten Sie auch die Python-Bibliothek für reguläre Ausdrücke verwenden. Dieser Code scheint den Trick für Ihr Beispiel zu tun (Ich habe Ihre kleine Zeichnung in eine Datei kopiert und sie "Bälle" genannt.txt "):

import re 

f = open("balls.txt", "r") 

for line in f : 

    balls = re.search("(\.+)(#+)(\.+)(#*)(\.+)", line) 

    dots1 = balls.groups()[0] 
    ball1 = balls.groups()[1] 
    dots2 = balls.groups()[2] 
    ball2 = balls.groups()[3] 
    dots3 = balls.groups()[4] 

    if len(ball1) < len(ball2): 
     ball1 = ball1.replace('#', '.') 
    else: 
     ball2 = ball2.replace('#', '.') 

    print "%s%s%s%s%s" % (dots1, ball1, dots2, ball2, dots3) 

Und das ist, was ich bekommen:

...........#############.............................. 
.........################............................. 
........##################............................ 
.......####################........................... 
........##################............................ 
.........################............................. 
...........#############.............................. 

Ich hoffe, das Ihnen einige Ideen für die Lösung des Problems berühren

+0

Woah, hacktastisch! – YXD

+0

Ow ... Das scheint gut, aber was importieren Sie? – Tsunaze

+0

@Mr E Hehe danke :) – nay

0

die Kugeln Unter der Annahme, nicht geben kann, :

Unter der Annahme, genau zwei Kugeln

zwei Kugeln Objekte erstellen, (genannt Kugeln 0 und 1) Jeder besitzt eine Reihe von Punkten. Punkte sind x, y Paare.

Scannen Sie jede Reihe von oben nach unten, von links nach rechts innerhalb jeder Zeile.

Wenn Sie das erste # sehen, weisen Sie es Kugel 0 zu (fügen Sie seine x, y-Schnüre zu dem Satz hinzu, der dem Objekt ball 0 gehört).

Wenn Sie eine nachfolgende # sehen, fügen Sie sie zu Ball 0 hinzu, wenn sie an einen Punkt in Ball 0 angrenzt; andernfalls füge es zu Ball 1 hinzu. (Wenn das neue # bei x ist, y wir gerade testen (x + 1, y) ist gesetzt, (x-1, y) ist gesetzt, (x, y + 1) ist im Satz ist (x, y-1) gesetzt, und die diagonalen Nachbarn)

Wenn der Scan abgeschlossen ist, decken die Listengrößen den größeren Ball auf. Sie haben dann eine Liste der zu löschenden Punkte in den Punkten des anderen Balls.