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 :

tableau des tableaux


Sujet :

C++

  1. #1
    Membre actif
    Inscrit en
    Février 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 61
    Par défaut tableau des tableaux
    Bonjour,
    Je suis débutante en c++, je développe une fonction pour décomposer une image couleur en blocs.
    Ma fonction prend en paramètre les deux points de départ de bloc et retourne un tableau. Voici le code appelant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(unsigned int y=0;y < L;y++)
     
    	    for(unsigned int x=0;x< C;x++)
     
     
                     PixelValue *tile_tab=JPGImage_Entree.Extract_tile(y*64,x*64,y,x);
    je ne trouve pas la bonne structure pour sauvegarder chaque tableau. est ce que je peux utiliser une matrice ?

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Pourquoi ne pas utiliser OpenCV pour gérer simplement tes matrices-images ?

  3. #3
    Membre actif
    Inscrit en
    Février 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 61
    Par défaut
    en faite je veux implémenter moi meme la fonction, mon probleme est de sauvegarder chaque bloc extrait dans une matrice ou chaque ligne représente un bloc.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour !

    Alors perso, j'utiliserais un vector de vector, sous la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    vector<vector<PixelValue> >
    ou sinon, je les ait pas étudiés donc je veux pas te dire de bêtises, mais il me semble que la STL a encapsulé une classe array, faisant la même chose que un tableau de taille fixe....

    Dans tous les cas, ça seras de la forme :
    tableau<tableau<type> >

    et tu pourras utiliser tableau[x][y]

    Voila, en espérant avoir aidé

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    A vrai dire, je ne suis vraiment pas partisan du fait d'utiliser std::vector<std::vector<UnType> > quand la "matrice" est clairement destinée à être pleine, comme c'est le cas ici.

    On peut en effet estimer si une image a X pixels de large et Y pixels de haut qu'il faudra *forcément* fournir l'intégralité des X*Y pixels qui la représentent.

    Dés lors, il est surement beaucoup plus facile de travailler avec un tableau de dimension unique qui va effectivement contenir les X*Y pixels (car c'est le but), et utiliser la formule relativement simple pour obtenir l'index d'un pixel se trouvant à la ligne row et à la colonne col que voici : index = row*X + col (note: bien qu'on ait l'habitude de représenter les coordonnées sous la forme "abscisse, ordonnée", les pixels d'une image sont généralement stocké dans l'autre sens: tous les pixels d'une même ligne étant contigus )

    Evidemment, cela sous entend qu'il faut veiller à garder la largeur et la hauteur de l'image "quelque part".

    Pour cela, l'idéal est sans doute de travailler avec une classe proche de
    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
    class Image
    {
        public:
            /* il faut connaitre la hauteur et la largeur de l'image */
            Image(size_t width, size_t height):width_(width), height_(height)
            {
                pixels_.reserve(height_*width_);
            }
            /* pour obtenir la valeur du pixel à la ligne row et à la colonne col */
            PixelValue const & pixelAt(size_t row, size_t col) const
            {
                 /* on peut vérifier que row < height_ et que col < width_ ;) */
                 return pixels_[row*  width_ + col];
            }
            void changePixelAt(size_t row, size_t col, PixelValue const & newValue)
            {
     
                 /* on peut vérifier que row < height_ et que col < width_ ;) */
                 pixels_[row*  width_ + col] = newValue;
            }
        private:
            size_t width_;
            size_t height_;
            std::vector<PixelValue> pixels_;
    };
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Dés lors, il est surement beaucoup plus facile de travailler avec un tableau de dimension unique
    Tu devrais expliquer pourquoi cela est beaucoup plus facile.

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    La question est abordée dans la FAQ : Pourquoi est-il préférable que l'interface de ma classe Matrix ne soit pas basée sur le modèle du tableau de tableaux ?
    Et on peut ajouter que l'on voit régulièrement des débutants avoir des problèmes de manipulations de tableaux de tableaux, autant se limiter aux tableaux simples

  8. #8
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    La question est abordée dans la FAQ : Pourquoi est-il préférable que l'interface de ma classe Matrix ne soit pas basée sur le modèle du tableau de tableaux ?
    Et on peut ajouter que l'on voit régulièrement des débutants avoir des problèmes de manipulations de tableaux de tableaux, autant se limiter aux tableaux simples
    Juste remarque et si on reprend la FAQ ("Utilisez l'approche basée sur l'operator()") et l'embryon de classe de Koala, ça donne en substance :

    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
     
    class Image
    {
        public:
            /* il faut connaitre la hauteur et la largeur de l'image */
            Image(size_t width, size_t height):width_(width), height_(height)
            {
                pixels_.reserve(height_*width_);
            }
     
            inline PixelValue const & operator () (size_t row, size_t col) const
            {
                 /* on peut vérifier que row < height_ et que col < width_ ;) */
                 return pixels_[row*  width_ + col];
            }
            inline PixelValue & operator () (size_t row, size_t col)
            {
                 /* on peut vérifier que row < height_ et que col < width_ ;) */
                 return pixels_[row*  width_ + col];
            }
     
            inline size_t width() const { return width_; } ;
            inline size_t height() const { return height_; } ;
     
        private: 
            size_t width_;
            size_t height_;
            std::vector<PixelValue> pixels_;
    };
    pour pouvoir faire un bon vieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Image image(5,5);
    for ( size_t i = 0; i < image.width(); i++ ){
         for ( size_t j = 0; j < image.heigth(); j++ ){
               image(i,j) = ( i == j ) ? 1 : 0 ;
         }
    }

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    La bafouille parle des performances, mais pas de facilité du stockage en ligne.
    En fait, ce qui est surtout abordé, c'est la prise en compte du cas des matrices creuses. Et on pourrait parfaitement imaginer un vecteur de vecteurs, si les performances n'étaient pas de première importance.
    Comme nous parlons ici d'une image, un tableau de tableaux fait l'affaire.

    Citation Envoyé par gbdivers Voir le message
    Et on peut ajouter que l'on voit régulièrement des débutants avoir des problèmes de manipulations de tableaux de tableaux, autant se limiter aux tableaux simples
    Pour désigner l'élément d'une matrice, il apparait pourtant bien plus facile d'utiliser la double indexation qu'une formule.

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Tout fera l'affaire. Même un pointeur nu sur les data. La question est qu'est ce qui permet le moins d'erreur

    bien plus facile d'utiliser la double indexation qu'une formule
    Il faut utiliser img[x][y] ou img[y][x] ? C'est une erreur très classique. Alors que img.at(x,y) est bien plus naturel (ça ne viendrait à l'idée de personne d'écrire img.at(y,x))

    De plus, c'est une mauvaise abstraction, tu dois savoir si tu es sur un modèle colonne ou lignes, alors qu'avec (x,y) ça ne change pas le code


    De toute façon, tant que l'on verra sur les forums des gens se tromper lors de l'utilisation de tableau de tableau, ça va être dur de dire que cela ne pose pas de problème et on continuera de conseiller cette approche
    (de toute façon, vu le nombre régulière d'erreur avec [], je conseillerais même de ne plus l'utiliser, au profit de at())

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Il faut utiliser img[x][y] ou img[y][x] ?
    Non. C'est simplement que l'argument de simplicité ne me semblait pas pertinent.

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par oodini Voir le message
    Non. C'est simplement que l'argument de simplicité ne me semblait pas pertinent.
    Et pourtant:

    1. Avec la double indexation, tu vas te retrouver à faire un nombre d'allocations mémoire correspondant à la taille du premier indice +1, chacune d'elle pouvant échouer (la gestion d'erreur devient particulièrement difficile pour éviter les fuites mémoires ), travailler avec std::vector ne changera rien à ce problème
    2. Quand tu n'as plus besoin de la matrice, tu dois effectuer un nombre de libérations de mémoire correspondant à la taille du premier indice +1, sous peine d'observer une fuite mémoire
    3. Le premier indice représente l'abscisse, ou l'ordonnée
    4. Pour être efficace, tu dois créer deux classes différentes: une qui donne accès au premier indice, l'autre qui donne accès au deuxième
    5. Tu dois travailler, pour le premier indice, avec un tableau de pointeurs

    Le fait de travailler avec une collection de X * Y éléments t'évite tous ces problèmes:
    1. Tu n'as plus qu'une seule allocation de mémoire (donc, une seule possibilité d'échec), et tu évites donc les fuites mémoires en cas d'échec
    2. Tu n'as plus qu'une seule libération de mémoire à effectuer (même si elle est automatique avec std::vector)
    3. La fonction qui te permet d'accéder à un élément donné t'indique clairement si la première valeur est l'abscisse ou l'ordonnée, la représentation physique (ligne * colonne ou colonne * ligne) ne change rien au code qui utilise ta matrice
    4. Tu te rapproche finalement fort de la représentation mathématique d'accès aux données d'une matrice (on pourrait remplacer la fonction at par l'opérateur () qui permettrait un code proche de mat(x, y) )
    5. Une seule classe suffit, vu que tu peux fournir directement la valeur d'abscisse et la valeur d'ordonnée à la fonction (que ce soit at() ou l'opérateur () )
    6. Tu peux travailler directement avec des objets, au lieu de devoir travailler avec des pointeurs sur objets pour le premier indice
    L'argument de facilité est donc bel et bien présent et, cerise sur le gâteau, on peut ajouter un argument du point de vue des performances (qui ne seront de toutes façons jamais pires qu'avec l'approche utilisant deux indices)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    tu oublie le bonus kiss-cool:
    si un jour tu passe à une classe à trois indices, tu n'as quasiment rien à changer:
    un parametre et l'implémentation de operator(), modifier la méthode internal_size()
    modifier le constructeur.

    Avec les templates et les initializer_list, tu peux meme ne rien avoir à changer du tout.

    alors qu'avec une abstraction crocheteuse, la cubice devient une pilier<colonne<ligne<T>>> (si la matrice etait un colonne<ligne<T>>)

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Et puis, si on veut vraiment des opérateurs [], on peut en faire qui retournent des proxys, mémorisant les coordonnées, le dernier retournant at(a, b, ...).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Envoyer un tableau des tableaux en ajax mvc3
    Par lilux dans le forum ASP.NET Ajax
    Réponses: 1
    Dernier message: 16/04/2012, 10h22
  2. [iText] Tableau contenant des tableaux
    Par drizztoli dans le forum Documents
    Réponses: 2
    Dernier message: 01/09/2010, 21h51
  3. Affichage des données d'un tableau de tableaux
    Par Invité dans le forum Langage
    Réponses: 4
    Dernier message: 13/07/2010, 10h59
  4. [PHP 5.3] Parcours d'un tableau tridimensionnel contenant des tableaux
    Par DarkSeiryu dans le forum Langage
    Réponses: 11
    Dernier message: 28/05/2010, 15h05
  5. Tableau dont les éléments sont des tableaux
    Par tpdm dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 27/01/2010, 19h02

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