Question

J'ai frappais ma tête depuis longtemps sur celui-ci

Je suis en train de faire l'imagerie. Jusqu'à présent, j'ai binarisée mes images, ce qui signifie que d'une image en niveaux de gris, chaque pixel sous une certaine valeur sont abandonnées. Cela me donne seulement quelques régions de l'image originale avec beaucoup de « zéro pixels » tout autour de ces régions.

Ensuite, j'ai RLL encodée mes régions en « blobs ». Pistes sont un procédé de compression de données. Par exemple, supposons que vous avez binarisée un carré, vous aurez seulement quelques pistes décrivant l'image. Les pistes sont définies par des coordonnées x, y et une longueur.

Lors de la recréation de l'image, pour chaque essai, aller à coordonnées x, y et ajouter des pixels sur l'axe des x de la longueur de la course.

Maintenant, je dois prendre les courses et créer une chaîne de ce qui décrira le contour de la région. Je ne sais pas comment faire.

I ont un tas de x, y, pistes de longueur et je dois "naviguer" sur les bords pour former un chaîne. Normalement, en imagerie ce processus se fait avec l'image originale mais je ne peux plus utiliser l'image originale ici, donc je dois calculer avec les pistes.

Je sais que cela ressemble à un grand mur de texte, mais je ne sais pas comment poser cette question mieux.

Les conseils ou des pointeurs sur la mise en œuvre identique serait génial.

EDIT

grâce à rialiser Ill lien quelques images:


(source: tudelft.nl )

Dans cet exemple, ils traitent l'image B dans le contour C (que j'appelle chaîne). Cependant, je voudrais générer le contour de D, la course Longueurs

Était-ce utile?

La solution 3

Et bien je perdu ce contrat, mais la réponse était d'utiliser le Freeman chaîne technique de codage

Le fait qu'il est exécuté le codage des longueurs n'a rien à voir avec l'algorithme, à la différence que je pensais que précédemment.

Autres conseils

À première vue, je ne vois pas un algorithme pratique pour cela. Une solution pauvre homme serait développez l'image originale de la longueur codée un. Donc, si vos lignes ressemblent à ceci:

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

où les caractères renvoient la valeur réelle des pixels (par exemple, A = 0, B = 127, ...). Vous pouvez écrire les valeurs de pixels dans un tableau à deux dimensions (ou une autre structure de données de votre choix) .Il ressemble à ceci:

ABBBAAAAAAAAAACDDDDDDDD
CDDDDAAACCCCCCAAAAAAAAA

générer ensuite votre chaîne, supprimez le tableau et conserver les informations de la chaîne. Bien sûr, cela coûte cher si peut-être vous pouvez le faire avant la longueur codant pour l'image d'origine.

Voici une solution parfaitement simple et pratique (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;
        }
    }

}

Cela fonctionne par itérer sur les pistes, à tester les extrémités gauche et droite pour la direction qu'ils sauter, et en ajoutant le nombre d'éléments de la chaîne à deux vecteurs: un pour l'avant, du côté droit, et un dans l'ordre inverse, pour la gauche. Il relie ensuite les deux chaînes en ajoutant le nombre approprié de liens pour la dernière ligne de balayage, puis inverse la chaîne latérale gauche et elle se adresse à celui de droite pour produire la chaîne finale.

L'espoir est ce que vous cherchez!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top