Image->matrice->Copie Image (pgm)

Image->matrice->Copie Image (pgm) - C - Programmation

Marsh Posté le 18-03-2005 à 22:56:01    

Bonjour,
j'ai essayé de copier une image *.pgm dans une matrice puis de relire la matrice pour crréer une copie :
j'ai récupéré les dimentions de l'image dans l'entête, j'ai alloué une matrice et fait une boucle pour copier l'iamge dedans, puis j'ai relu la mat en faisant un fprintf et quand je regarde la copie, elle fait le meme poids que l'otiginal mais seul le quart superieur a été recopié et il s'est arrété au milieu d'une ligne, le reste est gris :| (sans plantage)
 
Si quelqu'un a une idé de la provennance du probleme
(je n'ai pas le code ici mais je le posterai en rentrant lundi si besoin, de toute facon c'est que quelques lignes)


Message édité par dark86 le 20-03-2005 à 23:51:32
Reply

Marsh Posté le 18-03-2005 à 22:56:01   

Reply

Marsh Posté le 18-03-2005 à 22:57:32    

phoque !!  
ma boule de crystal est encore cassée :/


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 20-03-2005 à 10:43:12    

0) t'as specifie correctement tes parametres dans le fprintf ?
1)T'as des char dans les donnees d'origine et des int dans la matrice allouee ?
2) tu t'es plante dans ta boucle ?
3) poste ton code

Reply

Marsh Posté le 20-03-2005 à 11:22:38    

je parie qu'il ne lis pas toute les donnée...
pgm c'est une image couleur, donc il y a 3 char a lire pour un pixel...


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 20-03-2005 à 11:36:00    

pgm c'est niveaux de  gris, c'est pour ca que je l'ai pris^^
je vous poste le code ce soir en rentrant :D

Reply

Marsh Posté le 20-03-2005 à 11:38:01    

et non !
le nivreau de gris c'est ppm :o


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 20-03-2005 à 11:41:19    

KangOl a écrit :

et non !
le nivreau de gris c'est ppm :o


non, c'est l'inverse.


Message édité par skeye le 20-03-2005 à 11:41:38

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-03-2005 à 11:45:51    

enfin, l'extension on s'en fout un peu
l'important c'est que le fichier soit correct...


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 20-03-2005 à 11:51:00    

KangOl a écrit :

enfin, l'extension on s'en fout un peu
l'important c'est que le fichier soit correct...


Rattrapage aux branches detected...:o
 
Mais c'est sûr que sans code on va pas avancer des masses de toute manière...:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-03-2005 à 11:52:50    

oui, comme le chat : retombage sur mes pattes..


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 20-03-2005 à 11:52:50   

Reply

Marsh Posté le 20-03-2005 à 22:04:56    

comme promis :  

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <malloc.h>
  4. int main()
  5. {
  6. int n,m;
  7. int i,j;
  8. unsigned char ** image;
  9. char ligne[100];
  10. FILE* voiture;
  11. voiture=fopen("voiture.pgm","r" );
  12. if(voiture==NULL) {printf("ERROR" ); return(0);}
  13. for(i=0;i<2;i++)
  14. {
  15.  fgets(ligne,100,voiture);
  16.  printf("\n%s\n",ligne);
  17. }
  18. fscanf(voiture,"%d%d%d\n",&m,&n,&i);
  19. printf("nb ligne:%d\nnb col:%d\n%d\n",n,m,i);
  20. image=(unsigned char**) malloc(n*sizeof(unsigned char*));
  21. for(i=0;i<n;i++)
  22.  image[i]=(unsigned char*) malloc(m*sizeof(unsigned char));
  23. for(i=0;i<n;i++)
  24.  for(j=0;j<m;j++)
  25.   fscanf(voiture,"%c",image[i]+j);
  26. /*for(i=0;i<n;i++)
  27.  for(j=0;j<m;j++)
  28.   printf("%d",image[i][j]);
  29. */
  30. FILE* voiture2;
  31. voiture2=fopen("voiture2.pgm","wt" );
  32. if(voiture2==NULL) {printf("ERROR2" ); return(0);}
  33. fprintf(voiture2,"P5\n#Copy by dark86\n" );
  34. fprintf(voiture2,"%d %d\n255\n",m,n);
  35. for(i=0;i<n;i++)
  36.  for(j=0;j<m;j++)
  37.   fprintf(voiture2,"%c",image[i][j]);
  38. for(i=0;i<n;i++)
  39.  free(image[i]);
  40. free(image);
  41. fclose(voiture);
  42. fclose(voiture2);
  43. return(0);
  44. }


 
[edit]et voila les fichiers dde test : (pas affichables apparemment)
http://awoiselle.perso.egim-mrs.fr/visible/temp/voiture2.pgm
http://awoiselle.perso.egim-mrs.fr/visible/temp/voiture2.pgm


Message édité par dark86 le 20-03-2005 à 22:14:29
Reply

Marsh Posté le 21-03-2005 à 18:08:22    

y a plus personne???? :(

Reply

Marsh Posté le 21-03-2005 à 21:59:10    

Je ne vois pas, mais je trouve que tu te compliques la vie avec un tableau de pointeurs sur des tableaux.  
Vu que ton image est un rectangle, moi, je me contenterais d'un tableau à 1 dimension, quitte à faire une macro  
 
#define PIX(i, j) image[(i) * n + (j)]
 
pour accéder à un élément donné. C'est facile de définir des fonctions facilement sur la matrice ou une ligne ou une colonne donnée de la matrice, qui faciliteront la tâche par la suite.

Reply

Marsh Posté le 21-03-2005 à 22:10:51    

En cadeau une classe C++ que j'ai écrite et utilisée quand j'avais besoin de faire quelques petits calculs sur des matrices. C'est pas super optimisé mais suffisant pour des matrices jusqu'à 500x500.
 
(je sais, c'est du C++ et on est en cat C, mais on peut s'inspirer):

Code :
  1. #ifndef _CLASSE_Matrice_
  2. #define _CLASSE_Matrice_
  3. #include<vector>
  4. //#include<ostream>
  5. using namespace std;
  6. template <typename T>
  7. class Matrice
  8. {
  9. public:
  10.     /// constructeurs/destructeur
  11.     Matrice(const int l, const int c, const T val = 0):
  12.     _iL(l), _iC(c) {
  13. _v.resize(l * c, val);
  14.     }
  15.    
  16.     Matrice(const int l, const int c, const T* tab): _iL(l), _iC(c)
  17.     {
  18.        _v.resize(l * c);
  19.        for( int l = 0; l < _iL; l++ )
  20.             for( int c = 0; c < _iC; c++ )
  21.                  _v[ l*_iC + c ] = tab[ l*_iC + c ];
  22.     }
  23.     Matrice(const Matrice &rhs): _iL(rhs.getX()), _iC(rhs.getY())
  24.     {
  25.       _v.resize(_iL * _iC);
  26.       for( int l = 0; l < _iL; l++ )
  27.            for( int c = 0; c < _iC; c++ )
  28.                _v[ l*_iC + c ] = rhs(l, c);
  29.     }
  30.    
  31.     ~Matrice(){}
  32.     /// @brief accesseurs
  33.     inline T operator()(const int l, const int c) const {
  34. return _v[l * _iC + c];
  35.     }
  36.     inline T& operator()(const int l, const int c) {
  37. return _v[l * _iC + c];
  38.     }
  39.     inline T get(int x, int y) const {
  40.         return _v[ x * _iC + y ];
  41.     }
  42.     inline void set(int x, int y, T val) {
  43.         _v[ x * _iC + y ] = val;
  44.     }
  45.    
  46.     inline int getX() const { return _iL; }
  47.     inline int getY() const { return _iC; }
  48.     /// opérations sur la classe
  49.    
  50.     /// @brief operateur d'assignation
  51.     T& operator=(const T& rhs) {
  52.        if (&rhs != this) {
  53.             if(rhs.getX() != _iL || rhs.getY() != _iC)
  54.                  // très inefficace:  
  55.                  // il faudrait recopier directement le vecteur
  56.                  for(int l = 0; l < _iL; ++l)
  57.                      for(int c = 0; c < _iC; ++c)
  58.                         _v[l * _iC + c] = rhs(l, c);
  59.             else return NULL;
  60.        }
  61.        return (*this);
  62.     }
  63.    
  64.     /// @brief remplit la table avec la valeur val
  65.     inline int remplit(const T& val) {
  66.         int nbelem(_iL * _iC);
  67.         _v.assign(nbelem, val);
  68.         return nbelem;
  69.     }
  70.     /// @brief applique la fonction f(arg) aux éléments de la table     
  71.     template<typename ret> void applique(ret (*f)(T)) {
  72.          typename vector<T>::iterator it = _v.begin();
  73.          while(it != _v.end()) {
  74.               *it = (*f)(*it);
  75.               ++it;
  76.          }
  77.     }
  78.     /// @brief applique la fonction f(arg1, arg2) aux éléments de la table  
  79.     /// arg2 doit être du type exact demandé par la fonction f,  
  80.     ///aucune conversion implicite n'étant possible
  81.     template<typename ret, typename A>
  82.     void applique(ret (*f)(T, A), A arg2) {
  83.          typename vector<T>::iterator it = _v.begin();
  84.          while(it != _v.end()) {
  85.              *it = (*f)(*it, arg2);
  86.              ++it;
  87.          }
  88.     }
  89.     //friend ostream& operator<<(ostream& os, Matrice<T>& mat) const {;}
  90. protected:
  91.     int _iL, _iC; // lignes, colonnes
  92.     vector<T> _v;      // notre structure d'accueil
  93. };
  94. #endif


 
Et un exemple d'utilisation

Code :
  1. #include <cmath>
  2. #include <iostream>
  3. #include <ostream>
  4. #include "Matrice.h"
  5. using namespace std;
  6. typedef Matrice<double> Matdbl;
  7. /// Impression d'une matrice
  8. ostream& operator<<(ostream& os, Matdbl & mat) {
  9. int L = mat.getL(), C = mat.getC();
  10. for(int l = 0; l < L; ++l) {
  11.  os << "[ ";
  12.  for(int c = 0; c < C; ++c)
  13.   os << mat(l, c) << '\t';
  14.  os << "]" << endl;
  15. }
  16. }
  17. double f1(double x){ return sqrt(fabs(x)); }
  18. double f2(double x, int i){ return (x * i); }
  19. int main(int argc, char* argv[])
  20. {
  21. cout << "Matrice d'origine\n" << endl;
  22. Matdbl M(7, 7);
  23. Matdbl N(7, 7);
  24. cout << "fill" << endl;//M;
  25. M.fill(-1.);
  26. cout << "Divers acces en lecture/ecriture" << endl;
  27. for(short i = 1; i < M.getX(); i++) M(i, 0) = i;
  28. for(short j = 1; j < M.getY(); j++) M(0, j) = j;
  29. for(short j = 0; j < M.getY(); j++) M(j, j) = 1.;
  30. cout << "Une recopie" << endl;
  31. N = M;
  32. cout << "M =\n" << M;
  33. cout << "N =\n" << N;
  34. M.applique(&f1);
  35. cout << "sqrt(fabs(elem)) = \n" << M;
  36. M.applique(&f2, 2);
  37. cout << "M x 2 = \n" << M;
  38. return 0;
  39. }


Message édité par el muchacho le 21-03-2005 à 22:47:02
Reply

Marsh Posté le 21-03-2005 à 22:20:22    

el muchacho a écrit :

Je ne vois pas, mais je trouve que tu te compliques la vie avec un tableau de pointeurs sur des tableaux.  
#define PIX(i, j) image[(i) * n + (j)]


pourquoi pas, mais je suis habitué aux matrices^^ :whistle:  
enfin ce n'est qu'un detail de notation, et ca ne résoudra pas mon prebleme :s
 
pour le C++, je n'y connais absolument rien :/
 
sinon, je me demandais si le probleme ne pouvait pas venir de la confusion char/unsigned_char (%c), mais le haut de l'image est parfaitement restitué donc je pense pas que ce soit ca... :(  
 
une idée??  :??:

Reply

Marsh Posté le 21-03-2005 à 22:24:33    

dark86 a écrit :

pourquoi pas, mais je suis habitué aux matrices^^ :whistle:  
enfin ce n'est qu'un detail de notation, et ca ne résoudra pas mon prebleme :s


Si parce que le code est trivial. Tu ne t'embêtes pas avec les pointeurs et les allocs. Tu as un seul tableau et un seul pointeur à gérer.


Message édité par el muchacho le 21-03-2005 à 22:28:54
Reply

Marsh Posté le 21-03-2005 à 22:45:32    

On dirait que ton programme est censé gérer des fichier .pgm ayant pour "magic number" : "P2" or ton fichier a pour "magic number" : "P5" autrement dit à la place de gérer un ficher ASCII il faudrait gérer un fichier binaire.
 
http://www.cs.ubc.ca/spider/ladic/text/pgm.txt

Reply

Marsh Posté le 22-03-2005 à 15:35:40    

Heu, je viens de verifier, le fichier original est bien un "P5" et celui que j'ai créé par copie est aussi un P5, alors je ne vois pas où est le problème....
et en quoi mon prog gèrerait les P2 plutôt que les P5?? un problème avec les Char/unsignedChar?

Reply

Marsh Posté le 22-03-2005 à 20:54:57    

Déjà tu ouvres ton fichier en ASCII, ensuite tu n'utilises que des fonctions gérant des chaînes de caractères (fscanf, fprintf)...
 
Enfin bref y a beaucoup de choses qu'il faudrait modifier.

Reply

Marsh Posté le 22-03-2005 à 22:51:24    

Tarabiscote a écrit :

Déjà tu ouvres ton fichier en ASCII,  
je débute en C, je ne connais que l'ouverture en texte ou binaire et j'avais testé en binaire sans qu'il n'y ait le moindre changement...que dois-je faire?
ensuite tu n'utilises que des fonctions gérant des chaînes de caractères (fscanf, fprintf)...
où est le probleme? on m'avait dit (prof) que c'était des unsigned_char les données de l'image....
Enfin bref y a beaucoup de choses qu'il faudrait modifier.


expliquez moi, je suis tout ouï :D
je ne sais pas si vous avez regardé le fichier voiture2 de sortie mais le début est parfaitement recopié, c'est ça le plus étrange...

Reply

Marsh Posté le 23-03-2005 à 19:22:20    

Ben en fait le problème de l'ouverture en ASCII, c'est que comme tu n'es pas sous linux apparemment les \n sont précédé d'un \r.
 
Ensuite avec les fonction fscanf, fprintf dès qu'il tombera sur le caractère nul (ce qui peut arriver en binaire), il s'arrêtera.
 
Je te conseille de regarder plutôt du coté de fread et fwrite.

Reply

Marsh Posté le 23-03-2005 à 20:34:20    

Tarabiscote a écrit :

Ben en fait le problème de l'ouverture en ASCII,


??? Tu veux dire en mode texte ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 23-03-2005 à 20:40:02    

Euh oui, petit abus de langage désolé...

Reply

Marsh Posté le 23-03-2005 à 20:46:24    

Le truc sur les caracteres nuls correspondrait aux symptômes, je vais voir ce que je peux y faire...

Reply

Marsh Posté le 24-03-2005 à 18:18:27    

j'ai dit n'importe quoi hier : ma boucle ne fait aucun test, elle ne s'arrêtera pas, meme avec un caractère nul, donc c'est autre chose le problème :(

Reply

Marsh Posté le 24-03-2005 à 22:41:18    

Quelle boucle ?
T'as commencé à corriger ?
 
Bon je t'aide pour la lecture de tête je dirait qu'il faut remplacer :
for(i=0;i<n;i++)  
        for(j=0;j<m;j++)  
            fscanf(voiture,"%c",image[i]+j);
 
par :
for(i=0;i<n;i++)
  fread (image[i], sizeof(char), m, voiture);
 
voire même :
fread (image, sizeof(char), n*m, voiture);
en ne faisant qu'un malloc de n*m si le but est juste de copier l'image.
 
Bon je fait pas tous les testes qu'il serait mieux de faire mais ça donne déjà l'idée.

Reply

Marsh Posté le 24-03-2005 à 22:50:56    

Tarabiscote a écrit :


for(i=0;i<n;i++)
  fread (image[i], sizeof(char), m, voiture);


voire même :

fread (image, sizeof(char), n*m, voiture);




Attention. Toute fonction de lecture peut détecter une fin de fichier. Il faut donc tester le code retour et agir en conséquence.


Message édité par Emmanuel Delahaye le 24-03-2005 à 22:51:48

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 24-03-2005 à 23:05:45    

J'ai dit que c'était juste pour donner l'idée et si le fichier n'est pas endommagé la taille indiquée au début devrait être correcte.
 
Mais bon aller autant rajouter les teste puisqu’on y est, je me lance :

Code :
  1. if  (fread (image, sizeof(char), n*m, voiture) != n*m)
  2. {
  3.   if(feof(voiture))
  4.   {
  5.     printf("Fin du fichier prématuré !\n" ) ;
  6.     return -1 ;
  7.   }
  8.   else
  9.   {
  10.     printf("Erreur d’écriture !\n" ) ;
  11.     return ferror(voiture) ;
  12.   }
  13. }


Vous pouvez me dire si j’en ai oublié :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed