IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème d'initialisation du signe


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 52
    Par défaut Problème d'initialisation du signe
    Bonjour tous le monde;

    Je fais une étude sur les méthodes de segmentation d'images; et pour cela il faut initialiser un contour (moi j'utilise un cercle comme une courbe initiale); et il faut initialiser aussi les différents signes:

    si on considère la matrice contour mc[i][j]

    à l'intérieur du cercle : mc[i][j]=-1

    à l'extérieur du cercle : mc[i][j]=+1

    sur le cercle ( c-a-d : les pixels appartenant aux contour): mc[i][j]=0

    comment je peut écrire un programme sous Builder C++ qui me permet de faire cette opération

    Merci d'avance.

  2. #2
    Membre Expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Par défaut
    euh j'ai pas bien compris tu veux simplement initialiser la matrice ?

  3. #3
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 52
    Par défaut
    oui c'est ca en mettant la condition si le pixel est à l'intérieur, éxterieur ou sur le cercle.

    Merci

  4. #4
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut

    Il y a surement plusieurs façon de procéder. En voici deux. Je suppose que ton cercle est représenté par son centre et son rayon en pixel.
    1. Soit tu parcours tous tes pixels et tu calcules à chaque fois sa position par rapport au cercle.
    2. Soit tu commences par trouver les pixels sur le contour du cercle, tu les initialises dans ta matrices à m[i][j]=0. Puis tu parcours tout tes pixels dans un l'ordre (de gauche à droite et de haut en bas par exemple) et tu regarde si le pixel courant est déjà initialisé à 0 dans ce cas tu incrémente un compteur de 1. Tous les pixels situés sur la même ligne seront des m[i][j]==-1 jusqu'à ce que ton compteur passe à 2.
      Je te passes les détails de ré-initialisation du compteur et des cas au bord de l'image.



    Inutile de dire que niveau perfs la deuxième méthode est largement meilleur que la première.

    Bon courage

  5. #5
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 52
    Par défaut
    Citation Envoyé par befalimpertinent

    Il y a surement plusieurs façon de procéder. En voici deux. Je suppose que ton cercle est représenté par son centre et son rayon en pixel.
    [LIST=1][*]Soit tu parcours tous tes pixels et tu calcules à chaque fois sa position par rapport au cercle.[*]Soit tu commences par trouver les pixels sur le contour du cercle, tu les initialises dans ta matrices à m[i][j]=0. Puis tu parcours tout tes pixels dans un l'ordre (de gauche à droite et de haut en bas par exemple) et tu regarde si le pixel courant est déjà initialisé à 0 dans ce cas tu incrémente un compteur de 1. Tous les pixels situés sur la même ligne seront des m[i][j]==-1 jusqu'à ce que ton compteur passe à 2.
    Je te passes les détails de ré-initialisation du compteur et des cas au bord de l'image.

    Inutile de dire que niveau perfs la deuxième méthode est largement meilleur que la première.

    Bon courage
    Merci beaucoup pour la réponse et vous avez raison la 2ème est beaucoup mieux que la première, mais toujours problème d'implémentation, je vais essayer ici de poster mon programme et a vous de m'aider a corriger les erreurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    par exemple pour le cercle je peut le dessiner en rouge et je met la condition:
     
    for (int i=0;i<H;i++)
        for (int j=0;j<W;j++)
             if (Image1->Canvas->Pixels[j][i]==clRed)
               mc[i][j]=0; //comme ca on a trouver les pixels du contour
    mais après ça je ne sais pas quoi faire car il faut que à l'intérieur soit -1 et à l'extérieur soit +1, et si on arrive a trouver l'un des deux on peut facilement trouver l'autre car l'image contient : pixels internes+pixels externes+contour; donc si on connait deux on peut tirer le troisième.

    j'attends vos réponse et Merciiiiiiii

  6. #6
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Une fois que tu as initialiser les pixels sur contour du cercle avec ta boucle :
    Citation Envoyé par nadjib2007
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    par exemple pour le cercle je peut le dessiner en rouge et je met la condition:
     
    for (int i=0;i<H;i++)
        for (int j=0;j<W;j++)
             if (Image1->Canvas->Pixels[j][i]==clRed)
               mc[i][j]=0; //comme ca on a trouver les pixels du contour
    Moi je verrais bien un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    bool inside = false;
    //tu re-parcours les pixels de ton image
    for (int i=0;i<H;i++)
       {
        for (int j=0;j<W;j++)
           {
             if (mc[i][j]==0)
               inside=!inside;
             else
               {
                 if(inside) //pixels dans le cercle
                   mc[i][j]=-1;
                 else //pixels a l exterieur
                   mc[i][j]=1;
               }        
           }
       }
    C'est très simplifié car il y a surement des petites subtilités si le cercle touche le bord ou dépasse le cadre de l'image. ça dépend aussi de la façon dont tu initialise la matrice de contour à sa création ( 1 ?) pour que la condition mc[i][j]==0 corresponde réellement aux pixels du cercle.

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Je pense que le plus rapide est d'initialiser ton image a -1, et de traiter ton cercle
    un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    InitImage(mc,-1);
    int r_r = rayon*rayon;
    for (int i=yc-r;i<yc+r;i++)
       {
       //si l'indice de ligne est hors de l'image on passe a la ligne suivante
       if (i<0 || i>=H) continue;
     
       //calcule des deux indices de colonne sur le cercle pour la ligne i
       int dy =(i-yc);
       int x_cercle = sqrt(r_r-dy*dy);
       int xcmin =xc - x_cercle;
       int xcmax =xc + x_cercle;
     
       for (int j=Xc-r;j<Xc+r;j++)
           {
           //si l'indice de colone est hor de l'image on passe au pixel  suivant
           if (j<0 || j>=W) continue;
     
           if (j==xcmin ||j==xcmax)
    		{
    		//pixel sur le cercle
    		mc[i][j]==0)
    		}	
    	else if (j>xcmin &&j<xcmax)
    		{
    		//pixels dans le cercle
                    mc[i][j]=1;
    		}
             else
                   {
                   //pixels hors du cercle
                   mc[i][j]=-1;
                   }        
           }
       }
    tu doit pouvoir diviser par 4 le traitement du cercle, en traitant 1/4 du cercle et en répercutant le résultat sur les autres partie par "miroire"( je trouve plus le mot )

  8. #8
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par Mongaulois
    tu doit pouvoir diviser par 4 le traitement du cercle, en traitant 1/4 du cercle et en répercutant le résultat sur les autres partie par "miroire"( je trouve plus le mot )
    Symétrie je crois

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par befalimpertinent
    Symétrie je crois
    ouai merci

  10. #10
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 52
    Par défaut
    Citation Envoyé par Mongaulois
    Je pense que le plus rapide est d'initialiser ton image a -1, et de traiter ton cercle
    un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    InitImage(mc,-1);
    int r_r = rayon*rayon;
    for (int i=yc-r;i<yc+r;i++)
       {
       //si l'indice de ligne est hors de l'image on passe a la ligne suivante
       if (i<0 || i>=H) continue;
     
       //calcule des deux indices de colonne sur le cercle pour la ligne i
       int dy =(i-yc);
       int x_cercle = sqrt(r_r-dy*dy);
       int xcmin =xc - x_cercle;
       int xcmax =xc + x_cercle;
     
       for (int j=Xc-r;j<Xc+r;j++)
           {
           //si l'indice de colone est hor de l'image on passe au pixel  suivant
           if (j<0 || j>=W) continue;
     
           if (j==xcmin ||j==xcmax)
    		{
    		//pixel sur le cercle
    		mc[i][j]==0)
    		}	
    	else if (j>xcmin &&j<xcmax)
    		{
    		//pixels dans le cercle
                    mc[i][j]=1;
    		}
             else
                   {
                   //pixels hors du cercle
                   mc[i][j]=-1;
                   }        
           }
       }
    tu doit pouvoir diviser par 4 le traitement du cercle, en traitant 1/4 du cercle et en répercutant le résultat sur les autres partie par "miroire"( je trouve plus le mot )
    Merci beaucoup pour la réponse je vais tester ce programme et si j'aurai des résultats je les poster ....

    et merci beaucoup a vous " befalimpertinent " pour tes réponses ça ma fait plaisir

  11. #11
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    A la seule lecture du code , il me semble que ca ne marchera pas sur les parties "horizontales" du cercle...
    (edit) Et le premier test me semble louche: si le cercle est plus grand d'entrée de jeu, on fait rien et on laisse à -1 comme si c'était hors du cercle

    Choix 1: Refaire la boucle dans le sens vertical (sans mise à +1 à l'interieur cette fois).
    Choix 2: Utiliser à mort les symétries infinies du cercle, notamment autour des diagonales (pour éviter le problême évoqué).

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    C'est juste une ébauche. Y as sûrement quelque erreur

    Citation Envoyé par nicroman
    A la seule lecture du code , il me semble que ca ne marchera pas sur les parties "horizontales" du cercle...
    comment ca?


    Citation Envoyé par nicroman
    (edit) Et le premier test me semble louche: si le cercle est plus grand d'entrée de jeu, on fait rien et on laisse à -1 comme si c'était hors du cercle
    euh. ben si une parti du cercle est hors de l'image, on peut pas faire grand chose, donc ou passe a une autre partie

    Citation Envoyé par nicroman
    Choix 1: Refaire la boucle dans le sens vertical (sans mise à +1 à l'intérieur cette fois).
    pas terrible pour de l'image. Les parcours horizontaux sont plus rapide que les parcours verticaux. Bien sur, uniquement si l'image est implémenté suivant le sens horizontale


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (j==xcmin ||j==xcmax)
    		{
    		//pixel sur le cercle
    		mc[i][j]==0)
    		}	
    	else if (j>xcmin &&j<xcmax)
    		{
    		//pixels dans le cercle
                    mc[i][j]=1;
    		}
             else
                   {
                   //pixels hors du cercle
                   mc[i][j]=-1;
                   }
    }
    peut etre remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (j==xcmin ||j==xcmax)
    		{
    		//pixel sur le cercle
    		mc[i][j]==0)
    		}	
    	else if (j>xcmin &&j<xcmax)
    		{
    		//pixels dans le cercle
                    mc[i][j]=1;
    		}
    }
    puise que l'image est déjà initialisé a -1 mais bon ca ne se vera pas

  13. #13
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Aprés si le cercle fait une bonne partie de l'image, autant traiter le cercle en même temp que l'initialisation, mais y aura un plus de test

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Je pense que la lecture de http://www.cs.unc.edu/~mcmillan/comp...e7/circle.html pourra être assez instructive, sur la façon de tracer la frontière du cercle, ensuite, en parcourant le tableau et en comptant le nombre de fois où l'on traverse la frontière, ça ne devrait pas être trop difficile.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  15. #15
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Excellent lien...
    Ce qui est marrant ... les deux premiers essais font exactement la même erreur que Mongaulois.
    Mais la dernière, utiliser la symétrie diagonale... par contre....

  16. #16
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par nicroman
    Excellent lien...
    Ce qui est marrant ... les deux premiers essais font exactement la même erreur que Mongaulois.
    Mais la dernière, utiliser la symétrie diagonale... par contre....
    ah ouai je vien de comprendre le problème.
    En utilisant les xcmax xcmin de la ligne précédente,
    y as sûrement moyen de palier au problème
    genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (j==xcmin || (j>xcmin_old &&j<=xcmin) 
         ||j==xcmax || (j>=xcmax &&j<xcmax_old)  )
    		{
    		//pixel sur le cercle
    		mc[i][j]==0)
    		}

  17. #17
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 52
    Par défaut
    ohh ...vraiment c'est extra ordinaire vos réponses et vos aidés merci beaucoup à vous tousssssssssssssssss

Discussions similaires

  1. Problème d'initialisation
    Par Gryzzly dans le forum C
    Réponses: 3
    Dernier message: 26/12/2005, 12h24
  2. Problème d'initialisation de winsock
    Par benjiprog dans le forum C
    Réponses: 6
    Dernier message: 18/12/2005, 10h45
  3. Problème d'initialisation avec GLFW
    Par adrien357 dans le forum Composants VCL
    Réponses: 4
    Dernier message: 23/10/2005, 18h29
  4. Problème d'initialisation variable tableau
    Par HeZiX dans le forum Langage
    Réponses: 3
    Dernier message: 08/06/2005, 16h30
  5. Pitié, aidez moi : Problème d'initialisation de postgreSQL
    Par ttalourd dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 16/11/2004, 12h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo