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 :

Vecteur ou liste d'IplImages ?


Sujet :

OpenCV

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Par défaut Vecteur ou liste d'IplImages ?
    Bonjour,
    je fait un stage en analyse d'image, dans la reconnaiscance de visage, mon objectif est le devellopement d'une application de reconnaiscance de visage en c++ en utilisant la lib openCv et un classifieur svm. J'ai déja un prototype sous matlab qui fonctionne, et la je suis en train de migrer vers le c++.

    J'ai un problème avec la structure iplImage, je n'arrive pas a l utiliser dans un conteneur vector (ou list j'ai essayer aussi).
    Je m explique, pour pouvoir entrainer le classifieur je charge une base d'apprentissage en mémoire celle ci est constitué d image 30x30 de visages.
    J'ai donc pour l'instant 1 classe Personne qui contient une liste d'image le nom de la personne.... et des fonction de chargement (a l aide d un fichier liste) d'enregistrement ( création du répertoire, du fichier list contenant le path des images, et d'écriture des images.) je penser stocker ces images dans un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<IplImage*> maBase
    ou une liste.
    Et la problème, lorsque je veux enregistrer les images, je les extrait du vecteur et les réutiliser dans une fonction openCv, (que ca soit de l'affichage, sauvegarde, ou clonage) j'ai la meme erreur à l execution (la compile est ok, sans warning) :

    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
    OpenCV ERROR: Bad flag (parameter or structure field) (Unrecognized or unsupported array type)
            in function cvGetMat, cxarray.cpp(2881)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
            called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    voila mon code :
    Le point h :
    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
    using namespace std;
    	class Personne{
    		private:
    			string nom;
    			int nbrImages;	
    			list<IplImage*> listeVisage;
    			vector<IplImage*> test;
    			list<IplImage*> listeOptimisation;		
    			int paramC_svm;
    			int paramSigma_svm;
    		public:
    			Personne(string);		
    			~Personne();	
    			void ajouterVisage(IplImage*);
    			void supprimerVisage(int);
    			void chargerPersonne(string);
    			void enregistrePersonne(string);		
    			void projectionPersonne(vector<IplImage*>);		
    			void set_nom(string nom);
    			inline string get_nom(){ return this->nom;};		
    			void set_nbrImages(int);
    			int get_nbrImages();		
    			void set_paramC_svm(int);
    			int get_paramC_svm();		
    			void set_paramSigma_svm(int);
    			int get_paramSigma_svm();		
    			void set_test(vector< IplImage * > &   	 DImages);
    	};
    Le .cpp
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    using namespace std;
     
    Personne::Personne(string nomN){
    	this->nom=nomN;
    	this->nbrImages=0;	
     
    }
     
     
    // Foncteur servant à libérer un pointeur - applicable à n'importe quel type
    struct Delete { 
    	template <class T> void operator ()(T*& p) const{ 
    		delete p;
    		p = NULL;
    	} 
    };
     
    Personne::~Personne(){
    	//Destruction de la liste des images d apprentissage
    	for_each(this->listeVisage.begin(), this->listeVisage.end(), Delete()); 
    	this->listeVisage.clear();
    	//Destruction de la liste des images d optimisation
    	//delete this->listeOptimisation;
    	for_each(this->listeOptimisation.begin(), this->listeOptimisation.end(), Delete()); 
    	this->listeOptimisation.clear();
    }
     
     
    void Personne::chargerPersonne(string cheminBase){
    	cout << "--> Personne : chargerPersonne STARTING"<<endl;
    	char personneListFileName[512];
    	int varParc=0;	
    	//Nettoyage de l ancien vecteur de base
    	this->listeVisage.clear();
    	this->listeOptimisation.clear();
    	sprintf(personneListFileName,"%s/%s/base/%s.lst",cheminBase.c_str(),this->get_nom().c_str(),this->get_nom().c_str());
    	cout<<personneListFileName<<endl;
    	// le constructeur de ifstream permet d'ouvrir un fichier en lecture
    	ifstream fichier(personneListFileName);
    	if (fichier){ // ce test échoue si le fichier n'est pas ouvert
    		string ligne; // variable contenant chaque ligne lue
            	// cette boucle s'arrête dès qu'une erreur de lecture survient
    		while ( getline( fichier, ligne ) ){
    			varParc++;
    			IplImage* image = cvLoadImage( ligne.c_str(), 1 );
    			if (image){
    				this->test.push_back(image);
    				this->listeVisage.push_back(image);
    				cvReleaseImage( &image );
    			}
    			else{
    			}
    		}
    	}
    	else{
    		cout << "|WARNING|--> Personne : chargerPersonne\t:\t visage list file doesn't exist\n";
    	}
    	cout << "--> Personne : chargerPersonne\t:\t"<<varParc<<" visage charged\n";
    	cout << "--> Personne : chargerPersonne LEAVING"<<endl;
    }	
     
     
     
    void Personne::enregistrePersonne(string cheminBase){
    	cout << "--> Personne : enregistrePersonne STARTING"<<endl;
    	char personneListFileName[512];
    	char commandeCreatRep[512];
    	char visageFileName[512];
    	int varParc=0;
    	list<IplImage *>::iterator IlisteVisage;
    	list<IplImage *>::iterator IlisteOptimisation;			
    	sprintf(personneListFileName,"%s/%s/%s.lst",cheminBase.c_str(),this->get_nom().c_str(),this->get_nom().c_str());
    	sprintf(commandeCreatRep,"mkdir %s/%s",cheminBase.c_str(),this->get_nom().c_str());
    	system(commandeCreatRep);	
    	ofstream file(personneListFileName, ios_base::app );
    	cout << "--> Personne : enregistrePersonne \t:\t saving listeVisage in progress ..."<<endl;
     
     
    	for(list<IplImage *>::const_iterator iter = listeVisage.begin();iter != listeVisage.end();++iter)
    	{
    		cout<<varParc<<endl;
    		sprintf(visageFileName,"%s/%s/%s_%d.jpg",cheminBase.c_str(),this->get_nom().c_str(),this->get_nom().c_str(),varParc);
    		file <<visageFileName<<endl;
    		varParc++;
    		IplImage* image = test[varParc];
    		cvSaveImage(visageFileName,image);
    		//IplImage *pTemp = cvCloneImage(test[1]);
    		cvReleaseImage( &image );
    	}
     
    	cout<<this->listeVisage.size()<<endl;
     
    	for(this->listeVisage.begin(); IlisteVisage!=this->listeVisage.end(); IlisteVisage++){
    		cout<<varParc<<endl;
    		//sprintf(visageFileName,"%s/%s/%s_%d.jpg",cheminBase.c_str(),this->get_nom().c_str(),this->get_nom().c_str(),varParc);
    		//file <<visageFileName<<endl;
    		//cvSaveImage(visageFileName,*IlisteVisage);
    		varParc++;
    	}
    	for(this->listeOptimisation.begin(); IlisteOptimisation!=this->listeOptimisation.end(); IlisteOptimisation++){
    		sprintf(visageFileName,"%s/%s/%s_%d.jpg",cheminBase.c_str(),this->get_nom().c_str(),this->get_nom().c_str(),varParc);
    		file <<visageFileName<<endl;
    		//cvSaveImage(visageFileName,(* IlisteOptimisation));
    		varParc++;
    	}
    	cout << "|REPORT|--> Personne : enregistrePersonne \t:\t"<<varParc<<" visage saved\n";
    	cout << "--> Personne : enregistrePersonne LEAVING"<<endl;
    }
     
    int main(int argc, char *argv[])
    {
      Personne* alex=new Personne("alex");
      alex->chargerPersonne("/home/taf/Devellopement/Matlab/DRVH_Matlab/base");
      //Jusque la pas d erreur
      alex->enregistrePersonne("/home/taf/Devellopement/testEcriture");
     
     
      return EXIT_SUCCESS;
    }
    Je précise que je suis débutant en c++, c la deuxième fois que j 'utilise la stl j'aimerais bien comprendre pourkoi il m est impossible de lire ces images, alors que je l'ai deja vu faire dans d'otre codes (google "vector<IplImage*>" j'ai chercher avant de poster, ca doit etre une connerie qq part mais je vois pas.
    Merci a tous ceux qui prendrons le temps d etudier le probleme ;-).

  2. #2
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Par défaut Reponse a moi-meme :-)
    Salut tlm !
    Première reponse :
    Quand on a des base de + de 1000 images il ne vaut mieux pas les stocker en mémoire comme je voulais le faire, je m'explique : dans mon cas les valeurs qui m'interresser était les résultat de la projection de chaque image par une technique d'ACP, donc stocker les images est inutile, je les charges réalise la projection et stocke le résultat dans un vecteur de flottant. plus simple et plus léger , Sinon, il n 'est pas possible d'utiliser un vector<IplImage> ou list<IplImage> directement il faut en passer par la définition d'un wrapper et aprés utiliser un vector<Image> ou list<Image>:
    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
     
    template<class T>Image{
      private:
        IplImage * imgp;
      public:
        Image(IplImage * img=0) {imgp=img;}
        ~Image(){imgp=0;}
        void operator=(IplImage * img) {imgp=img;}
        inline T* operator[](const int rowIndx){
          return ((T *)(imgp->imageData + rowIndx*imgp->widhtStep));}
    };
     
    typedef struct {
      unsigned char b,g,r;
    } RgbPixel;
     
    typedef struct {
      float b,g,r;
    } RgbPixelFloat;
     
    typedef Image<RgbPixel>  RgbImage;
    typedef Image<RgbPixelFloat> RgbImageFloat;
    typedef Image<unsigned char> BwImage;
    typedef Image<float> BwImageFloat;

  3. #3
    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 Rectification
    Salut,

    Le message est un peu vieux mais je tiens à rectifier les choses pour ceux qui comme moi ont passé du temps (ou qui veulent éviter d'en passer) sur les vector d'IplImage. Je viens de trouver qu'il est tout à fait possible d'utiliser un vector d'IplImage . Cependant, il faut a priori (je n'ai pas encore vraiment approfondi) passer par une image temporaire pour l'affichage avec cvShowImage (les autres fonctions OpenCV ont l'air de fonctionner allez savoir pourquoi ). Par exemple, ce code pour afficher les images d'une vidéo fonctionne bien chez moi:

    //Lecture du fichier vidéo
    input_video = cvCaptureFromFile("C:/temp/capture.avi");
    //Vecteur d'IplImage*
    std::vector<IplImage*> queue;
    IplImage* ImTemp;

    //nombre d'image dans la vidéo
    unsigned int FrameNumber = static_cast<unsigned int>(cvGetCaptureProperty(input_video, CV_CAP_PROP_FRAME_COUNT));

    for (unsigned int i=0; i<FrameNumber; i++)
    {
    //Choix de la ième image de la vidéo
    cvSetCaptureProperty( input_video,CV_CAP_PROP_POS_FRAMES, i);
    //Ajout au vecteur d'images de la ième image
    queue.push_back(cvQueryFrame(input_video));

    //Copie de l'image du vecteur dans un IplImage* "simple"
    ImTemp=cvCloneImage(queue[i]);

    //Affichage
    cvNamedWindow("Image de la video",1);
    cvShowImage("Image de la video",ImTemp);
    //Affichage image par image
    cvWaitKey( 0 );
    }

    J'espère que ça pourra servir à quelqu'un,

    A+

    Hunta

  4. #4
    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 Rectification de rectification
    Salut,

    Bon ben faudrait que je réfléchisse un peu plus avant de poster...
    Il est possible d'afficher directement les vecteur d'IplImages... mais il faut faire attention à ce qu'on met dans le vecteur ce que je n'ai pas fait .
    Bref ci-dessous un exemple qui me semble nettement plus propre :

    input_video = cvCaptureFromFile("C:/temp/capture.avi");

    unsigned int FrameNumber = static_cast<unsigned int>(cvGetCaptureProperty(input_video, CV_CAP_PROP_FRAME_COUNT));

    std::vector<IplImage*> queue;

    for (unsigned int i=0; i<FrameNumber; i++)
    {
    cvSetCaptureProperty( input_video,CV_CAP_PROP_POS_FRAMES, i);
    queue.push_back(cvCloneImage(cvQueryFrame(input_video)));
    }
    cvReleaseCapture(&input_video);

    for (unsigned int i=0; i<FrameNumber; i++)
    {
    cvNamedWindow("AFFICHAGE",1);
    cvShowImage("AFFICHAGE",queue[i]);
    cvWaitKey(0);
    }
    ...etc.

    C'est pas parfait mais ça fonctionne.

    ++
    Hunta

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

Discussions similaires

  1. Métrique comparaison vecteur ou liste
    Par bougnbie dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 06/05/2014, 14h33
  2. Réponses: 7
    Dernier message: 10/10/2007, 11h29
  3. Vecteur ou liste orienté objet?
    Par Vincent157 dans le forum C++
    Réponses: 4
    Dernier message: 03/07/2007, 14h49
  4. Vecteur d' IplImage
    Par Sixdeux dans le forum C++
    Réponses: 13
    Dernier message: 16/05/2007, 17h11
  5. Réponses: 10
    Dernier message: 19/09/2006, 03h15

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