Problème de comparaison.

Problème de comparaison. - C - Programmation

Marsh Posté le 01-02-2007 à 14:14:45    

Bien le bonjour.
 
Je suis en train de dévelloper une petite application de traitement d'image,
dans laquelle j'ai écrit cette ligne de code, qui crashe à l'éxécution
(le programme compile sans aucune erreur ni warning) :
 

Code :
  1. if(getPixel(source,i,j) == 255) {
  2. /*traitement*/
  3. }


 
Ce que je ne comprend pas, c'est que plus haut dans le code,
j'ai cette ligne qui fonctionne parfaitement:
 
 

Code :
  1. if(getPixel(source,i,j) == 0) {
  2. /*traitement*/
  3. }


 
J'ai aussi testé une comparaison avec 254 et 256, bilan : ligne fonctionnelle.
 
PS : La fonction getpixel renvoie un unsigned char.
 
Quelqu'un a une explication ? Merci d'avance.


Message édité par Evil_Ifrit le 01-02-2007 à 14:16:53

---------------
Soon.
Reply

Marsh Posté le 01-02-2007 à 14:14:45   

Reply

Marsh Posté le 01-02-2007 à 14:20:13    

Mince ! http://forum-images.hardware.fr/icones/message/icon9.gif


Message édité par Elmoricq le 01-02-2007 à 14:20:18
Reply

Marsh Posté le 01-02-2007 à 14:20:37    

ce qui est important, c'est pas la valeur (255 ou 0) à laquelle tu compares le résultat, mais plutôt les valeurs de i et j. Il faut t'assurer que i et j ne dépassent pas les tailles max allouées pour les données de ton image (variable 'source', je suppose).
 
Je ne peux pas t'en dire plus sans avoir un peu de contexte. En particulier, d'où viennent i et j, et surtout comment a été alloué 'source' (et accessoirement, le code de getPixel serait peut-être utile)


---------------
TriScale innov
Reply

Marsh Posté le 01-02-2007 à 14:23:29    

Les variable i et j sont peut-être hors des limites du bitmap, ce qui peut arriver sur l'on inverse la colonne avec la ligne, ou si l'on croit que le bitmap courvre tous l'écran au lieu de ne couvrir qu'une portion de l'écran

Reply

Marsh Posté le 01-02-2007 à 14:28:44    

En fait j'ai créé ces deux fonctions aux codes quasi-identiques (mis à part la fameuse comparaison),
la preuve en code (désolé pour la longueur) :
 

Code :
  1. void Dilatation(tImage *source, tImage *res) {
  2.      int i, j, val;
  3.      tHistogramme histo;
  4.    
  5.      res->dimX = source->dimX;
  6.      res->dimY = source->dimY;
  7.      res->buffer = (unsigned char*)malloc((res->dimX)*(res->dimY)*sizeof(char));
  8.    
  9.      for ( i=1 ; i < res->dimX ; i++ ) {
  10.          for( j=1 ; j < res->dimY ; j++ ) {
  11.              if(getPixel(source,i,j) == 0) {
  12.                 setPixel(res, i-1, j, 0);
  13.                 setPixel(res, i, j-1, 0);
  14.                 setPixel(res, i, j, 0);
  15.                 setPixel(res, i, j+1, 0);
  16.                 setPixel(res, i+1, j, 0);
  17.              }
  18.              else
  19.                 setPixel(res, i, j,getPixel(source,i,j));     
  20.          }
  21.      }
  22.    
  23.      DessineImageGris(IMAGE_TRAITEE, res);
  24.      ConstruitHistogramme(res, &histo);
  25.      DessineHistogramme(HISTOGRAMME_IMAGE_TRAITEE, &histo);
  26.    
  27.      free(res->buffer);
  28. }
  29. void Erosion(tImage *source, tImage *res) {
  30.    
  31.      int i, j, val;
  32.      tHistogramme histo;
  33.    
  34.      res->dimX = source->dimX;
  35.      res->dimY = source->dimY;
  36.      res->buffer = (unsigned char*)malloc((res->dimX)*(res->dimY)*sizeof(char));
  37.    
  38.      for ( i=1 ; i < res->dimX ; i++ ) {
  39.          for( j=1 ; j < res->dimY ; j++ ) {
  40.              if(getPixel(source,i,j) == 255) {
  41.                 setPixel(res, i-1, j, 255);
  42.                 setPixel(res, i, j-1, 255);
  43.                 setPixel(res, i, j, 255);
  44.                 setPixel(res, i, j+1, 255);
  45.                 setPixel(res, i+1, j, 255);
  46.              }
  47.              else
  48.                 setPixel(res, i, j,getPixel(source,i,j));     
  49.          }
  50.      }
  51.    
  52.      DessineImageGris(IMAGE_TRAITEE, res);
  53.      ConstruitHistogramme(res, &histo);
  54.      DessineHistogramme(HISTOGRAMME_IMAGE_TRAITEE, &histo);
  55.    
  56.      free(res->buffer);
  57. }


Sur la même image, la fonction dilatation marche, et érosion crashe.
Je suis sûr à 100% que l'erreur ne vient pas des fonctions appelées (DessineImageGris & Cie),
Donc je ne pense pas non plus que l'erreur vienne des variables i et j passant hors limite.
 
D'autres idées ? :]
 
PS : Au cas où, le code de getpixel :
 

Code :
  1. unsigned char getPixel(tImage *img, int x, int y) {
  2.     return (*(img->buffer + (y*img->dimX)+x));

Message cité 1 fois
Message édité par Evil_Ifrit le 01-02-2007 à 14:32:13

---------------
Soon.
Reply

Marsh Posté le 01-02-2007 à 14:37:55    

Code :
  1. for ( i=1 ; i < res->dimX ; i++ ) {
  2.             for( j=1 ; j < res->dimY ; j++ ) {


Je pense qu'il faut plutôt mettre

Code :
  1. for ( i=1 ; i < res->dimX-1 ; i++ ) {
  2.             for( j=1 ; j < res->dimY-1 ; j++ ) {


 
Comme ça les indices que tu utilises dans tes traitements (i-1,i+1,j-1,j+1) restent toujours dans les limites allouées : [0;dimX] et [0;dimY]


---------------
TriScale innov
Reply

Marsh Posté le 01-02-2007 à 14:40:01    

A priori rien à voir avec ton bug, mais après les malloc() (dont le cast est inutile d'ailleurs), tu devrais vérifier que l'allocation s'est bien effectuée.
Pour le cas où, histoire de ne pas taper dans un res->buffer qui contiendrait NULL.

Reply

Marsh Posté le 01-02-2007 à 14:43:03    

Aw yeah, la solution de francesco marche :]
Comme quoi les erreurs ne sont pas tout le temps là où on les attend.
Erreur toute nulle en plus ^^
 
Merci beaucoup à tous (et spécialement à francesco).

Message cité 1 fois
Message édité par Evil_Ifrit le 01-02-2007 à 14:44:50
Reply

Marsh Posté le 01-02-2007 à 14:47:20    

Evil_Ifrit a écrit :

Aw yeah, ça marche :]
Comme quoi les erreurs ne sont pas tout le temps là où on les attend.
Erreur toute nulle en plus ^^


Les erreurs ne sont jamais où on les attend :o
 
C'est pas une erreur si nulle que ça : c'est sûrement le type d'erreur le plus rencontré en C. Tu peux aussi apprendre à utiliser un debugger, ce qui te permettrait de localiser beaucoup plus rapidement et précisément l'origine des problèmes.


---------------
TriScale innov
Reply

Marsh Posté le 10-02-2007 à 13:22:34    

Evil_Ifrit a écrit :

En fait j'ai créé ces deux fonctions aux codes quasi-identiques (mis à part la fameuse comparaison),

Code :
  1. void Dilatation(tImage *source, tImage *res) {
  2.      int i, j, val;
  3.      tHistogramme histo;
  4.    
  5.      res->dimX = source->dimX;
  6.      res->dimY = source->dimY;




T'as rien dilaté du tout...

Code :
  1. res->dimX = source->dimX + 2;
  2.      res->dimY = source->dimY + 2;


ou un truc comme ça...

 

Le tableau est donc trop petit. Comportement indéfini.

 

Toujours vérifier ses indices. assert() peut aider...

 

Message cité 1 fois
Message édité par Emmanuel Delahaye le 10-02-2007 à 13:24:47

---------------
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 10-02-2007 à 13:22:34   

Reply

Marsh Posté le 27-05-2007 à 18:55:23    

Emmanuel Delahaye a écrit :

T'as rien dilaté du tout...

Code :
  1. res->dimX = source->dimX + 2;
  2.      res->dimY = source->dimY + 2;


ou un truc comme ça...
 
Le tableau est donc trop petit. Comportement indéfini.
 
Toujours vérifier ses indices. assert() peut aider...


 
Je tenais à garder la taille de l'image de base,
la dilatation ne devait s'appliquer que sur les formes contenues dans l'image.
 
De plus, je n'applique pas l'algorithme de dilatation sur les pixels situés 'au bord' de l'image.
La tableau n'est donc pas trop petit, et le comportement défini.
 
Cordialement.

Reply

Sujets relatifs:

Leave a Replay

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