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 :

Erreur de désallocation de mémoire


Sujet :

OpenCV

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 53
    Par défaut Erreur de désallocation de mémoire
    Bonjour,
    J'ai écrit un petit code qui me permet de lire une vidéo à partir d'un fichier et qui calcule la différence entre deux images qui se suivent. Mais ce programme présente un défaut énorme:il bouffe la mémoire. et donc, j'ai pensé à détruire les variables temporaires, mais j'obtiens un message d'erreur au moment de l'exécution(pas de problème au moment de la compilation): "Unknown error code -49(Deallocation error) ..."
    Voci mon code
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
     
    #include <iostream>
    #include <cv.h>
    #include <cxcore.h>
    #include <highgui.h>
    #include <cmath>
    using namespace std;
    double calcul(IplImage* ImTemp1, IplImage* ImTemp2);
    int main()
    {
       	CvCapture* input_video=NULL;
    	input_video = cvCaptureFromFile("video.avi");
    	int FrameNumber = static_cast<int> (cvGetCaptureProperty (input_video, CV_CAP_PROP_FRAME_COUNT));
    	printf("%d\n",FrameNumber);
     
    	IplImage* ImTemp1=NULL;
    	cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,0);
        ImTemp1=cvQueryFrame(input_video);
     
     
    	    for (int i=0;i<FrameNumber-1;i++)
            {
                double somme;
                IplImage* ImTemp2=NULL;
                cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,i+1);
                ImTemp2=cvQueryFrame(input_video);
                cvNamedWindow("F1",1);
                cvShowImage("F1",ImTemp2);
                cvWaitKey(1);
                ImTemp1=cvCloneImage(ImTemp2);
                cvReleaseImage(&ImTemp2);
                somme=calcul(ImTemp1,ImTemp2);
            }
     
        cvReleaseCapture(&input_video);
        return 0;
    }
    double calcul(IplImage* ImTemp1, IplImage* ImTemp2)
    {
        double res=(double)ImTemp1->width*(double)ImTemp1->height;
        CvScalar scalaire1;
        CvScalar scalaire2;
        double somme = 0;
        for (int x=0; x<ImTemp1->width; x++)
            {
                for (int y=0; y<ImTemp1->height; y++)
                {
                    scalaire1=cvGet2D(ImTemp1,y,x);
                    scalaire2=cvGet2D(ImTemp2,y,x);
                    somme = somme + std::abs((double)scalaire1.val[0]- (double)scalaire2.val[0]);
                }
            }
            return somme/res;
    }
    Si je met la ligne " cvReleaseImage(&ImTemp2);" en commentaire le programme marche bien je retrouve le problème de mémoire.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 53
    Par défaut
    J'ai trouvé l'erreur: c'est simple: il faut mettre la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    somme=calcul(ImTemp1,ImTemp2);
    avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ImTemp1=cvCloneImage(ImTemp2);
    Mais le problème maintenant est que la boucle ne boucle pas Il affiche la première image et il sort.

  3. #3
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut
    Pourquoi crées tu une nouvelle structure ImTemp2 dans le for?
    Tu pourrais la créé plutot avant le for, l'utiliser dans le for, et faire le release a la sortie du for...
    Pourquoi ça ne boucle plus par contre je ne sais pas, ta essayé un affichage au lieu d'une fenetre pour l'image traitée du for?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 53
    Par défaut
    Si je je crée ImTemp2 en dehors de la boucle, je ne résout pas le problème de mémoire. Le problème vient de cvCloneImage c'est pourquoi j'ai pensé à créer une variable temporaire à l'intérieur de la boucle et de la libérer à la fin. Mais la boucle ne fonctionne pas.
    En faite j'ai testé plusieurs combinaisons:
    si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //double somme=calcul(ImTemp1,ImTemp2);
    ImTemp1=cvCloneImage(ImTemp2);
    //cvReleaseImage(&ImTemp2);
    pb de mémoire
    si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //double somme=calcul(ImTemp1,ImTemp2);
    ImTemp1=cvCloneImage(ImTemp2);
    cvReleaseImage(&ImTemp2);
    pb de déallocation
    si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     double somme=calcul(ImTemp1,ImTemp2);
    ImTemp1=cvCloneImage(ImTemp2);
    //cvReleaseImage(&ImTemp2);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double somme=calcul(ImTemp1,ImTemp2);
     ImTemp1=cvCloneImage(ImTemp2);
     cvReleaseImage(&ImTemp2);
    la boucle ne fonctionne pas.

  5. #5
    Membre éprouvé Avatar de hunta_kirua
    Profil pro
    Inscrit en
    Février 2008
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 110
    Par défaut
    Bonjour,

    Il me semble (à vérifier) que cvQueryFrame sert uniquement de moyen pour accéder à la vidéo c'est-à-dire que l'IplImage* n'est pas vraiment créé, il ne faut donc pas le libérer par cvReleaseImage puisque le fichier vidéo le sera avec cvReleaseCapture et du coup (aussi à vérifier) cvSetCaptureProperty ne te donne qu'un "pointeur" sur la vidéo et sans cvCloneImage, tu dois avoir 2 fois la même image.

    Essaie 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    int main()
    {
       	CvCapture* input_video=NULL;
    	input_video = cvCaptureFromFile("video.avi");
    	int FrameNumber = static_cast<int> (cvGetCaptureProperty (input_video, CV_CAP_PROP_FRAME_COUNT));
    	printf("%d\n",FrameNumber);
     
    	IplImage* ImTemp1=NULL;
    	IplImage* ImTemp2=NULL;
     
    	    for (int i=0;i<FrameNumber-1;i++)
            {
                double somme;
    	    cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,i);
    	    ImTemp1=cvCloneImage(cvQueryFrame(input_video));
                cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,i+1);
                ImTemp2=cvCloneImage(cvQueryFrame(input_video));
                cvNamedWindow("F1",1);
                cvShowImage("F1",ImTemp2);
                cvWaitKey(1);
                somme=calcul(ImTemp1,ImTemp2);
     
    	    cvReleaseImage(&ImTemp1);
    	    cvReleaseImage(&ImTemp2);
            }
     
        cvReleaseCapture(&input_video);
        return 0;
    }
    Edit : pour limiter les accès au fichier, voir pour faire 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
    19
    20
    IplImage* ImTemp1=NULL;
    	IplImage* ImTemp2=NULL;
     
    	cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,0);
    	ImTemp1=cvCloneImage(cvQueryFrame(input_video));
     
    	    for (int i=0;i<FrameNumber-1;i++)
            {
                double somme;
     
                cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES,i+1);
                ImTemp2=cvCloneImage(cvQueryFrame(input_video));
                ...........
    		cvReleaseImage(&ImTemp1);
    		ImTemp1=ImTemp2;
     
            }
     
       cvReleaseImage(& ImTemp2);
        cvReleaseCapture(&input_video);
    A+,

    Hunta

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 53
    Par défaut
    Merci hunta_kirua
    C'est bon:
    En ajoutant cvCloneImage à cvQueryFrame j'arrive à résoudre les problèmes d'allocations et de mémoire
    Par contre, je comprend pas toujours à résoudre le pb de la boucle

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD11] Erreur de lecture emplacement mémoire
    Par roseau dans le forum WinDev
    Réponses: 1
    Dernier message: 02/05/2008, 22h53
  2. erreur d'allocation de mémoire?
    Par ulnar dans le forum C
    Réponses: 17
    Dernier message: 18/05/2007, 09h36
  3. désallocation de mémoire
    Par Tex-Twil dans le forum C
    Réponses: 12
    Dernier message: 19/10/2006, 10h09
  4. allocation/désallocation de mémoire
    Par kinta dans le forum C++
    Réponses: 2
    Dernier message: 10/02/2006, 09h52
  5. Désallocation de mémoire ...
    Par Mike888 dans le forum C
    Réponses: 9
    Dernier message: 18/01/2006, 10h42

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