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

Langage C++ Discussion :

Problème remplissage std::map


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut Problème remplissage std::map
    Bonjour,

    J'ai une image volumique en niveau de gris sous forme d'un tableau tridimensionnel d'unsigned char ptr donc chaque élément correspond à un niveau de gris (blanc=niveau maximal, noir=niveau nul).

    Je désire trier mes voxels selon leur niveau de gris. J'ai pensé à une std::map dont les clés sont les adresses des voxels dans ptr et dont les valeurs sont les niveaux de gris. Voici un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    std::map<unsigned char*, unsigned char, classcomp> mamap;
    //remplissage de la map
    for(int i=0; i<3; i++)
     for(int j=0; j<2; j++)
      for(int k=0; k<4; k++)
        mamap[&ptr[i][j][k]] = ptr[i][j][k];

    où classcomp est défini comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct classcomp {
      bool operator()( unsigned char* s1, unsigned char* s2 ) {
            return (*s1)<(*s2);
          }
    };


    Après ceci, le premier constat est que la taille de mamap vaut 1!!! C'est pas bon! La taille devrait être la taille du volume (=nbre total de voxels).

    Où pensez-vous que se situe mon erreur?

    Merci de m'aider, je ne comprends pas
    Pix

  2. #2
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Insérer les voxels selon leur adresse mémoire est à priori très douteux. Mais bon, si c'est ce que tu veux faire...

    Une adresse n'est pas un unsigned char, c'est un unsigned int.

    Donc, pour ce faire, tu dois faire comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::map<unsigned int, unsigned char, classcomp> mamap;
    //remplissage de la map
    for(int i=0; i<3; i++)
     for(int j=0; j<2; j++)
      for(int k=0; k<4; k++)
        mamap[(unsigned int)&ptr[i][j][k]] = ptr[i][j][k];

  3. #3
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Salut,

    Merci pour ta proposition, mais je pense que ca ne peut pas marcher :
    étant donné que je veux trier les voxels par niveau de gris croissant rien qu'en les insérant dans la map (qui trie en interne par ordre croissant selon l'opérateur de comparaison, lors de l'insertion), c'est l'opérateur de comparaison qui est important et en mettant "unsigned int" comme type d'adresse, je ne peux plus accéder à la valeur pointée! Et donc plus comparer les niveaux de gris!

    Tu comprends ce que j'ai voulu faire? Mais bon, ça ne marche pas...

  4. #4
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Tu peux ré-effectuer un cast avec l'adresse pour avoir la valeur, mais c'est vraiment trop barbare (déjà que je ne mettrais jamais le code que j'ai moi même posté plus haut dans un de mes code sources...)

    Tu ferais mieux alors d'avoir un vecteur, simplement. Tu ajoutes tes voxels un par un avec un push_back, et ensuite tu fais un sort avec ton foncteur.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Faudrait pas faire dans l'autre sens? Si tes niveaux de gris sont les valeurs de tes pointeurs, ce doit être eux les clefs de ta map (la map est triée par clefs, pas par valeurs)

    Donc, faudrait un truc comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mamap[ptr[i][j][k]]=&(ptr[i][j][k]);
    (et peut être mettre les coordonnées i,j,k au lieu des adresses comme valeurs de la map...)

    non?



    Francois

  6. #6
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    J'ai essayé ta proposition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    std::vector<unsigned char *> monvector;
    //remplissage du vecteur
    for(int i=0; i<3; i++)
     for(int j=0; j<2; j++)
      for(int k=0; k<4; k++)
        monvector.push_back(&ptr[i][j][k]);
     
    std::sort(monvector.begin(), monvector.end(), uc_cpr);
    avec uc_cpr défini comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    bool uc_cpr( unsigned char * s1, unsigned char * s2 ) {
      return (*s1)<=(*s2);
    }

    et le programme plante, je ne comprends pas bien..

  7. #7
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    fcharton : le souci est que pour un niveau de gris donné, plusieurs voxels peuvent l'avoir... Donc en inversant, je perds des données!

  8. #8
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Citation Envoyé par Pixcoder Voir le message
    J'ai essayé ta proposition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    std::vector<unsigned char *> monvector;
    //remplissage du vecteur
    for(int i=0; i<3; i++)
     for(int j=0; j<2; j++)
      for(int k=0; k<4; k++)
        monvector.push_back(&ptr[i][j][k]);
     
    std::sort(monvector.begin(), monvector.end(), uc_cpr);
    avec uc_cpr défini comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    bool uc_cpr( unsigned char * s1, unsigned char * s2 ) {
      return (*s1)<=(*s2);
    }

    et le programme plante, je ne comprends pas bien..
    Normal, uc_cpr doit renvoyer vrai si le 1er argument est strictement inférieur, et non inférieur ou égal !

    Ce code fonctionne chez moi:

    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
    36
    37
    #include <vector>
    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    bool uc_cpr( unsigned char * s1, unsigned char * s2 ) {
      return (*s1)<(*s2);
    }
     
     
    int main()
    {
    	vector< unsigned char * > v;
     
    	unsigned char ptr[10][10][10];
     
    	for( int i = 0; i < 10; ++i )
    		for( int j = 0; j < 10; ++j )
    			for( int k = 0; k < 10; ++k )
    				ptr[i][j][k] = i+(i*j+k)+(i+j*k);
     
    	for( int i = 0; i < 10; ++i )
    		for( int j = 0; j < 10; ++j )
    			for( int k = 0; k < 10; ++k )
    				v.push_back( &ptr[i][j][k] );
     
    	cout << "pre order:" << endl;
    	for( unsigned int i = 0; i < v.size(); ++i )
    		cout << '0' + *v[i] << endl;
     
    	sort( v.begin(), v.end(), uc_cpr );
     
    	cout << "post order:" << endl;
    	for( unsigned int i = 0; i < v.size(); ++i )
    		cout << '0' + *v[i] << endl;
    }

Discussions similaires

  1. Problème avec std::map
    Par Mat.M dans le forum SL & STL
    Réponses: 15
    Dernier message: 01/09/2010, 19h55
  2. std map problème récurrent
    Par Champignon_atomik dans le forum SL & STL
    Réponses: 11
    Dernier message: 03/10/2008, 17h35
  3. extern std:map problème exécution
    Par Champignon_atomik dans le forum C++
    Réponses: 10
    Dernier message: 08/04/2008, 11h09
  4. Problème de class template et std::map
    Par bathof dans le forum Langage
    Réponses: 2
    Dernier message: 31/07/2007, 22h18
  5. Problème de fonction "const" avec une std::map
    Par Clad3 dans le forum SL & STL
    Réponses: 3
    Dernier message: 02/01/2007, 12h38

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