Segmentation Fault....en traitement d'image

psysta Messages postés 5 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 9 avril 2004 - 2 avril 2004 à 22:05
zamourse Messages postés 1 Date d'inscription jeudi 10 mars 2005 Statut Membre Dernière intervention 10 mars 2005 - 10 mars 2005 à 19:41
Bonjour,
je suis nouveau dans la programmation en C. J'ai un programme Matlab qui marche bien, et je souhaiterais l'implémenter en C. Le pgm compile bien, mais me sort un "segmentation fault" à l'exécution. Le pgm doit prendre une image en RAW data en entrée, lui appliquer un algo de tri, puis en ressortir une image modifiée, toujours en RAW.
Il doit y avoir un pb de pointeurs...mais où? Si vous pouviez m'aider, ca serait vraiment inespéré!
Merci par avance. :)
Psysta
[mailto:psysta2@hotmail.com @mail]

PS: le pgm a l'air long, mais en grande partie à cause des déclarations et initialisations.
----------------------------------------------------------------------
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define INT_TYPE unsigned int
#define IMAGE_TYPE unsigned char
#define DOUBLE_TYPE double

void fatal(s)
char *s;
{
printf("\n%s\n",s);
exit(-1);
}

FILE *fichier, *ouput;

IMAGE_TYPE **image, **newImage;

DOUBLE_TYPE *sumClustCol;

INT_TYPE *averageRowDist, *averageColDist, *averageCol, *colCent, *rowCent, *columnCent,
*whichColCent, **whichCent, **rowDistance, **columnDistance, *sumRowDistance,
*sumColDistance, *pixelsInClust, *colorOfCent;

int numClustCent=10, NBC=256, NBL=256;
int i, j, A, Q, O, P, I, J, k, K, N, M, R, S, X, Z, m1, m2, H, p=1,
whichColor,
currentRow,
currentColumn,
rowDist,
columnDist,
clustCent,
colCentOrder,
centerBelong;

double whichDistCent, totalDist;
long int taille;

main()
{ /* Entry variables */
averageRowDist = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));
averageColDist = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));
averageCol = (unsigned int*)calloc(numClustCent,sizeof(unsigned int));

for(i=0;i<numClustCent;i++)
{averageRowDist[i]=0;}
for(i=0;i<numClustCent;i++)
{averageColDist[i]=0;}
for(i=0;i<numClustCent;i++)
{averageCol[i]=0;}

colorOfCent = (unsigned int*)calloc(numClustCent,sizeof(unsigned int));
colCent = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));
rowCent = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));
columnCent = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));
whichColCent = (unsigned int*)calloc(numClustCent, sizeof(unsigned int));

whichCent = (unsigned int**)calloc(NBC, sizeof(unsigned int));
for (i=0;i<NBL;i++)
{ whichCent[i] = (unsigned int*)calloc(NBC,sizeof(unsigned int));}

rowDistance = (unsigned int**)calloc(NBC, sizeof(unsigned int));
for (i=0;i<NBL;i++)
{ rowDistance[i] = (unsigned int*)calloc(NBC,sizeof(unsigned int));}

columnDistance = (unsigned int**)calloc(NBC, sizeof(unsigned int));
for (i=0;i<NBL;i++)
{ columnDistance[i] = (unsigned int*)calloc(NBC,sizeof(unsigned int));}


/* Reading of the image file */

if((fichier=fopen("lenna.dat","rb"))==NULL)
{fatal("Can't open input file");}

fseek(fichier,0,SEEK_END);
taille = ftell(fichier);
fseek(fichier,0,SEEK_SET);
image = (unsigned char**)calloc(NBC,sizeof(unsigned char));
for (i=0;i<NBL;i++)
{ image[i] = (unsigned char*)calloc(NBC,sizeof(unsigned char));}

fread(image[i][j],1,taille,fichier);
fclose(fichier);

newImage = (unsigned char**)calloc(NBC,sizeof(unsigned char));
for (i=0;i<NBL;i++)
{ newImage[i] = (unsigned char*)calloc(NBC,sizeof(unsigned char));}

/* start of Kmean algorithm */
m1 = floor((double)NBL/numClustCent);
m2 = floor((double)NBC/numClustCent);

/* see where to put cluster centers initially */
for(H=0;H<numClustCent;H++)
{ rowCent[H]= floor(((double)H-1.0)*m1+m1/2.0);
columnCent[H] = floor(((double)H-1.0)*m2+m2/2.0);
colorOfCent[H] = (double)(image[rowCent[H]][columnCent[H]]);
}


do
{
if(p>1)
{
colorOfCent = averageCol;
rowCent = averageRowDist;
columnCent = averageColDist;
}
/* compare pixels by color and distance to determine what is cluster center for
it */
for(I=0;I<NBL;I++)
{
for(J=0;J<NBC;J++)
{
currentRow = I;
currentColumn = J;

/* compare with cluster centers */
for(K=0;K<numClustCent;K++)
{
/* compare with cluster centers for color */
clustCent = colorOfCent[K];
whichColor = abs((int)image[I][J]-clustCent);
colCent[K] = whichColor;

/* see if color centers are within treshold range */
if (whichColor>=30)
{whichColCent[K]=0;}
else {whichColCent[K]=1;}

/* list best color center */
if(K==1)
{colCentOrder=K;}
else if(colCent[K]<=colCent[colCentOrder])
{colCentOrder=K;}
}
colCentOrder=colCentOrder;

whichDistCent = sqrt(pow((double)NBL,2.0)+pow((double)NBC,2.0))+1.0;

/* compare with cluster center for distance */
for(M=0;M<numClustCent;M++)
{
/* check to see if something is within color threshold */
/* if not, then choose the closest color as cluster center */
for(k=0;k<numClustCent;k++)
{
if(whichColCent[k]!=0)
{N=1;}
else {N=0;}
}

if(N==1 || whichColCent[M]==1)
{
rowDist = abs(I-rowCent[M]);
columnDist = abs(J-columnCent[M]);
totalDist = sqrt(pow((double)rowDist,2.0)+pow((double)columnDist,2.0));
if(totalDist<=whichDistCent)
{
whichDistCent = totalDist;
whichCent[I][J] = M;
rowDistance[I][J] = rowDist;
columnDistance[I][J] = columnDist;
}
}
}
}
}
whichCent = whichCent;

/* replace cluster centers with the mean of the elements in their cluster */

/* initialization of data */
sumClustCol = (double*)calloc(numClustCent, sizeof(double));
sumRowDistance = (unsigned int*)calloc(numClustCent, sizeof(int));
sumColDistance = (unsigned int*)calloc(numClustCent, sizeof(int));
pixelsInClust = (unsigned int*)calloc(numClustCent, sizeof(int));

for(i=0;i<numClustCent;i++)
{sumClustCol[i]=0;}
for(i=0;i<numClustCent;i++)
{sumRowDistance[i]=0;}
for(i=0;i<numClustCent;i++)
{sumColDistance[i]=0;}
for(i=0;i<numClustCent;i++)
{pixelsInClust[i]=0;}


for(O=0;O<NBL;O++)
{ for(P=0;P<NBC;P++)
{ A = whichCent[O][P];
pixelsInClust[A] = pixelsInClust[A]+1;
sumClustCol[A] = sumClustCol[A]+(double)image[O][P];
sumRowDistance[A] = sumRowDistance[A]+rowDistance[O][P];
sumColDistance[A] = sumColDistance[A]+columnDistance[O][P];
}
}

for(i=0;i<numClustCent;i++)
{averageRowDist[i]=0;}
for(i=0;i<numClustCent;i++)
{averageColDist[i]=0;}
for(i=0;i<numClustCent;i++)
{averageCol[i]=0;}

for(Q=0;Q<numClustCent;Q++)
{ averageCol[Q] = (unsigned int)ceil(sumClustCol[Q]/(double)pixelsInClust[Q]);
averageColDist[Q] = (unsigned int)ceil(sumRowDistance[Q]/(double)pixelsInClust[Q]);
averageRowDist[Q] = (unsigned int)ceil(sumColDistance[Q]/(double)pixelsInClust[Q]);
}

p=p+1;

}while(rowCent!=averageRowDist && columnCent!=averageColDist &&
colorOfCent!=averageCol);

/* set all pixels that belong to a cluster to different colors */
for(R=0;R<NBL;R++)
{ for(S=0;S<NBL;S++)
{ centerBelong = whichCent[R][S];
newImage[R][S] = colorOfCent[centerBelong]*40;
}
}

/* output file generated */
ouput = fopen("sortie_kmean","wb");

if(ouput == NULL)
{ fatal("ouput file error");}
else {printf("fichier de sortie cree avec succes.");}

for(Z=0;Z<NBL;Z++)
{ for(X=0;X<NBC;X++)
{ fwrite(&newImage[Z][X],1,1,ouput);}
}
fclose(ouput);

}

9 réponses

progqt Messages postés 13 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 27 avril 2004
6 avril 2004 à 09:01
Le source est effectivement un peu long pour trouver ce qui ne va pas en le lisant. Voici néanmoins quelques techniques pour trouver la source du problème. Puisque tu fais référence à un "segmentation fault" je pense que tu es sans doute sous Linux ou Unix.
Afin de trouver l'endroit du programme qui "plante", le mieux est d'utiliser un debogeur tel que gdb. Donc tu lances dans un terminal : gdb nomprog
gdb va charger ton programme qu'il faut ensuite lancer par run.
Le programme va fonctionner normalement et s'arrêter lorsqu'il va planter. En tapant where, gdb va t'indiquer l'endroit et la cause du plantage.
PS : Il faut compiler le programme avec des options de debogage. Pour ce faire il faut rajouter -g dans les optiions du compilateur et du linkeur.

webmestre du site français dédié à la programmation QT.
http://prog.qt.free.fr
0
psysta Messages postés 5 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 9 avril 2004
6 avril 2004 à 23:55
Merci de ton aide. Je vais peut-être trouver la solution grâce à toi. :)
Je travaille effectivement sous Unix, Solaris. L'erreur provient du 1er fread.... je vais essayer de trouver ca. par contre, ayant repris les travaux de qqun, j'utilise gcc et gmake, au lieu de cc et make. Puis je modifier le compilateur et linkeur de même?
merci d'avance

Psysta
0
psysta Messages postés 5 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 9 avril 2004
7 avril 2004 à 00:57
au fait, en utilisant gdb, je tape run, puis where, mais il me donne comme réponse:
#0 0x11b98 in main()

Qu'est ce que ca veut dire??

Psysta
0
progqt Messages postés 13 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 27 avril 2004
7 avril 2004 à 12:00
Pour avoir accès au debogage de ton programme, il faut utiliser -g comme option de compilation :
gcc -g -o monprog monsource.c
va générer un exécutable nommé monprog en compilant monsource.c et en incluant dans l'exe ce qui est nécessaire pour degoguer.
Ensuite avec : gdb monprog, run puis where après le plantage tu devrais avoir plus de détails.
Pour remplacer cc par gcc, il faut je pense dans ton Makefile simplement changer chaque occurence de cc par gcc.

webmestre du site français dédié à la programmation QT.
http://prog.qt.free.fr
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
psysta Messages postés 5 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 9 avril 2004
7 avril 2004 à 22:01
Le debogeur fonctionne bien, mais je n'arrive pas a comprendre ce qu'il me dit...
il me donne comme réponse:
#0 0x11b98 in main()
comment puis je retrouver la ligne exact de l'erreur dans mon code?

Psysta
0
progqt Messages postés 13 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 27 avril 2004
7 avril 2004 à 23:37
gdb te donne #0 0x11b98 in main() sans plus de détail car tu n'a pas inclus les options de déboguage lors de la compilation.
Voici un petit exemple :
// toto.c
#include <stdio.h>

void f();

void main()
{
f();
}

void f()
{
int j;
int *i[100];
for(j=0; j<100; j++)
*i[j] = 12000;
}

Si je compile sans instruction de déboguage :
gcc -o toto toto.c
puis gdb toto
run
j'obtiens "Program received signal SIGSEGV, Segmentation fault."
0x080483365 in f ()
Gdb connait l'adresse du plantage mais ne peut afficher la ligne en cause.

Si je compile avec les instructions de déboguage :
gcc -g -o toto toto.c
puis gdb toto
run
j'obtiens "Program received signal SIGSEGV, Segmentation fault."
0x080483365 in f () at toto.c:15
15 *i[j] = 12000;
ici j'ai maintenant le ligne en cause.

Pour plus de renseignement concernant le débogage avec gdb, vas jeter un oeil à : http://www.linux-france.org/article/memo/node119.html

webmestre du site français dédié à la programmation QT.
http://prog.qt.free.fr
0
psysta Messages postés 5 Date d'inscription vendredi 2 avril 2004 Statut Membre Dernière intervention 9 avril 2004
9 avril 2004 à 22:11
ok. je ne sais pas pourquoi, mais malgre tout (options du deboggeur mises), il ne veut pas m'affciher les lignes. Ce n'est pas grave, j'ai palie ce probleme en ecrivant un printf de la ligne.J'ai reussi a faire fonctionner le pgm. Merci beaucoup pour ton aide.
8D]

Psysta
0
progqt Messages postés 13 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 27 avril 2004
9 avril 2004 à 22:13
De rien , toujours prêt à rendre service. Au plaisir.

webmestre du site français dédié à la programmation QT.
http://prog.qt.free.fr
0
zamourse Messages postés 1 Date d'inscription jeudi 10 mars 2005 Statut Membre Dernière intervention 10 mars 2005
10 mars 2005 à 19:41
comment je fais pour prendre la librairie de pandore
0
Rejoignez-nous