Précédent   Forum du club des développeurs et IT Pro > Autres langages > Algorithmes > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 13/05/2008, 21h19   #1
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Par défaut [image] Algorithmes de squelettisation d'images

Salut,

Il existe plusieurs algorithmes de squelettisation d'images, je vais essayer de vous expliquer quelques uns, je commence par l'algorithme de Hilditch :


Considérons le voisinage suivant :

Citation:
P1 P2 P3
P8 P P4
P7 P6 P5
Hilditch présente quatre conditions qu’un squelette doit remplir :

2 < = B(p1) < = 6
A(p1)=1
p2.p4.p8=0 ou A(p2)!= 1
p2.p4.p6=0 ou A(p4)!= 1


Avec :

B(p1) = nombre de voisins non nuls de P1.
A(p1) = nombre de passage de 0,1 de la séquence : P2,p3,p4,p5,p6,p7,p8,p1,p2

code C++
Code C :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
H=Image2->Picture->Bitmap->Height;
W=Image2->Picture->Bitmap->Width;
int Bp,Ap1,Ap2,Ap4;
for (int i=1;i<=nombreitération; i++)
{
for(int x=1;x<W;x++)
        for(int y=1;y<H;y++)
        {
        Bp=0;
        Ap1=0;
        Ap2=0;
        Ap4=0;
 
        if (Image2->Canvas->Pixels[x-1][y-1]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x-1][y]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x-1][y+1]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x][y+1]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x+1][y+1]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x+1][y]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x+1][y-1]==clBlack)Bp=Bp+1;
        if (Image2->Canvas->Pixels[x][y-1]==clBlack)Bp=Bp+1;
 
 
        if (Image2->Canvas->Pixels[x-1][y]==clWhite && Image2->Canvas->Pixels[x-1][y+1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x-1][y+1]==clWhite && Image2->Canvas->Pixels[x][y+1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x][y+1]==clWhite && Image2->Canvas->Pixels[x+1][y+1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x+1][y+1]==clWhite && Image2->Canvas->Pixels[x+1][y]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x+1][y]==clWhite && Image2->Canvas->Pixels[x+1][y-1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x+1][y-1]==clWhite && Image2->Canvas->Pixels[x][y-1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x][y-1]==clWhite && Image2->Canvas->Pixels[x-1][y-1]==clBlack)Ap1=Ap1+1;
        if (Image2->Canvas->Pixels[x-1][y-1]==clWhite && Image2->Canvas->Pixels[x-1][y]==clBlack)Ap1=Ap1+1;
 
 
        if (Image2->Canvas->Pixels[x-2][y]==clWhite && Image2->Canvas->Pixels[x-2][y+1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x-2][y+1]==clWhite && Image2->Canvas->Pixels[x-1][y+1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x-1][y+1]==clWhite && Image2->Canvas->Pixels[x][y+1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x][y+1]==clWhite && Image2->Canvas->Pixels[x][y]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x][y]==clWhite && Image2->Canvas->Pixels[x][y-1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x][y-1]==clWhite && Image2->Canvas->Pixels[x-1][y-1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x-1][y-1]==clWhite && Image2->Canvas->Pixels[x-2][y-1]==clBlack)Ap2=Ap2+1;
        if (Image2->Canvas->Pixels[x-2][y-1]==clWhite && Image2->Canvas->Pixels[x-2][y]==clBlack)Ap2=Ap2+1;
 
 
        if (Image2->Canvas->Pixels[x-1][y+1]==clWhite && Image2->Canvas->Pixels[x-1][y+2]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x-1][y+2]==clWhite && Image2->Canvas->Pixels[x][y+2]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x][y+2]==clWhite && Image2->Canvas->Pixels[x+1][y+2]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x+1][y+2]==clWhite && Image2->Canvas->Pixels[x+1][y+1]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x+1][y+1]==clWhite && Image2->Canvas->Pixels[x][y+1]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x][y+1]==clWhite && Image2->Canvas->Pixels[x][y]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x][y]==clWhite && Image2->Canvas->Pixels[x-1][y]==clBlack)Ap4=Ap4+1;
        if (Image2->Canvas->Pixels[x-1][y]==clWhite && Image2->Canvas->Pixels[x-1][y+1]==clBlack)Ap4=Ap4+1;
 
 
        if (Bp>=2 && Bp<=6 && Ap1==1)
        {
        if ((Image2->Canvas->Pixels[x-1][y]==clWhite && Image2->Canvas->Pixels[x][y+1]==clWhite && Image2->Canvas->Pixels[x][y-1]==clWhite)|| (Ap2==1) )
        {
        if ((Image2->Canvas->Pixels[x-1][y]==clWhite && Image2->Canvas->Pixels[x][y+1]==clWhite && Image2->Canvas->Pixels[x+1][y]==clWhite)|| (Ap4==1) )
                {
                Image2->Canvas->Pixels[x][y]=clWhite;
                }
        }
        }
}
}

NB : Les objets dans l'image doivent être noirs ( je n'aime pas les fonds noirs )

A suivre....
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 14h36   #2
b_reda31
Membre expérimenté
 
Avatar de b_reda31
 
Homme Réda Bentata
Étudiant
Inscription : avril 2007
Messages : 543
Détails du profil
Informations personnelles :
Nom : Homme Réda Bentata
Âge : 29
Localisation : Algérie

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 543
Points : 577
Points : 577
Envoyer un message via MSN à b_reda31
Merci pour cette contribution.
Je vois que vous utiliser la propriété Pixels!,la traitement doit être hyper long non?(surtout avec 3 boucles imbriqués)
__________________
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»
b_reda31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 16h35   #3
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Citation:
Envoyé par b_reda31 Voir le message
Je vois que vous utiliser la propriété Pixels!,la traitement doit être hyper long non?(surtout avec 3 boucles imbriqués)
Non, je ne trouve pas qu'il est long !! mais toute optimisation du code sera la bienvenue.
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 16h46   #4
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 815
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Architecte système
Secteur : Industrie

Informations forums :
Inscription : décembre 2006
Messages : 9 815
Points : 16 458
Points : 16 458
Citation:
Envoyé par Lost in Voir le message
Non, je ne trouve pas qu'il est long !! mais toute optimisation du code sera la bienvenue.
En l'occurence, je crois qu'il parle d'une optimisation spécifique à C++Builder(Scaline / Pixels)
__________________
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 16h59   #5
b_reda31
Membre expérimenté
 
Avatar de b_reda31
 
Homme Réda Bentata
Étudiant
Inscription : avril 2007
Messages : 543
Détails du profil
Informations personnelles :
Nom : Homme Réda Bentata
Âge : 29
Localisation : Algérie

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 543
Points : 577
Points : 577
Envoyer un message via MSN à b_reda31
Citation:
Envoyé par Lost in Voir le message
Non, je ne trouve pas qu'il est long !! mais toute optimisation du code sera la bienvenue.
Ah oui?!
Je viens de le tester chez moi,ça met environ une minute pour une Image 256x256 et avec 10 itérations.

Citation:
En l'occurence, je crois qu'il parle d'une optimisation spécifique à C++Builder(Scaline / Pixels)
Oui c'est de ça que je parlais et non pas d'optimisation de l'algorithme.
En remplaçant la propriété Pixels par ScanLine,le traitement sera beaucoup plus rapide.
__________________
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»
b_reda31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 17h41   #6
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Citation:
Envoyé par b_reda31 Voir le message
En remplaçant la propriété Pixels par ScanLine,le traitement sera beaucoup plus rapide.
Peux tu poster le code avec la propriété ScanLine ?
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 18h12   #7
PRomu@ld
Responsable Algorithmes
 
Avatar de PRomu@ld
 
Homme Romuald Perrot
Attaché Temporaire d'Enseignement et de Recherche (ATER)
Inscription : avril 2005
Messages : 4 146
Détails du profil
Informations personnelles :
Nom : Homme Romuald Perrot
Âge : 27
Localisation : France

Informations professionnelles :
Activité : Attaché Temporaire d'Enseignement et de Recherche (ATER)
Secteur : Enseignement

Informations forums :
Inscription : avril 2005
Messages : 4 146
Points : 6 166
Points : 6 166
Est-ce que tu peux nous poster un exemple d'application de ton algo ?
__________________
http://rperrot.developpez.com
http://phos-graphein.fr

Vous désirez contribuer à la rubrique algorithmique, n'hésitez pas à me contacter.
PRomu@ld est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 19h38   #8
b_reda31
Membre expérimenté
 
Avatar de b_reda31
 
Homme Réda Bentata
Étudiant
Inscription : avril 2007
Messages : 543
Détails du profil
Informations personnelles :
Nom : Homme Réda Bentata
Âge : 29
Localisation : Algérie

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 543
Points : 577
Points : 577
Envoyer un message via MSN à b_reda31
Personnellement pour le traitement d'image avec C++ Builder je procède comme suit:
1-Charger l'image dans une matrice.(Lecture)
2-Effectuer les traitement sur la matrice.
3-Charger la matrice dans l'image.(Ecriture)

J'utilise pour cela deux procédures :

-Pour la lecture :
Code :
void ImageToMatrice(TImage *img,byte mat[3000][3000])
lit l'image img de type TImage et charge ses éléments dans la matrice mat tout en la transformant en niveaux de gris.(Ca ne posera pas de problème puisque l'image en entré est binaire).





-Pour l'affichage:
Code C++ :
void MatriceToImage(TImage *img,byte mat[3000][3000])
Affiche le contenu de la matrice dans le composant l TImage.




C'est deux procédure utilisent la méthode ScanLine.L'image en entré doit être une BMP de format 24 bits,Sinon il faut modifier le corp des procédures.


Pour l'algorithme,comme je disais je n y toucherai pas,sauf pour le début et la fin du parcours,dans les boucles parcourant l'image en hauteur et largeur j'ai commencé par 2 au lieu de 1 jusqu'à w-3(en largeur) et h-3 (en hauteur),sinon il y aurai accès à des éléments qui se trouvent hors de l'image (Image1->Canvas->Pixels[x-2][y-2] avec x=0!)

Code C++ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 
int H=Image2->Picture->Bitmap->Height;
int W=Image2->Picture->Bitmap->Width;
int Bp,Ap1,Ap2,Ap4;
int nombreiteration=10;
 
 
ImageToMatrice(Image2,matrice);//Chargement de l'image dans "matrice"
 
 
for (int i=1;i<=nombreiteration; i++)
{
for(int x=2;x<W-2;x++)
        for(int y=2;y<H-2;y++)
        {
        Bp=0;
        Ap1=0;
        Ap2=0;
        Ap4=0;
 
        if (matrice[x-1][y-1]==0)Bp=Bp+1;
        if (matrice[x-1][y]==0)Bp=Bp+1;
        if (matrice[x-1][y+1]==0)Bp=Bp+1;
        if (matrice[x][y+1]==0)Bp=Bp+1;
        if (matrice[x+1][y+1]==0)Bp=Bp+1;
        if (matrice[x+1][y]==0)Bp=Bp+1;
        if (matrice[x+1][y-1]==0)Bp=Bp+1;
        if (matrice[x][y-1]==0)Bp=Bp+1;
 
 
        if (matrice[x-1][y]==255 && matrice[x-1][y+1]==0)Ap1=Ap1+1;
        if (matrice[x-1][y+1]==255 && matrice[x][y+1]==0)Ap1=Ap1+1;
        if (matrice[x][y+1]==255 && matrice[x+1][y+1]==0)Ap1=Ap1+1;
        if (matrice[x+1][y+1]==255 && matrice[x+1][y]==0)Ap1=Ap1+1;
        if (matrice[x+1][y]==255 && matrice[x+1][y-1]==0)Ap1=Ap1+1;
        if (matrice[x+1][y-1]==255 && matrice[x][y-1]==0)Ap1=Ap1+1;
        if (matrice[x][y-1]==255 && matrice[x-1][y-1]==0)Ap1=Ap1+1;
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==0)Ap1=Ap1+1;
 
 
        if (matrice[x-2][y]==255 && matrice[x-2][y+1]==0)Ap2=Ap2+1;
        if (matrice[x-2][y+1]==255 && matrice[x-1][y+1]==0)Ap2=Ap2+1;
        if (matrice[x-1][y+1]==255 && matrice[x][y+1]==0)Ap2=Ap2+1;
        if (matrice[x][y+1]==255 && matrice[x][y]==0)Ap2=Ap2+1;
        if (matrice[x][y]==255 && matrice[x][y-1]==0)Ap2=Ap2+1;
        if (matrice[x][y-1]==255 && matrice[x-1][y-1]==0)Ap2=Ap2+1;
        if (matrice[x-1][y-1]==255 && matrice[x-2][y-1]==0)Ap2=Ap2+1;
        if (matrice[x-2][y-1]==255 && matrice[x-2][y]==0)Ap2=Ap2+1;
 
 
        if (matrice[x-1][y+1]==255 && matrice[x-1][y+2]==0)Ap4=Ap4+1;
        if (matrice[x-1][y+2]==255 && matrice[x][y+2]==0)Ap4=Ap4+1;
        if (matrice[x][y+2]==255 && matrice[x+1][y+2]==0)Ap4=Ap4+1;
        if (matrice[x+1][y+2]==255 && matrice[x+1][y+1]==0)Ap4=Ap4+1;
        if (matrice[x+1][y+1]==255 && matrice[x][y+1]==0)Ap4=Ap4+1;
        if (matrice[x][y+1]==255 && matrice[x][y]==0)Ap4=Ap4+1;
        if (matrice[x][y]==255 && matrice[x-1][y]==0)Ap4=Ap4+1;
        if (matrice[x-1][y]==255 && matrice[x-1][y+1]==0)Ap4=Ap4+1;
 
 
        if (Bp>=2 && Bp<=6 && Ap1==1)
        {
        if ((matrice[x-1][y]==255 && matrice[x][y+1]==255 && matrice[x][y-1]==255)|| (Ap2==1) )
        {
        if ((matrice[x-1][y]==255 && matrice[x][y+1]==255 && matrice[x+1][y]==255)|| (Ap4==1) )
                {
                matrice[x][y]=255;
                }
        }
        }
}
}
 
 
MatriceToImage(Image2,matrice);//AFFICHAGE DU RESULTAT.
}

Ce qu'il faut ajouter en déclaration globale dans le fichier "H" :

Code C++ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
//à mettre juste aprés "public :" du fichier "h"
 
byte matrice[3000][3000];
void ImageToMatrice(TImage *img,byte mat[3000][3000])
 
 
{
 
 
class jPixel
{
public :
Byte Blue;
Byte Green;
Byte Red;
};
Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
 
 
 
 
jPixel *Pixel;
 
int grey, blue, red, green;
 
Graphics::TBitmap *B = img->Picture->Bitmap;
 
 
    for(int y = 0; y < B->Height; y++)
        {
        Pixel = (jPixel*)B->ScanLine[y];
        for(int x = 0; x < B->Width; x++)
            {
 
            grey = (Pixel[x].Red+
                    Pixel[x].Green+
                    Pixel[x].Blue) /3;
 
             mat[x][y]=grey;
}
        }
    img->Repaint();
}
 
void MatriceToImage(TImage *img,byte mat[3000][3000])
{
class jPixel
{
public :
Byte Blue;
Byte Green;
Byte Red;
};
Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
jPixel *Pixel;
 
int grey, blue, red, green;
Graphics::TBitmap *B ;
 
B=img->Picture->Bitmap;
 
 
    for(int y = 0; y < B->Height; y++)
        {
        Pixel = (jPixel*)B->ScanLine[y];
        for(int x = 0; x < B->Width; x++)
            {
 
            Pixel[x].Red=mat[x][y];
            Pixel[x].Green=mat[x][y];
            Pixel[x].Blue=mat[x][y];
             }
        }
    img->Repaint();
 
    }

Je viens de testé chez moi,le traitement avec affichage est quasi instantané.J'ajouterai juste que les procédures ImageToMatrice et MatriceToImage ne sont pas optimisé pour ce cas là,je les ai implémenté pour des bmp couleur 24 bits,il faudra donc ajouter un test sur le format de l'image au début dans le corp de ImageToMatrice.
__________________
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»
b_reda31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2008, 22h33   #9
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Pas mal
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 19h45   #10
benDelphic
Membre actif
 
Inscription : mars 2008
Messages : 209
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 209
Points : 193
Points : 193
Citation:
Envoyé par b_reda31 Voir le message
Personnellement pour le traitement d'image avec C++ Builder je procède comme suit:
1-Charger l'image dans une matrice.(Lecture)
2-Effectuer les traitement sur la matrice.
3-Charger la matrice dans l'image.(Ecriture)
tu penses que c'est plus rapide ? je n' suis pas si sur . en plus tu utilise une matrice 3000*3000 . je suggere plutot l'utilisation de matrice à base de vecteurs dynamiques ( une spécialité Borland quoi ) . puis tu met utilise setLength.
benDelphic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 19h52   #11
b_reda31
Membre expérimenté
 
Avatar de b_reda31
 
Homme Réda Bentata
Étudiant
Inscription : avril 2007
Messages : 543
Détails du profil
Informations personnelles :
Nom : Homme Réda Bentata
Âge : 29
Localisation : Algérie

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 543
Points : 577
Points : 577
Envoyer un message via MSN à b_reda31
Citation:
Envoyé par benDelphic Voir le message
tu penses que c'est plus rapide ? je n' suis pas si sur . en plus tu utilise une matrice 3000*3000 .
Certe question "mémoire" cela n'est pas trés optimal!
Mais en temps d'éxécution l'utilisation de ScanLine est beaucoup plus rapide que Pixels
Comme je le disais avec PIXELS le traitement prend presque une minute avec 10 itérations! alors qu'avec SCANLINE cela est instantané.
Citation:
je suggere plutot l'utilisation de matrice à base de vecteurs dynamiques ( une spécialité Borland quoi ) . puis tu met utilise setLength.
Il vaut mieux travailler directement avec un TBITMAP.
__________________
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»
b_reda31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 20h21   #12
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Par défaut Algorithme de Thomé

Salut !!

L'algorithme de Thomé est un algorithme de type parallèle : il supprime plusieurs points inessentiels à la fois.

Les 16 configurations présentent dans la pièce jointe sont un résumé de l'ensemble de toutes les configurations où P est inessentiel

Code C++ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
int H=Image1->Picture->Bitmap->Height;
int W=Image1->Picture->Bitmap->Width;
 
int nombreiteration=10;
 
 
ImageToMatrice(Image1,matrice);
 
 
 
for (int i=1;i<=nombreiteration; i++)
{
for(int x=1;x<W;x++)
        for(int y=1;y<H;y++)
        {
        if (matrice[x-1][y]==0 && matrice[x+1][y]==0  && matrice[x][y-1]==0 && matrice[x][y+1]==255) matrice[x][y]=255;
        if (matrice[x-1][y]==255 && matrice[x+1][y]==0  && matrice[x][y-1]==0 && matrice[x][y+1]==0) matrice[x][y]=255;
        if (matrice[x-1][y]==0 && matrice[x+1][y]==0  && matrice[x][y-1]==255 && matrice[x][y+1]==0) matrice[x][y]=255;
        if (matrice[x-1][y]==0 && matrice[x+1][y]==255  && matrice[x][y-1]==0 && matrice[x][y+1]==0) matrice[x][y]=255;
 
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==255  && matrice[x-1][y+1]==255 && matrice[x][y+1]==255 && matrice[x+1][y+1]==0 && matrice[x+1][y]==0 && matrice[x][y-1]==255)   matrice[x][y]=255;
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==255  && matrice[x-1][y+1]==255 && matrice[x][y+1]==255 && matrice[x+1][y]==0   && matrice[x+1][y-1]==0 && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y-1]==0 && matrice[x-1][y]==0   && matrice[x][y+1]==255   && matrice[x+1][y+1]==255 && matrice[x+1][y]==255 && matrice[x+1][y-1]==255 && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y]==0   && matrice[x-1][y+1]==0 && matrice[x][y+1]==255   && matrice[x+1][y+1]==255 && matrice[x+1][y]==255 && matrice[x+1][y-1]==255 && matrice[x][y-1]==255) matrice[x][y]=255;
 
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==255   && matrice[x][y+1]==0   && matrice[x+1][y+1]==0 && matrice[x+1][y]==255   && matrice[x+1][y-1]==255 && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==255   && matrice[x-1][y+1]==0 && matrice[x][y+1]==0  && matrice[x+1][y]==255   && matrice[x+1][y-1]==255 && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y]==255   && matrice[x-1][y+1]==255 && matrice[x][y+1]==255   && matrice[x+1][y+1]==255 && matrice[x+1][y]==255   && matrice[x+1][y-1]==0 && matrice[x][y-1]==0) matrice[x][y]=255;
        if (matrice[x-1][y-1]==0 && matrice[x-1][y]==255   && matrice[x-1][y+1]==255 && matrice[x][y+1]==255   && matrice[x+1][y+1]==255 && matrice[x+1][y]==255   && matrice[x][y-1]==0) matrice[x][y]=255;
 
        if (matrice[x-1][y]==255   && matrice[x-1][y+1]==255 && matrice[x][y+1]==255 && matrice[x+1][y]==0   && matrice[x][y-1]==0) matrice[x][y]=255;
        if (matrice[x-1][y-1]==255 && matrice[x-1][y]==255 && matrice[x][y+1]==0 && matrice[x+1][y]==0  && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y]==0   && matrice[x][y+1]==0   && matrice[x+1][y]==255   && matrice[x+1][y-1]==255 && matrice[x][y-1]==255) matrice[x][y]=255;
        if (matrice[x-1][y]==0   && matrice[x][y+1]==255   && matrice[x+1][y+1]==255 && matrice[x+1][y]==255   && matrice[x][y-1]==0) matrice[x][y]=255;
        }
}
MatriceToImage(Image1,matrice);

A bientôt
Images attachées
Type de fichier : jpg 16 Configurations.JPG (36,0 Ko, 80 affichages)
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 20h25   #13
benDelphic
Membre actif
 
Inscription : mars 2008
Messages : 209
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 209
Points : 193
Points : 193
non je parlais plutot de cette maniere bitmap-matrice-bitmap .
puis voila ce que donne ton code ...
sur une image fractale http://www.developpez.net/forums/att...1&d=1211134984
originale.jpg
avec un nombre d iteration de 10 ca donne
http://www.developpez.net/forums/att...1&d=1211134984
10bw.jpg
avec 100 cela donne
http://www.developpez.net/forums/att...1&d=1211134984
100bw.jpg
on constate qu il n y a aucun changement apart que ca passe en BW .
Pire encore sur une autre image ( un building ) l algo n a aucun effet ...
C'est normal ça ???
Images attachées
Type de fichier : jpg originale.jpg (23,2 Ko, 81 affichages)
Type de fichier : jpg 10bw.jpg (16,2 Ko, 62 affichages)
Type de fichier : jpg 100bw.jpg (16,8 Ko, 55 affichages)
benDelphic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 20h30   #14
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Citation:
Envoyé par benDelphic Voir le message
on constate qu il n y a aucun changement apart que ca passe en BW .
Pire encore sur une autre image ( un building ) l algo n a aucun effet ...
C'est normal ça ???
Le traitement doit être fait sur une image binaire
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 20h32   #15
benDelphic
Membre actif
 
Inscription : mars 2008
Messages : 209
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 209
Points : 193
Points : 193
Lost in il fallait le signaler au début et en plus ... a quoi servent ces filtres ?...
benDelphic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2008, 21h59   #16
b_reda31
Membre expérimenté
 
Avatar de b_reda31
 
Homme Réda Bentata
Étudiant
Inscription : avril 2007
Messages : 543
Détails du profil
Informations personnelles :
Nom : Homme Réda Bentata
Âge : 29
Localisation : Algérie

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 543
Points : 577
Points : 577
Envoyer un message via MSN à b_reda31
Citation:
Envoyé par benDelphic Voir le message
non je parlais plutot de cette maniere bitmap-matrice-bitmap .
puis voila ce que donne ton code ...
sur une image fractale http://www.developpez.net/forums/att...1&d=1211134984
originale.jpg
avec un nombre d iteration de 10 ca donne
http://www.developpez.net/forums/att...1&d=1211134984
10bw.jpg
avec 100 cela donne
http://www.developpez.net/forums/att...1&d=1211134984
100bw.jpg
on constate qu il n y a aucun changement apart que ca passe en BW .
Pire encore sur une autre image ( un building ) l algo n a aucun effet ...
C'est normal ça ???
Je n'ai pas touché à l'algorithme de la contribution,J'ai juste modifié la "manière" d'accéder à l'image.
__________________
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»
b_reda31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2008, 19h41   #17
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Pour PRomu@ld

Images obtenues après :

10 itérations pour Thomé

10 itérations pour Hilditch
Images attachées
Type de fichier : jpg Image test.JPG (16,2 Ko, 56 affichages)
Type de fichier : jpg Hilditch.JPG (13,4 Ko, 60 affichages)
Type de fichier : jpg thomé.JPG (11,8 Ko, 63 affichages)
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/06/2008, 20h09   #18
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Salut,

Pour déterminer si un point est inessentiel, Serra utilise les masques suivants :

Citation:
0 0 0
x 1 x
1 1 1
et

Citation:
x 0 0
1 1 0
x 1 x
L’ensemble des voisinages 3*3 d’un point inessentiel est obtenu à partir de ces configurations par rotation de 90°.

Code c++ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
for (int i=1;i<=nombreiteration; i++)
{
for(int x=1;x<W;x++)
        for(int y=1;y<H;y++)
        {
        if (matrice[x-1][y-1]==255  && matrice[x-1][y]==255    && matrice[x-1][y+1]==255  && matrice[x+1][y+1]==0    && matrice[x+1][y]==0     && matrice[x+1][y-1]==0 )   matrice[x][y]=255;
        if (matrice[x-1][y]==255    && matrice[x-1][y+1]==255  && matrice[x][y+1]==255    && matrice[x+1][y]==0      && matrice[x+1][y-1]==0   && matrice[x][y-1]==0 )     matrice[x][y]=255;
        if (matrice[x-1][y-1]==0    && matrice[x-1][y+1]==255  && matrice[x][y+1]==255    && matrice[x+1][y+1]==255  && matrice[x+1][y-1]==0   && matrice[x][y-1]==0 )     matrice[x][y]=255;
        if (matrice[x-1][y-1]==0    && matrice[x-1][y]==0      && matrice[x][y+1]==255    && matrice[x+1][y+1]==255  && matrice[x+1][y]==255   && matrice[x][y-1]==0 )     matrice[x][y]=255;
        if (matrice[x-1][y-1]==0    && matrice[x-1][y]==0      && matrice[x-1][y+1]==0    && matrice[x+1][y+1]==255  && matrice[x+1][y]==255   && matrice[x+1][y-1]==255 ) matrice[x][y]=255;
        if (matrice[x-1][y]==0      && matrice[x-1][y+1]==0    && matrice[x][y+1]==0      && matrice[x+1][y]==255    && matrice[x+1][y-1]==255 && matrice[x][y-1]==255 )   matrice[x][y]=255;
        if (matrice[x-1][y-1]==255  && matrice[x-1][y+1]==0    && matrice[x][y+1]==0      && matrice[x+1][y+1]==0    && matrice[x+1][y-1]==255 && matrice[x][y-1]==255 )   matrice[x][y]=255;
        if (matrice[x-1][y-1]==255  && matrice[x-1][y]==255    && matrice[x][y+1]==0      && matrice[x+1][y+1]==0    && matrice[x+1][y]==0     && matrice[x][y-1]==255 )   matrice[x][y]=255;
        }
}


L’algorithme général est de type séquentiel. Il consiste à balayer l’image ligne par ligne et à supprimer les points inessentiels au fur et à mesure qu’ils sont rencontrés. Il ne peut donc pas tenir compte de l’environnement dans lequel il opère et a tendance à enlever trop de points d’un seul coup.
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/05/2009, 22h31   #19
Booster_8
Invité de passage
 
Inscription : mai 2009
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 7
Points : 4
Points : 4
Algorithme de thomé en OpenCV: (petit pb d'exécution)

J'ai deja implémenté l'algo de Thomé en C++ mais à l'aide de la biblio OpenCv pr l'accés aux pixels de l'image (builder C++ et ImageToMatrice...machin chose pas trop compri !! )

en OpenCv, l'accés à l'image ne se fait pas comme une matrice donc le traitement est un peu lourd cad kil faut récupérer la valeur du pixel aprés faire la verification de son voisinage de configuration...etc, du fait, cela va prendre bcp de temps ou meme un buggage..voici mon code:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
nbr=10;
for(int k=0;k<nbr;k++)
 {
   // superposition et verification des 16 configurations de masques pour chaque pixel
   for(i=0;i<m_img->width;i++)
    {for(j=0;j<m_img->height;j++)
     {

        pixel=cvGet2D(m_img,j,i);
        // si le pixel est noir (l'image) on teste les masques
       if(pixel.val[0]==0) {
                                 verif=config_1(i,j);// verifie le mask1
                                 //cout<<pixel.val[0]<<endl;
                                 if(verif==true) {

                                                  pixel.val[0]=255;
                                                  pixel.val[1]=255;
                                                  pixel.val[2]=255;
                                                  cvSet2D(img_squel,j,i,pixel);
                                                  m_img=img_squel;

                                                 }
                                  else
                                  {
                                   verif=config_2(i,j);//verifie mask2
                                   if(verif==true){
                                                   pixel.val[0]=255;
                                                   pixel.val[1]=255;
                                                   pixel.val[2]=255;
                                                   cvSet2D(img_squel,j,i,pixel);
                                                   m_img=img_squel;

                                                  }
                                    else
                                    {
                                      verif=config_3(i,j);
                                      if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                      else
                                      { verif=config_4(i,j);
                                        if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;
                                                        stable=false;
                                                       }

                                        else
                                        {
                                           verif=config_5(i,j);
                                           if(verif==true) { pixel.val[0]=255;
                                                             pixel.val[1]=255;
                                                             pixel.val[2]=255;
                                                             cvSet2D(img_squel,j,i,pixel);
                                                             m_img=img_squel;

                                                          }
                                         else
                                         {
                                            verif=config_6(i,j);
                                            if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }

                                            else
                                            {
                                             verif=config_7(i,j);
                                             if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                             }
                                              else
                                              {
                                                verif=config_8(i,j);
                                                if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;
                                                        stable=false;
                                                       }
                                               else
                                               {
                                                verif=config_9(i,j);
                                                if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                                else
                                                {
                                                 verif=config_10(i,j);
                                                 if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                                else
                                                {
                                                  verif=config_11(i,j);
                                                  if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                                  else
                                                  {
                                                   verif=config_12(i,j);
                                                   if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                                  else
                                                  {
                                                    verif=config_13(i,j);
                                                    if(verif==true) { pixel.val[0]=255;
                                                        pixel.val[1]=255;
                                                        pixel.val[2]=255;
                                                        cvSet2D(img_squel,j,i,pixel);
                                                        m_img=img_squel;

                                                       }
                                                    else
                                                    {
                                                     verif=config_14(i,j);
                                                     if(verif==true) { pixel.val[0]=255;
                                                           pixel.val[1]=255;
                                                           pixel.val[2]=255;
                                                           cvSet2D(img_squel,j,i,pixel);
                                                            m_img=img_squel;

                                                                     }
                                                    else
                                                    {
                                                      verif=config_15(i,j);
                                                      if(verif==true) { pixel.val[0]=255;
                                                          pixel.val[1]=255;
                                                          pixel.val[2]=255;
                                                          cvSet2D(img_squel,j,i,pixel);
                                                          m_img=img_squel;

                                                                      }
                                                      else
                                                      {
                                                        verif=config_16(i,j);
                                                        if(verif==true) { pixel.val[0]=255;
                                                          pixel.val[1]=255;
                                                          pixel.val[2]=255;
                                                          cvSet2D(img_squel,j,i,pixel);
                                                          m_img=img_squel;

                                                                        }
                                                      }
                                                    }
                                                    }
                                                  }
                                                  }
                                                }
                                                }
                                               }
                                              }
                                            }
                                         }
                                        }
                                      }
                                    }
                                  }
        }
     }
    }
 }

 cvSaveImage("33_Frame_squelettisé.bmp",img_squel);

}
je veux vraiment savoir ou ça cloche ici, car parfois, il n'arrive pas a sortir de la boucle globale!!!! SOS
Booster_8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/05/2009, 13h28   #20
Lost in
Membre régulier
 
Avatar de Lost in
 
Inscription : janvier 2008
Messages : 268
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 268
Points : 85
Points : 85
Salut,

Je n'ai pas bien compris ton problème !!

Pour l'algorithme de Thomé il suffit qu'un pixel de l'image satisfasse l'une des 16 configurations données pour qu'on puisse dire qu'il n'appartient pas au squelette.

A+
__________________
Si vous acceptez vos possibilités présentes, vous progresserez certainement à l'avenir. en revanche si vous niez vos limites, vous ne vous en libérerez jamais.
Lost in est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 22h59.


 
 
 
 
Partenaires

Hébergement Web