Frage

Ich habe meinen Kopf für eine lange Zeit auf diesem worden hämmern

Ich tue Bildgebung. Bisher habe ich meine Bilder binarisiert, was bedeutet, dass aus einem Graustufenbild, jedes Pixel unter einem bestimmten Wert fallen gelassen werden. Das gibt mir nur einige Regionen aus dem Originalbild mit vielen „Null-Pixel“ alle um diese Regionen.

Als nächstes habe ich Lauflänge codiert meine Regionen in „Blobs“. Runs ist ein Verfahren zur Komprimierung von Daten. Angenommen, dass Sie einen Platz binarisiert haben, müssen die Sie nur ein paar läuft das ganze Bild zu beschreiben. Die Durchläufe sind definiert durch x, y-Koordinaten und eine Länge.

Wenn das Bild neu zu erstellen, für jeden Lauf, gehen zu x, y-Koordinate und fügen Pixel auf der x-Achse für die Länge des Laufs.

Jetzt muss ich die Läufe nehmen und eine Kette aus ihm heraus zu erstellen, die die Kontur der Region beschreiben. Ich weiß nicht, wie das zu tun.

Ich habe eine Reihe von x, y, Länge läuft und ich „Navigieren“ um die Kanten ein Kette . Normalerweise sollten Sie diese Verfahren bei der Bildgebung mit dem Originalbild fertig ist, aber ich kann nicht das Originalbild verwenden mehr hier, damit ich es mit den Läufen berechnen müssen.

Ich weiß, das sieht aus wie eine große Wand aus Text, aber ich weiß nicht, wie diese Frage stellen besser.

Für Hinweise oder Hinweise auf identische Implementierung wäre genial.

EDIT

dank Abroller, link Ill ein paar Bilder:


(Quelle: tudelft.nl )

In diesem Beispiel verarbeiten sie das Bild B in die Kontur C (die I-Kette nennen). Aber ich mag die Kontur von D, die Lauflängen

erzeugen,
War es hilfreich?

Lösung 3

verloren Nun, ich diesen Vertrag aber die Antwort war, die Freeman Kettenkodierungstechnik

Die Tatsache, dass es Lauflängen codieren, hat nichts mit dem Algorithmus zu tun, im Gegensatz zu mir bisher angenommen.

Andere Tipps

Auf den ersten Blick sehe ich keinen praktischen Algorithmus dafür. Ein armer Mann-Lösung wäre erweitern das Originalbild aus der Länge codiert ein. Also, wenn Ihre Zeilen wie folgt aussehen:

A 3B 10A C 8D
C 4D 3A 6C 9A

in dem die Zeichen, die den tatsächlichen Pixelwert zurück (z.B. A = 0, B = 127, ...). Sie könnten die Pixelwerte in einer zweidimensionalen Matrix (oder eine andere Datenstruktur Ihrer Wahl) schreiben .Es sieht wie folgt aus:

ABBBAAAAAAAAAACDDDDDDDD
CDDDDAAACCCCCCAAAAAAAAA

Danach Ihre Kette erzeugen, um das Array löschen und die Kette Informationen zu halten. Sicher ist dies teuer, so dass vielleicht Sie können dies tun, bevor Länge kodiert, das Originalbild.

Hier ist eine ganz einfache und praktische Lösung (C ++):

#include <iostream>
#include <vector>

struct Run { int x, w; };
enum { EAST, NORTHEAST, NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST };

int main() {

    const Run data[] = {
        { 7, 2 },
        { 5, 6 },
        { 5, 7 },
        { 5, 7 },
        { 6, 6 },
        { 0, 12 },
        { 0, 12 },
        { 0, 11 },
        { 1, 7 },
        { 3, 4 },
        { 3, 4 },
        { 3, 5 },
        { 3, 7 },
        { 3, 7 },
        { 5, 5 }
    };

    std::vector<Run> runs(data, data + 15);
    std::vector<int> before;
    std::vector<int> after;
    unsigned int i;
    int j;

    for (i = 0; i < runs.size() - 1; ++i) {

        if (runs[i].x < runs[i + 1].x) {

            for (j = 0; j < runs[i + 1].x - runs[i].x - 1; ++j)
                before.push_back(WEST);
            before.push_back(NORTHWEST);

        } else if (runs[i].x > runs[i + 1].x) {

            before.push_back(NORTHEAST);
            for (j = 0; j < runs[i].x - runs[i + 1].x - 1; ++j)
                before.push_back(EAST);

        } else {

            before.push_back(NORTH);

        }

        int first_right(runs[i].x + runs[i].w);
        int second_right(runs[i + 1].x + runs[i + 1].w);

        if (first_right < second_right) {

            after.push_back(SOUTHEAST);
            for (j = 0; j < second_right - first_right - 1; ++j)
                after.push_back(EAST);

        } else if (first_right > second_right) {

            for (j = 0; j < first_right - second_right - 1; ++j)
                after.push_back(WEST);
            after.push_back(SOUTHWEST);

        } else {

            after.push_back(SOUTH);

        }

    }

    for (j = 0; j < runs.back().w - 1; ++j)
        after.push_back(WEST);

    std::reverse(before.begin(), before.end());
    after.insert(after.end(), before.begin(), before.end());

    for (j = 0; j < int(after.size()); ++j) {
        switch (after[j]) {
        case EAST:      std::cout << "EAST\n";      break;
        case NORTHEAST: std::cout << "NORTHEAST\n"; break;
        case NORTH:     std::cout << "NORTH\n";     break;
        case NORTHWEST: std::cout << "NORTHWEST\n"; break;
        case WEST:      std::cout << "WEST\n";      break;
        case SOUTHWEST: std::cout << "SOUTHWEST\n"; break;
        case SOUTH:     std::cout << "SOUTH\n";     break;
        case SOUTHEAST: std::cout << "SOUTHEAST\n"; break;
        }
    }

}

Dies funktioniert, indem über die Läufe laufen, das Testen der linken und rechten Endpunkte für die Richtung, sie sind Springen und um die entsprechende Anzahl von Kettenelementen zu zwei Vektoren: eine in Vorwärtsrichtung, für die rechte Seite, und ein in umgekehrter Reihenfolge, für die linke. Sie verbindet dann die beiden Ketten durch die entsprechende Anzahl von Links zu der letzten Scanlinie hinzufügen, dann kehrt die linke Seitenkette und hängt es an den rechten Seite ein, die letzte Kette zu erzeugen.

Hope das ist, was Sie suchen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top