Problem mit Konturpunktverfolgung
-
Hallo zusammen,
ich habe ein Problem und hoffe, dass mir hier jemand helfen kann. Gleich vorweg, ich beschäftige mich noch nicht sehr lange mit der Programmiersprache C.
So nun zu meinem Problem. Ich habe ein Binärbild (ist in einer selbst entwickelten Datenbank gepeichert ist), welches aus Nullen und Einsen besteht. Es spannt ein Feld von 180 x 180 auf. Nun soll ich einen geeigneten Startpunkt in diesem Binärbild finden(habe ich mit xmin und ymin gemacht). Jetzt soll von diesem Startpunkt aus ein geschlossener Polygonzug entstehen. Ich habe den code so gescshrieben, dass er Pixel für Pixel anschaut und dann mit der "Konturpunktverfolgung" beginnt. Ein Feld hat ja 7 Nachbarn. Jetzt "schaut" mein Algorithmus alle Nachbarn an. Befindet sich in der Umgebung eine Eins läuft die "Verfolgung" in diese Richtung weiter. Kommt er an einen "Endpunkt" (sprich sind alle Nachbarn Null, dann läuft er wieder auf dem Weg wie er gekommen ist zurück und setzt die Konturpunktverfolgung fort. Und genau hier liegt mein Problem. Das Programm weiß am Anfang aus wievielen Punkten mein Gebilde besteht. Die Konturpunktverfolgung zählt wieviele Punkte schon "angeschaut" worden sind. Sind die Angeschauten == der Gesamtanzahl, dann bricht die Schleife mit dem Algorithmus ab.
Er soll die Konturpunktverfolgung aber solange fortsetzten, bis wirklich alle Punkte "verbraucht" sind.
Wie kann ich also C beibringen, dass er die Punkte, welche zweimal "abgelaufen" werden nicht aufsummiert?? (Sprich, wenn der Algorithmus in eine Verzweigung läuft, wo er dann feststellt, dass es nicht weitergeht und umdrehen muss).
Ich hoffe die Problematik ist einigermaßen verstanden worden!!!? Und mir kann nun jemand weiterhelfen...
Vielen Dank im Voraus.Viele Grüße,
Tobi
-
Legt dir nochmal ein Feld mit 180x180 Werten drüber in der du speicherst ob du das schon gemacht hast oder nicht.
Oder:
ich nehme jetzt einfach mal an, dass du jedes feld auch wenn es nur binär ist in einer min. 8 bit zahl speicherst. Ausserdem verfolgst du ja nur die 1 Felder. Zaehl überprüfte Felder einfach auf 2 hoch. das kannst du dann beim nächsten feld überprüfen. und ganz zu schluss kannst du nochmal drüber gehen und alle werde groesser 1 wieder auf 1 zurücksetzen.hoffe ich konnte helfen.
-
Die Idee von dir ist echt gut. Aber leider habe ich in C zu wenig anhnung, dass ich weiß, wie ich es am geschicktesten umsetzte
Vielleicht kannst du mir noch ein wenig helfen!?
Würde mich freuen.
Vielen Dank.
Gruß
Tobi
-
Jetzt wird es ein bisschen schwierig, weil ich deinen code nicht kenne. und nicht weisst wie du auf die einzelnen felder zugreifst. die "selberentwickelte Datenbank" verschreckt mich etwas.
-
Sag nichts zu dem Programmierstil. Ich weiss, dass er schrecklich ist.
[cpp]
/* int mode = TREE; */float SKAL_X=2.0/(float)540;
float SKAL_Y=2.0/(float)540;typedef struct
{
int pos_i;
int pos_j;
}
pos_type;int contour_points = 0;
pos_type object_ref[540*540];
while (object_points>15)
{printf("BEGIN: Object Extraction \n");
memset(&object_ref, 0, sizeof(object_ref));
object_extract(&i_start, &j_start);
printf(" object points %d \n",object_points);
printf(" possible start point %d %d\n",i_start, j_start);int dir_i = 0;
int dir_j = 1;int l_dir_i = 1;
int l_dir_j = 1;object_ref[0].pos_i = i_start;
object_ref[0].pos_j = j_start;for(i=0;i<object_points;i++)
{
l_dir_i = dir_i;
l_dir_j = dir_j;find_next(&object_ref[i+1].pos_i, &object_ref[i+1].pos_j, dir_i, dir_j, object_ref[i].pos_i, object_ref[i].pos_j);
dir_i = object_ref[i].pos_i - object_ref[i+1].pos_i;
dir_j = object_ref[i].pos_j - object_ref[i+1].pos_j;if ((object_ref[i+1].pos_i==0) &&(object_ref[i+1].pos_j==0))
{
dir_i = -l_dir_i;
dir_j = -l_dir_j;object_ref[i+1].pos_i = object_ref[i].pos_i;
object_ref[i+1].pos_j = object_ref[i].pos_j;}
//printf("\nN %d %d N+1 %d %d\n",object_ref[i].pos_i, object_ref[i].pos_j, object_ref[i+1].pos_i, object_ref[i+1].pos_j);
if (!((dir_j==0) && (dir_i==0)))
{
contour_points++;
}//printf("Direction i %d Direction j %d\n\n", dir_i, dir_j);
if ((object_ref[i+1].pos_i == i_start) && (object_ref[i+1].pos_j == j_start))
{
break;
}}
Wenn du noch mehr code brauchst, dann sag einfach was dir fehlt.
Was ich alles verlang. Tut mir echt leid.
Mfg,
Tobi
-
Also ich verstehe es nicht ganz, aber gehe ich recht in der Annahme, dass du eine einziges Array von 540*540 felder einfach linear anlegst und fuer jeden punkt die die koordinaten in deinem feld speicherst??? was haelst du davon, das in einem 2 dimensionalen array zu speichern
int feld[540][540];
und so könntest du auch das isDone array anlegen. du sagst wenn du einen punkt überprüft hast.
int isDone[540][540]; \\ ... isDone[object_ref[i].pos_i][object_ref[i].pos_j]++;
und bevor du einen punkt überprüfst prüfst du auf != 0. musst das array natürlich vorher mit 0 initialisieren.
Ich weiss nicht, was du in deiner daten bank noch alles speicherst, aber ich weiss nicht, ob sie fuer diesen code hier förderlich ist. und wenn du darin ablegen kannst was du willst, dann füg doch einfach nochmal eine variable dazu.
hoffe konnte helfen.
-
...du hast mir echt sehr geholfen. Dieses Problem waere somit geloest. Die anderen warten schon
Dir ein schoenes wochenende.
Mfg,
Tobi