00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00037 #include "classifier.h"
00038 #include "image.h"
00039 #include "proto2D.h"
00040 #include "fuzzy_c_means.h"
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <math.h>
00045 #include <time.h>
00046 #include <ctype.h>
00047
00048
00049
00050 #define ABS(X) ((X)<0?-(X):(X))
00051
00065
00066
00086 param *fuzzy_c_means_lect( fuzzy_c_means_t *fcm, param *ptp, char *debq)
00087 {
00088 char question[500];
00089
00090 sprintf(question, "%s nombre de classes [nb_class] (entier)", debq);
00091 lec_param(question, ptp);
00092 fcm->nb_class = atoi(ptp->rep);
00093 ptp = ptp->next;
00094
00095 sprintf(question, "%s indice de flou [fuzzy_coeff] (>1) (reel)", debq);
00096 lec_param(question, ptp);
00097 fcm->fuzzy_coeff = (float)atof(ptp->rep);
00098 ptp = ptp->next;
00099
00100 sprintf(question, "%s seuil d'arret [threshold] [0, 1] (ex:0.001) (reel)", debq);
00101 lec_param(question, ptp);
00102 fcm->threshold = (float)atof(ptp->rep);
00103 ptp = ptp->next;
00104
00105 sprintf(question, "%s nombre maximum d'iterations [nb_it] (entier)", debq);
00106 lec_param(question, ptp);
00107 fcm->nb_it = atoi(ptp->rep);
00108 ptp = ptp->next;
00109
00110 sprintf(question, "%s extension noms fichiers images d'appartenance (.ima|.ras|.imf), non sauvees si ''", debq);
00111 lec_param(question, ptp);
00112 strcpy(fcm->extension, ptp->rep);
00113 ptp = ptp->next;
00114
00115 sprintf(question, "%s Quelle initialisation? ( 0 | 1 | nom_fichier )", debq);
00116 lec_param(question, ptp);
00117 strcpy(fcm->init_type, ptp->rep);
00118 ptp = ptp->next;
00119
00120 return(ptp);
00121 }
00122
00123
00124
00125
00126
00127
00149 int fuzzy_c_means_init(fuzzy_c_means_t *fcm, data_input dataI , data_output *dataO)
00150 {
00151 int i, k, j;
00152
00153 printf("\n fuzzy_c_mean init...");
00154
00155 dataO->nb_class = fcm->nb_class;
00156 dataO->nb_pts = dataI.nb_pts;
00157 dataO->type = FUZZY_CHOICE;
00158 dataO->equ_nb_cols = dataI.equ_nb_cols;
00159 dataO->equ_nb_rows = dataI.equ_nb_rows;
00160
00161 fcm->centre=(unsigned short **)Calloc(fcm->nb_class,sizeof(*fcm->centre));
00162 for (k=0;k<fcm->nb_class;k++)
00163 fcm->centre[k]=(unsigned short *)Calloc(dataI.nb_attr,sizeof(unsigned short));
00164
00165 alloc_classifier_data_output(dataO);
00166
00167
00168 init_coeff_appartenance(fcm, dataI, dataO);
00169
00170 printf("\ninit fcm OK.\n");
00171 }
00172
00173
00174
00175
00176
00177
00194 int fuzzy_c_means_calc(fuzzy_c_means_t *fcm, data_input dataI , data_output *dataO)
00195 {
00196 int i,j,k,t;
00197 float media,tmp;
00198
00199 printf("\nfcm calc...\n\n");
00200
00201 t=0;
00202 printf("Nb. de iterations[nb_it]=%d\n",fcm->nb_it);
00203 printf("\n");
00204 while(t<fcm->nb_it)
00205 {
00206 printf("\n");
00207 printf(" Itération numéro %d\n",t);
00208 printf("\n");
00209
00210 calcul_centroides(fcm,dataI, dataO);
00211 calcul_coeff_appartenance(fcm, dataI, dataO);
00212
00213 media=fcm->variation/(fcm->nb_class*(dataI.nb_pts));
00214 printf("===> seuil = %1.5f",fcm->threshold);
00215 printf(" --->> la variation actuelle = %1.5f",media);
00216 if (media<fcm->threshold) break;
00217
00218 if (t<fcm->nb_it-1) printf(" ... donc, continue\n");
00219
00220 t++;
00221 }
00222
00223
00224 printf("\n");
00225 printf("\n");
00226
00227 printf("Calcul effectué!\n");
00228 if (t!=fcm->nb_it) printf("L'algorithme a terminé le calcul après %d cycles.\n",t+1);
00229 else printf("\nNb. maximum d'itérations atteint !!! \n");
00230
00231 printf("\n");
00232 }
00233
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 char *Calloc(unsigned nelem,unsigned elsize)
00254 {
00255 char *ptr;
00256 if((ptr=calloc(nelem,elsize))==NULL)
00257 {
00258 perror("MEMORY ALLOCATION ERROR");
00259 exit(3);
00260 }
00261 return ptr;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void calcul_coeff_appartenance(fuzzy_c_means_t *fcm, data_input dataI , data_output *dataO)
00279 {
00280 int i,j,k,l,x,y,z,a,b;
00281 float S,S1,S2,S3;
00282
00283 fcm->variation=0;
00284 for(a=0;a<dataI.nb_pts;a++)
00285 for(i=0;i<fcm->nb_class;i++)
00286 {
00287 S3=S1=S2=S=0;
00288
00289 for(x=0;x<dataI.nb_attr;x++)
00290 S1=S1+pow((dataI.attributes[x][a]-fcm->centre[i][x]),2);
00291
00292 S3=1/pow(S1+0.001,1/(fcm->fuzzy_coeff-1));
00293
00294 for(j=0;j<fcm->nb_class;j++)
00295 {
00296 for(y=0;y<dataI.nb_attr;y++)
00297 S2=S2+pow((dataI.attributes[y][a]-fcm->centre[j][y]),2);
00298
00299 S2=1/pow(S2,1/(fcm->fuzzy_coeff-1));
00300 S=S+S2;
00301 }
00302
00303 fcm->variation=fcm->variation+ABS(dataO->classes.fuzzy[i][a]-(S3/S))*10;
00304 dataO->classes.fuzzy[i][a]=S3/S;
00305 }
00306
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 void calcul_centroides(fuzzy_c_means_t *fcm, data_input dataI , data_output *dataO)
00325 {
00326 int i,j,k,l;
00327 float S1,S2;
00328
00329 for(j=0;j<dataI.nb_attr;j++)
00330 {
00331 for(i=0;i<fcm->nb_class;i++)
00332 {
00333 S1=S2=0;
00334 for(k=0;k<dataI.nb_pts;k++)
00335 {
00336 S1=S1+pow(dataO->classes.fuzzy[i][k],fcm->fuzzy_coeff)*dataI.attributes[j][k];
00337 S2=S2+pow(dataO->classes.fuzzy[i][k],fcm->fuzzy_coeff);
00338 }
00339 fcm->centre[i][j]=(int)(S1/S2);
00340 printf("centre[%d][%d] = %d\n",i,j,fcm->centre[i][j]);
00341 }
00342 printf("\n");
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 void init_coeff_appartenance(fuzzy_c_means_t *fcm, data_input dataI , data_output *dataO)
00364 {
00365 int tmp;
00366 int i,j,k,x;
00367 float *a;
00368 int max,rnd;
00369 FILE *toto;
00370
00371 if ((strlen(fcm->init_type)==1)&&( (strstr(fcm->init_type,"0")!=NULL) || (strstr(fcm->init_type,"1")!=NULL) ))
00372 {
00373 printf("...Choix d'initialisation = %d\n",atoi(fcm->init_type));
00374
00375
00376 if (atoi(fcm->init_type) == 0)
00377 {
00378 srand((unsigned int)time(NULL));
00379 for(i=0;i<dataI.nb_pts;i++)
00380 {
00381 max=0;
00382 for(k=0;k<fcm->nb_class;k++)
00383 {
00384 dataO->classes.fuzzy[k][i]=(rand()%(100));
00385 max=max+dataO->classes.fuzzy[k][i];
00386 }
00387
00388 for(k=0;k<fcm->nb_class;k++)
00389 if (max!=0) dataO->classes.fuzzy[k][i]=(dataO->classes.fuzzy[k][i])/max;
00390 }
00391 }
00392
00393
00394
00395 else if (atoi(fcm->init_type) == 1)
00396 {
00397 a=(float *)Calloc(fcm->nb_class,sizeof(float));
00398
00399
00400 max=0;
00401 for(k=0;k<dataI.nb_attr;k++)
00402 for(i=0;i<dataI.nb_pts;i++)
00403 if (dataI.attributes[k][i]>max) max=dataI.attributes[k][i];
00404
00405
00406
00407 for(x=0;x<dataI.nb_attr;x++)
00408 for(i=0;i<fcm->nb_class;i++)
00409 fcm->centre[i][x]=rand()%(max);
00410
00411
00412
00413 for(x=0;x<dataI.nb_attr;x++)
00414 for(i=0;i<dataI.nb_pts;i++)
00415 {
00416 max=0;
00417 for(k=0;k<fcm->nb_class;k++)
00418 {
00419 a[k]=ABS(fcm->centre[k][x]-dataI.attributes[x][i]);
00420 max=max+a[k];
00421 }
00422 for(k=0;k<fcm->nb_class;k++)
00423 dataO->classes.fuzzy[k][i]=a[k]/max;
00424 }
00425
00426 }
00427 }
00428
00429
00430 else
00431 {
00432 printf("...initialisation par fichier = lecture dans '%s' les coeff suivants :\n\n",fcm->init_type);
00433
00434 a=(float *)Calloc(fcm->nb_class,sizeof(float));
00435
00436
00437 toto=fopen(fcm->init_type,"r");
00438
00439 for(i=0;i<fcm->nb_class;i++)
00440 {
00441 for(j=0;j<dataI.nb_attr;j++)
00442 {
00443 fscanf(toto,"%d ", &tmp);
00444 fcm->centre[i][j] = (unsigned short)tmp;
00445 printf("centre[%d][%d] = %d \t",i,j,fcm->centre[i][j]);
00446 }
00447 printf("\n");
00448 }
00449
00450
00451 fclose(toto);
00452
00453
00454 for(x=0;x<dataI.nb_attr;x++)
00455 for(i=0;i<dataI.nb_pts;i++)
00456 {
00457 max=0;
00458 for(k=0;k<fcm->nb_class;k++)
00459 {
00460 a[k]=ABS(fcm->centre[k][x]-dataI.attributes[x][i]);
00461 max=max+a[k];
00462 }
00463
00464 for(k=0;k<fcm->nb_class;k++)
00465 dataO->classes.fuzzy[k][i]=a[k]/max;
00466 }
00467 }
00468
00469
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480