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

OpenCV Discussion :

cvCreateImage et cvCloneImage


Sujet :

OpenCV

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Mai 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 196
    Par défaut cvCreateImage et cvCloneImage
    Bonjour,

    J'ai un petit problème quand j'utilise cvCreateImage associé à cvCloneImage, en effet j'ai le message suivant :
    OpenCV Error: Bad argument (Bad image header) in cvCloneImage, file [...]/OpenCV-2.0.0/src/cxcore/cxarray.cpp, line 3085
    En fait je dois afficher une image de taille quelconque (généricité), en niveau de gris. Pour cela je crée une image avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
    Et je l'initialise à "gris" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	for(int i=0; i<i_width; i++)
    		for(int j=0; j<i_height; j++)
    			((uchar *)(i_img->imageData + i*i_img->widthStep))[j]=125;
    Cette image est vouée à être modifiée pixel par pixel de façon dynamique, mais en partant à chaque fois de la base. Pour afficher une modification, je fais l'hypothèse que cvCloneImage est plus rapide que mon initialisation, puis je modifie les quelques pixel à modifier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    initImageDeBase();
    for(...)
    {
        IplImage* _tmp_cart_img = cvCloneImage(img_de_base);
        ((uchar *)(_tmp_cart_img->imageData + (unsigned int)_x*_tmp_cart_img->widthStep))[(unsigned int)_y]=_vPixel;
        cvShowImage("Events_cartesien", _tmp_cart_img);
        cvWaitKey(10);
        cvReleaseImage(&_tmp_cart_img);
    }
    En cherchant j'ai vu qu'il existait une méthode qui était censée initialiser le header,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cvInitImageHeader( image, *size, IPL_DEPTH_8U, channel)
    , mais ça ne change rien, ou alors je l'utilise mal ...

    Si vous avez une piste je suis preneur.

    Merci à vous.

    Clercq.

  2. #2
    Membre confirmé
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    65
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 65
    Par défaut
    Salut,
    je ne vois pas ou est le problème.

    "cvCloneImage" créé une copie compléte de l'en-tête, des données et du ROI. Donc, pas la peine de recréer un header!

    J'ai tester un code chez moi qui ressemble à ta description et il fonctionne:
    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
    IplImage * img_de_base= cvCreateImage(cvSize(200, 100), IPL_DEPTH_8U, 1);
     
    for(int i=0; i<100; i++)
        for(int j=0; j<200; j++)
            ((uchar *)(img_de_base->imageData + i*img_de_base->widthStep))[j]=200;
     
    for (int _x = 0; _x< 100; _x++)
    {
        for (int _y = 0; _y< 100; _y++)
        {
            IplImage* _tmp_cart_img = cvCloneImage(img_de_base);
            ((uchar *)(_tmp_cart_img->imageData + (unsigned int)_x*_tmp_cart_img->widthStep))[(unsigned int)_y]=0;
            cvShowImage("Events_cartesien", _tmp_cart_img);
            cvShowImage("ee", img_de_base);
            cvWaitKey(10);
            cvReleaseImage(&_tmp_cart_img);
        }
    }
    J'ai un beau pixel qui se promène à l'écran :p

    Peux-tu envoyer ton code?

  3. #3
    Membre éprouvé
    Inscrit en
    Mai 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 196
    Par défaut
    Merci de ta réponse 01011,

    En fait j'ai modifié quelque peu mon code est maintenant ça fonctionne ...

    Le problème venait du fait de l'initialisation de mon image de base.

    En fait cette image est membre de ma classe, je l'initialisais par appel dans le constructeur d'une méthode d'initialisation,
    qui comme le montre l'entête prenait en paramètre l'image. Pourquoi faire ça alors que mon image est membre de la classe ? Et bien parce que j'ai deux image à initialiser et donc je voulais faire un truc "propre".

    Mais depuis que j'initialise mes images directement dans le constructeur, et donc sans appel à la méthode ... Et bien ça fonctionne ?!?

    Pourtant mon image étant un pointeur, je ne vois pas vraiment la différence ... J'ai regardé rapidement du coté des pointeurs intelligents, qui, en version basique pourraient apporter des problèmes similaires, mais je n'ai pas conclue.

    Du coup mon code fonctionne (enfin pour cette partie), mais je ne vois pas trop le comment, ni le pourquoi ...

    Merci encore.

  4. #4
    Membre confirmé
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    65
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 65
    Par défaut
    regarde ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void init_img(IplImage * x)
    {
        x = cvCreateImage(cvSize(100, 200), IPL_DEPTH_8U, 1);
        std::cout << x; // x est égale à 0xXXXXXXXX
    }
     
    IplImage * init_img()
    {
        x = cvCreateImage(cvSize(100, 200), IPL_DEPTH_8U, 1);
        std::cout << x; // x est égale à 0xXXXXXXXX
        return x;
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IplImage * img = NULL;
    std::cout << img; // img est égale à 0x00000000
    init_img(img);
    std::cout << img; // img est toujours égale à 0x00000000
    img = init_img();
    std::cout << img; // img est égale à 0xXXXXXXXX
    bref, pour bien initialiser ton image, ta fonction doit avoir la forme
    IplImage * init_img(void);
    et non
    void init_img(IplImage * src);

  5. #5
    Membre confirmé
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    65
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 65
    Par défaut
    Citation Envoyé par Clercq Voir le message
    En fait cette image est membre de ma classe, je l'initialisais par appel dans le constructeur d'une méthode d'initialisation...
    Comme tu travailles en c++, pourquoi tu n'utilises pas les fonctions c++ d'OpenCV et la class cv::Mat? Elles existent depuis OpenCV2.0 je pense, et elles te permettent d'éviter les problème lier aux pointeurs. En plus, elles sont compatible avec l'ancienne syntaxe (la syntaxe c) via quelque manip.
    Regarde dans la doc, tu trouvera des exemples.

    A+

Discussions similaires

  1. Réponses: 0
    Dernier message: 13/12/2010, 11h02
  2. Problème de mémoire avec CvCreateImage
    Par kvarme63 dans le forum OpenCV
    Réponses: 3
    Dernier message: 03/07/2007, 16h44

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