Précédent   Forum des professionnels en informatique > C et C++ > C++
C++ Forum d'entraide technique sur le langage C++. Avant de poster -> F.A.Q C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/02/2012, 19h57   #1
Candidat au titre de Membre du Club
 
Homme
Étudiant
Inscription : juin 2011
Messages : 57
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : juin 2011
Messages : 57
Points : 11
Points : 11
Par défaut OpenCV: Convertion IplImage to Mat

Alors voilà, mon problème est tout simple:

Je souhaite convertir une séquence d'images au format IplImage vers le format Mat.
Pour convertir une seule image, pas de problème, cela se lance correctement:

Code :
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
 
 
IplImage * img2[579];
IplImage * img3[579];
 
 
	// charge the list of images to studye	
	for (int k=0; k<579; k++)
    {
	  stringstream ss;
 
	  if(k<10)
	  {
		  ss << "lc-0000" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	  else if((k>9)&&(k<100))
	  {
		  ss << "lc-000" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	  else
	  {
		  ss << "lc-00" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	}
 
        Mat imgMat3(img2[0]); 
	Mat imgMat212(img2[12]); 
 
        Mat imgMat2(img2[2]); // cette ligne marche
Par contre, si je passe dans une boucle, ça plante lors du lancement:

Code :
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
 
 
 
IplImage * img2[579];
IplImage * img3[579];
 
 
	// charge the list of images to studye	
	for (int k=0; k<579; k++)
    {
	  stringstream ss;
 
	  if(k<10)
	  {
		  ss << "lc-0000" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	  else if((k>9)&&(k<100))
	  {
		  ss << "lc-000" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	  else
	  {
		  ss << "lc-00" << k+1 << ".png";
		  img2[k] = cvLoadImage(ss.str().c_str());  
	  }
	}
 
        Mat imgMat3(img2[0]); 
	Mat imgMat212(img2[12]); 
 
// Cette boucle ne marche pas. En fait, ce que je veux faire, c'est soustraire chaque img2[h] avec la img2[12], la douzième et la mettre dans img3[h]. Le problème c'est qu'il faut convertir en Matrice Mat. 
 
	for(int h=0; h<579; h++)
	{
		Mat imgMat2(img2[h]); // c'est cette ligne qui plante je crois
		absdiff(imgMat2, imgMat212, imgMat3);
		img3[h] = &(IplImage(imgMat3));
	}
img2[] et img3[] étant des tableaux de IplImages.

Comment faire?

Mayday viens du français "venez m'aider !!" les anglais l'ont alors déformé en "mayday" (pour la petite histoire )
wilfryjules est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 00h14   #2
Membre éclairé
 
Inscription : décembre 2008
Messages : 236
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 236
Points : 315
Points : 315
Est-ce que img2 et img3 sont bien alloués à la bonne taille (579) ?

D'où sort imgMat3 ?
S'il est déclaré avant la boucle, son contenu sera écrasé à chaque itération.
S'il est déclaré dans la boucle, son contenu sera détruit après chaque itération.
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 11h04   #3
Candidat au titre de Membre du Club
 
Homme
Étudiant
Inscription : juin 2011
Messages : 57
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : juin 2011
Messages : 57
Points : 11
Points : 11
Merci d'avoir répondu,

il est vrai que ce n'était pas très clair, j'ai donc réécrit mon code.

De plus ce la plante dans les 2 cas, que imgMat3:
- soit déclaré dans la boucle,
- ou en dehors
wilfryjules est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 11h26   #4
Membre éprouvé
 
Homme
Chercheur en informatique
Inscription : avril 2008
Messages : 272
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Royaume-Uni

Informations professionnelles :
Activité : Chercheur en informatique

Informations forums :
Inscription : avril 2008
Messages : 272
Points : 451
Points : 451
Mais pourquoi tu charges tes images en IplImage (interface C d'OpenCV) pour ensuite les convertir en cv::Mat (interface C++) ? Restes sur des cv::Mat, ça t’éviteras un paquet d'erreur de mémoire et d'oublis de désallocation.
math_lab est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 11h28   #5
Membre éclairé
 
Inscription : décembre 2008
Messages : 236
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 236
Points : 315
Points : 315
Remarque préalable.
Comme je l'ai dit sur une autre discussion, tu devrais formater ta variable k :
Code :
1
2
3
4
#include <iomanip>
using namespace std;
 
ss << "file-" << setfill('0') << setw(4) << k << ".jpg";
Ce qui affichera la chose suivante :
Code :
1
2
3
4
5
file-0000.jpg (k=0)
file-0002.jpg (k=2)
file-0017.jpg (k=17)
file-1458.jpg (k=1458)
setw(N) affichera k sur N chiffres dans ton nom de fichier.
Si besoin est, setfill(X) comblera les caractères manquants par des X (ici des zéros mais ç'aurait pu être des '*' ou des espaces).

--

Quant à ton problème, là encore je t'avais conseillé de ne pas mélanger API C et API C++ d'OpenCV... Tu ne devrais pas recaster tes IplImage* en cv::Mat. Utilise cvAbsDiff (au lieu de cv::absdiff, note la différence) sur tes IplImage* et ça devrait mieux se dérouler.
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 13h11   #6
Candidat au titre de Membre du Club
 
Homme
Étudiant
Inscription : juin 2011
Messages : 57
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : juin 2011
Messages : 57
Points : 11
Points : 11
Merci pour l'information, je viens de le faire, mais j'ai toujours un problème avec absdiff qui plante. Ce compilateur, visual studio, n'est pas très performant, il pourrait trouver les erreurs avant la compilation au lieu de planter après sens arrêts!! je préfère netbeans en java, enfin, voici le code:


Code :
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
 
 
 
 
int main()
{
 
 
	// create a RGB colour image (set it to a black background)
	Mat img = Mat::zeros(480, 704, CV_8UC3);
 
	// create a list of images to study
	Mat img2[579];
        Mat img3[579];
 
 
 
	// charge the list of images to studye	
	for (int k=0; k<579; k++)
    {
	  stringstream ss;
 
	  if(k<10)
	  {
		  ss << "lc-0000" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	  else if((k>9)&&(k<100))
	  {
		  ss << "lc-000" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	  else
	  {
		  ss << "lc-00" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	}
 
 
 
 
	 for(int h=0; h<579; h++)
	 {
	  	absdiff(img2[h], img2[12], img3[h]);  // PLANTE
	 }
 
 
	namedWindow("photo", CV_WINDOW_AUTOSIZE);		
	imshow("photo",  img2[0]);
 
	waitKey(0);
 
        return 0;
}
wilfryjules est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 15h04   #7
Membre éclairé
 
Inscription : décembre 2008
Messages : 236
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 236
Points : 315
Points : 315
Un petit tour du côté de la doc :
http://opencv.itseez.com/modules/cor...s.html#absdiff

Est-ce que img3[k] a la même dimension que img2[k] au moment d'appeler absdiff ?
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 15h25   #8
Candidat au titre de Membre du Club
 
Homme
Étudiant
Inscription : juin 2011
Messages : 57
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : juin 2011
Messages : 57
Points : 11
Points : 11
Merci Cob, oui mon prof m'a aussi dit de ne pas mélanger c et c++, et oui, même en initialisant img3[] avec le contenu de img2[], ça plante.

Ce qui est pénible, c'est qu'il ne marque pas d'erreur dans le code.

voici ensuite le message d'erreur:

Exception non gérée à 0x75819673 (KernelBase.dll) dans IA_Assignment.exe*: Exception Microsoft C++*: cv::Exception à l'emplacement mémoire 0x002fee98..


Code :
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
 
 
 
 
 
 
int main()
{
 
 
	// create a RGB colour image (set it to a black background)
	Mat img = Mat::zeros(480, 704, CV_8UC3);
 
	// create a list of images to study
	Mat img2[579];
        Mat img3[579];
 
 
 
	// charge the list of images to studye	
	for (int k=0; k<579; k++)
    {
	  stringstream ss;
 
	  if(k<10)
	  {
		  ss << "lc-0000" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	  else if((k>9)&&(k<100))
	  {
		  ss << "lc-000" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	  else
	  {
		  ss << "lc-00" << k+1 << ".png";
		  img2[k] = imread(ss.str().c_str(), CV_LOAD_IMAGE_COLOR);  
	  }
	}
 
 
          for(int i=0; i<579; i++)
	 {
		 img3[i] = img2[i].clone();
	 }
 
 
 
	 for(int h=0; h<579; h++)
	 {
	  	absdiff(img2[h], img2[12], img3[h]);  // PLANTE
	 }
 
 
	namedWindow("photo", CV_WINDOW_AUTOSIZE);		
	imshow("photo",  img2[0]);
 
	waitKey(0);
 
        return 0;
}
merci !
wilfryjules est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 15h48   #9
Membre éclairé
 
Inscription : décembre 2008
Messages : 236
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 236
Points : 315
Points : 315
Avant d'appeler absdiff, essaie d'afficher la taille de ses paramètres, tu auras peut-être des surprises. Peut-être qu'un ou plusieurs fichiers n'ont pas pu être lus par imread, ce qui produit une matrice vide, ou que ces images n'ont pas toutes les mêmes dimensions.
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 16h55   #10
Candidat au titre de Membre du Club
 
Homme
Étudiant
Inscription : juin 2011
Messages : 57
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : juin 2011
Messages : 57
Points : 11
Points : 11
Bon, alors j'ai réussi, merci cob !! c'était la dimension l'erreur, pourtant mon prof me dit qu'elles sont toutes de la même dimension.

Aussi, j'ai également modifié la manière de charger la liste d'images.

Mais il faut alors lancer le code dans la console, et entrer en paramètre l'endroit ou les endroits où se trouvent les fichiers images.


Code :
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
 
 
 
#include <cv.h>   		// open cv general include file
#include <highgui.h>	// open cv GUI include file
#include <iostream>		// standard C++ I/O
#include <stdlib.h>
#include <ctime>
#include <iomanip>
#include <stdlib.h>
//#include "surflib.h"
//#include "kmeans.h"
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace cv; // OpenCV API is in the C++ "cv" namespace
 
/******************************************************************************/
 
 
 
int main(int argc, char *argv[])
{
 
 
	// create a RGB colour image (set it to a black background)
	Mat img = Mat::zeros(480, 704, CV_8UC3);
 
	// create a list of images to study
	Mat img2[579];
        Mat img3[579];
 
 
 
	for(int i = 1; i < argc; i++)
    {
        printf("File %i : %s\n", i, argv[i]);
 
	img2[i] = imread(argv[i], CV_LOAD_IMAGE_COLOR);  
    }
 
 
 
 
	 for(int h=0; h<579; h++)
	 {
		 if( img2[h].size() == img2[12].size())
		 {
			absdiff(img2[h], img2[12], img3[h]);
		 }
 
	 }
 
 
 
	namedWindow("photo", CV_WINDOW_AUTOSIZE);		
	imshow("photo",  img3[19]);
 
	waitKey(0);
 
    return 0;
 
 
 
}
wilfryjules est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h44.


 
 
 
 
Partenaires

Hébergement Web