00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00033 #include "eval_volume.h"
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <math.h>
00037
00038 #include <sys/types.h>
00039 #include <sys/stat.h>
00040 #include <fcntl.h>
00041 #include <unistd.h>
00042 #include <string.h>
00043
00044 #define ETMAX 17000000
00045
00046 #define ABSOL(x,y) (((x) > (y))? abs(x-y) : abs(y-x))
00047 #define MAX(x,y) (((x)>(y))? (x):(y))
00048 #define MIN(x,y) (((x)<(y))? (x):(y))
00049 #define MIN3(x,y,z) ( ( ((x)<(y))&&((x)<(z)) )?(x):( ( ((x)>(y))&&((y)<(z)) )?y:z ) )
00050 #define VRAI 1
00051 #define FAUX 0
00052
00053 typedef char booleen;
00054
00055
00056
00067 param* eval_volume_lect(eval_volume_t* des, param* ptp, char* debq){
00068 char question[500];
00069
00070 sprintf(question, "%s Classe a etudier (niveau de gris)", debq);
00071 lec_param(question, ptp);
00072 des->classe = atoi(ptp->rep);
00073 ptp = ptp->next;
00074
00075 return(ptp);
00076 }
00077
00078
00079
00080
00081
00098 int eval_volume_init(eval_volume_t* des, ima3Du1* imaIn){
00099
00100
00101 des->ima_etiq = (ima3Du8 *)malloc(sizeof(ima3Du8));
00102 des->ima_etiq->dimx = imaIn->dimx;
00103 des->ima_etiq->dimy = imaIn->dimy;
00104 des->ima_etiq->dimz = imaIn->dimz;
00105 des->ima_etiq->lgtete = imaIn->lgtete;
00106 des->ima_etiq->dept = imaIn->dept;
00107 allouer_ima3Du8 (des->ima_etiq);
00108
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 unsigned long int eval_equivalence_2_label( unsigned long int *pt_etiq,
00143 unsigned long int a,
00144 unsigned long int b){
00145
00146 unsigned long int minimum;
00147 unsigned long int beta;
00148 unsigned long int tmp;
00149
00150 minimum = MIN(a,b);
00151
00152 beta = a;
00153 while( pt_etiq[beta]!= minimum){
00154 tmp = pt_etiq[beta];
00155 pt_etiq[beta] = minimum;
00156 beta = tmp;
00157 }
00158
00159 beta = b;
00160 while( pt_etiq[beta]!= minimum){
00161 tmp = pt_etiq[beta];
00162 pt_etiq[beta] = minimum;
00163 beta = tmp;
00164 }
00165
00166 return( minimum);
00167
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 unsigned long int eval_equivalence_3_label( unsigned long int *pt_etiq,
00179 unsigned long int a,
00180 unsigned long int b,
00181 unsigned long int c){
00182
00183 unsigned long int minimum;
00184 unsigned long int beta;
00185 unsigned long int tmp;
00186
00187 minimum = MIN3( a, b, c);
00188
00189 beta = a;
00190 while( pt_etiq[beta]!= minimum){
00191 tmp = pt_etiq[beta];
00192 pt_etiq[beta] = minimum;
00193 beta = tmp;
00194 }
00195
00196 beta = b;
00197 while( pt_etiq[beta]!= minimum){
00198 tmp = pt_etiq[beta];
00199 pt_etiq[beta] = minimum;
00200 beta = tmp;
00201 }
00202
00203 beta = c;
00204 while( pt_etiq[beta]!= minimum){
00205 tmp = pt_etiq[beta];
00206 pt_etiq[beta] = minimum;
00207 beta = tmp;
00208 }
00209 return( minimum);
00210
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 void eval_label_management( unsigned char cas,
00308 unsigned long int haut,
00309 unsigned long int gauche,
00310 unsigned long int avant,
00311 unsigned long int *courant,
00312
00313 unsigned long int *pt_etiq,
00314
00315 unsigned long int *nb_etiq
00316 )
00317 {
00318
00319
00320 if(cas>=64) printf("PROBLEME\n");
00321
00322 switch (cas) {
00323
00324 case 0:
00325 case 8:
00326 case 16:
00327 case 24:
00328 case 32:
00329 case 40:
00330 case 48:
00331 case 56:
00332
00333 {
00334 *nb_etiq +=1;
00335 if(*nb_etiq>ETMAX-1) *nb_etiq=ETMAX-1;
00336 *courant = *nb_etiq;
00337 return;
00338 }
00339
00340 case 1:
00341 case 33:
00342
00343 {
00344 *courant = pt_etiq[avant];
00345 return;
00346 }
00347
00348 case 2:
00349 case 18:
00350
00351 {
00352 *courant = pt_etiq[haut];
00353 return;
00354 }
00355
00356 case 4 :
00357 case 12:
00358
00359 {
00360 *courant = pt_etiq[gauche];
00361 return;
00362 }
00363
00364 case 3:
00365 case 9:
00366 case 10:
00367 case 11:
00368
00369 {
00370 *courant = eval_equivalence_2_label( pt_etiq, avant, haut);
00371 return;
00372 }
00373
00374
00375 case 5:
00376 case 17:
00377 case 20:
00378 case 21:
00379
00380 {
00381 *courant = eval_equivalence_2_label(pt_etiq, avant, gauche);
00382 return;
00383 }
00384
00385 case 6:
00386 case 34:
00387 case 36:
00388 case 38:
00389
00390 {
00391 *courant = eval_equivalence_2_label(pt_etiq, haut, gauche);
00392 return;
00393 }
00394
00395 default:
00396
00397 {
00398 *courant = eval_equivalence_3_label(pt_etiq, haut, gauche, avant);
00399
00400 return;
00401 }
00402 }
00403
00404 }
00405
00406
00407
00408
00409
00410
00411
00412 void
00413 eval_reetiquetage( ima3Du1* ima_ori,
00414 ima3Du8* ima_etiq,
00415 unsigned long int *pt_etiq,
00416 unsigned long int *pt_nb_etiq,
00417 unsigned long int *pt_nb_real_etiq)
00418 {
00419 register unsigned int x,y,z;
00420 unsigned long int i;
00421
00422
00423 unsigned long int tmp;
00424
00425
00426 unsigned long int etiq_reelle;
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 for (i = 0; i <= (*pt_nb_etiq); i++) {
00456 tmp = i;
00457 while (pt_etiq[tmp]!=tmp){
00458 tmp = pt_etiq[tmp];
00459 }
00460 pt_etiq[i] = tmp;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 etiq_reelle = 0;
00488 for (i = 0; i <= (*pt_nb_etiq); i++) {
00489 if(pt_etiq[i] == i){
00490 pt_etiq[i] = etiq_reelle;
00491 etiq_reelle++;
00492 }else if(pt_etiq[i] < i){
00493 pt_etiq[i] = pt_etiq[pt_etiq[i]];
00494 }
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 for (i = 0; i <= (*pt_nb_etiq); i++) {
00509 if( pt_etiq[i]>i )
00510 pt_etiq[i] = pt_etiq[pt_etiq[i]];
00511 }
00512
00513
00514
00515
00516 for( z=0; z<ima_etiq->dimz; z++){
00517 for( x=0; x<ima_etiq->dimx; x++){
00518 for( y=0; y<ima_etiq->dimy; y++){
00519 ima_etiq->data[z][y][x] = pt_etiq[ ima_etiq->data[z][y][x] ];
00520 }
00521 }
00522 }
00523
00524
00525
00526 *pt_nb_real_etiq = etiq_reelle-1;
00527
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 void
00550 eval_etiquetage_strict(ima3Du1* ima_in,
00551 ima3Du8* ima_etiq,
00552 unsigned char classe,
00553 unsigned long int *pt_nb_etiq,
00554 unsigned long int *nb_real_etiq)
00555 {
00556 int cas;
00557 register int x,y,z;
00558 unsigned long int i;
00559 unsigned long int *pt_etiq;
00560 unsigned long int nb_etiq;
00561
00562
00563
00564
00565 pt_etiq = (unsigned long int *)calloc(ETMAX, sizeof(unsigned long int));
00566 if(pt_etiq == NULL){
00567 printf("Probleme d'allocation mémoire (pt_etiq)\n");
00568 exit(1);
00569 }
00570
00571
00572
00573 for( i=0; i<ETMAX ; i++)
00574 pt_etiq[i] = i;
00575
00576 nb_etiq = 0;
00577
00578
00579
00580 if( ima_in->data[0][0][0] != classe){
00581 ima_etiq->data[0][0][0] = 0;
00582 }
00583 else{
00584
00585 nb_etiq +=1;
00586 if(nb_etiq>ETMAX-1) nb_etiq=ETMAX-1;
00587 ima_etiq->data[0][0][0] = nb_etiq;
00588 }
00589
00590
00591 x = 0;
00592 z = 0;
00593 for( y=1; y<ima_in->dimy; y++){
00594
00595
00596
00597 if(ima_in->data[z][y][x] != classe){
00598 ima_etiq->data[z][y][x] = 0;
00599 continue;
00600 }
00601
00602 cas = 0;
00603 if( ima_in->data[z][y][x] == ima_in->data[z][y-1][x] )
00604 cas += 4;
00605 eval_label_management( cas,
00606 0,
00607 ima_etiq->data[z][y-1][x],
00608 0,
00609 &ima_etiq->data[z][y][x],
00610 pt_etiq,
00611 &nb_etiq
00612 );
00613 }
00614
00615
00616
00617
00618
00619
00620 z = 0;
00621 for( x=1; x<ima_in->dimx; x++){
00622 for( y=0; y<ima_in->dimy; y++){
00623
00624
00625
00626
00627 if(ima_in->data[z][y][x] != classe){
00628 ima_etiq->data[z][y][x] = 0;
00629 continue;
00630 }
00631
00632
00633 cas = 0;
00634
00635
00636 if( ima_in->data[z][y][x] == ima_in->data[z][y][x-1] )
00637 cas += 2;
00638
00639
00640
00641 if( y!=0){
00642
00643 if( ima_in->data[z][y][x] == ima_in->data[z][y-1][x] )
00644 cas += 4;
00645 if( ima_in->data[z][y-1][x] == ima_in->data[z][y][x-1] )
00646 cas += 32;
00647 eval_label_management( cas,
00648 ima_etiq->data[z][y][x-1] ,
00649 ima_etiq->data[z][y-1][x],
00650 0,
00651 &ima_etiq->data[z][y][x],
00652 pt_etiq,
00653 &nb_etiq
00654 );
00655 }
00656 else{
00657 eval_label_management( cas,
00658 ima_etiq->data[z][y][x-1] ,
00659 0,
00660 0,
00661 &ima_etiq->data[z][y][x],
00662 pt_etiq,
00663 &nb_etiq
00664 );
00665 }
00666 }
00667 }
00668
00669
00670
00671 for( z=1; z<ima_in->dimz; z++){
00672 for( x=0; x<ima_in->dimx; x++){
00673 for( y=0; y<ima_in->dimy; y++){
00674
00675
00676
00677
00678 if(ima_in->data[z][y][x] != classe){
00679 ima_etiq->data[z][y][x] = 0;
00680 continue;
00681 }
00682
00683
00684 cas = 0;
00685
00686
00687 if( ima_in->data[z][y][x] == ima_in->data[z-1][y][x] )
00688 cas += 1;
00689
00690
00691
00692 if(x==0){
00693 if(y!=0){
00694 if( ima_in->data[z][y][x] == ima_in->data[z][y-1][x] )
00695 cas += 4;
00696 if( ima_in->data[z][y-1][x] == ima_in->data[z-1][y][x] )
00697 cas += 16;
00698 eval_label_management( cas,
00699 0 ,
00700 ima_etiq->data[z][y-1][x] ,
00701 ima_etiq->data[z-1][y][x] ,
00702 &ima_etiq->data[z][y][x],
00703 pt_etiq,
00704 &nb_etiq
00705 );
00706
00707 }
00708 else{
00709 eval_label_management( cas,
00710 0 ,
00711 0 ,
00712 ima_etiq->data[z-1][y][x] ,
00713 &ima_etiq->data[z][y][x],
00714 pt_etiq,
00715 &nb_etiq
00716 );
00717
00718 }
00719 }
00720 else{
00721
00722
00723 if( ima_in->data[z][y][x] == ima_in->data[z][y][x-1] )
00724 cas += 2;
00725 if( ima_in->data[z][y][x-1] == ima_in->data[z-1][y][x] )
00726 cas += 8;
00727
00728 if(y!=0){
00729 if( ima_in->data[z][y][x] == ima_in->data[z][y-1][x] )
00730 cas += 4;
00731 if( ima_in->data[z][y-1][x] == ima_in->data[z-1][y][x] )
00732 cas += 16;
00733 if( ima_in->data[z][y-1][x] == ima_in->data[z][y][x-1] )
00734 cas += 32;
00735 eval_label_management( cas,
00736 ima_etiq->data[z][y][x-1] ,
00737 ima_etiq->data[z][y-1][x] ,
00738 ima_etiq->data[z-1][y][x] ,
00739 &ima_etiq->data[z][y][x],
00740 pt_etiq,
00741 &nb_etiq
00742 );
00743 }
00744 else{
00745 eval_label_management( cas,
00746 ima_etiq->data[z][y][x-1] ,
00747 0 ,
00748 ima_etiq->data[z-1][y][x] ,
00749 &ima_etiq->data[z][y][x],
00750 pt_etiq,
00751 &nb_etiq
00752 );
00753 }
00754 }
00755
00756
00757 }
00758 }
00759 }
00760
00761
00762 printf("nb_etiq = %d (max %d)\n", nb_etiq+1, ETMAX);
00763 if( nb_etiq+1 == ETMAX) {
00764 printf("-----DANGER Pas assez d'etiquettes !!!----\n");
00765 }
00766
00767 *pt_nb_etiq = nb_etiq+1;
00768
00769
00770 eval_reetiquetage( ima_in,
00771 ima_etiq,
00772 pt_etiq,
00773 &nb_etiq,
00774 nb_real_etiq);
00775
00776
00777
00778 free( pt_etiq);
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 int calcul_vol_objets(eval_volume_t* des, const char *filename, unsigned long int nb_objet){
00797
00798 unsigned int *vol;
00799 unsigned int repartition_vol[5]={0,0,0,0,0};
00800 unsigned int vol_min, vol_max;
00801 double vol_moy, vol_ecart_type;
00802 register unsigned int x, y, z;
00803 FILE *f;
00804
00805
00806 vol = calloc( nb_objet+1,sizeof(unsigned int));
00807 if( vol==NULL) {
00808 printf("Probleme allocation memoire\n");
00809 exit(1);
00810 }
00811
00812
00813 for( z=0; z<des->ima_etiq->dimz; z++)
00814 for( y=0; y<des->ima_etiq->dimy; y++)
00815 for( x=0; x<des->ima_etiq->dimx; x++){
00816 vol[des->ima_etiq->data[z][y][x]]++;
00817 }
00818
00819 printf("un\n");
00820
00821 f=fopen( filename, "w");
00822 if(f==NULL){
00823 perror("Dans calcul_vol_objets");
00824 printf("Erreur ouverture de %s\n", filename);
00825 }
00826 vol_min = vol[1];
00827 vol_max = vol[1];
00828 vol_moy = 0.0;
00829 for( x=1; x<=nb_objet; x++){
00830 fprintf( f, "%d %d\n", x, vol[x] );
00831 if (vol[x] > vol_max) vol_max = vol[x];
00832 if (vol[x] < vol_min) vol_min = vol[x];
00833 vol_moy += (double)vol[x]/(double)nb_objet;
00834
00835 if( vol[x]<10 ) repartition_vol[0]++;
00836 else if ( vol[x]<100 ) repartition_vol[1]++;
00837 else if ( vol[x]<1000 ) repartition_vol[2]++;
00838 else if ( vol[x]<10000 ) repartition_vol[3]++;
00839 else repartition_vol[4]++;
00840 }
00841
00842
00843
00844 vol_ecart_type = 0.0;
00845 for( x=1; x<=nb_objet; x++){
00846 vol_ecart_type += pow( (double)vol[x]-vol_moy, 2.0) / (double)nb_objet;
00847 }
00848 vol_ecart_type = sqrt( vol_ecart_type);
00849
00850
00851 printf("Volume minimal: %d\n", vol_min);
00852 printf("Volume maximal: %d\n", vol_max);
00853 printf("Volume moyen: %lf\n", vol_moy);
00854 printf("Ecart type: %lf\n", vol_ecart_type);
00855
00856 printf("Répartion des volumes:\n");
00857 printf("0->9:\t %d\n", repartition_vol[0]);
00858 printf("10->99:\t %d\n", repartition_vol[1]);
00859 printf("100->999:\t %d\n", repartition_vol[2]);
00860 printf("1000->9999:\t %d\n", repartition_vol[3]);
00861 printf("10000-> + :\t %d\n", repartition_vol[4]);
00862
00863
00864
00865 free( vol);
00866
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 int calcul_attributs_objets(eval_volume_t* des, const char *filename, unsigned long int nb_objet){
00878
00879 unsigned int *vol, *surf;
00880 register unsigned int x, y, z;
00881 register char l, m, n;
00882 FILE *f;
00883 booleen env;
00884 double compacite;
00885 double comp_moy;
00886
00887 comp_moy = 0.0;
00888
00889 vol = calloc( nb_objet+1,sizeof(unsigned int));
00890 if( vol==NULL) {
00891 printf("Probleme allocation memoire\n");
00892 exit(1);
00893 }
00894
00895 surf = calloc( nb_objet+1,sizeof(unsigned int));
00896 if( surf==NULL) {
00897 printf("Probleme allocation memoire\n");
00898 exit(1);
00899 }
00900
00901
00902
00903 printf("Calcul des attributs en cours\n");
00904 for( z=0; z<des->ima_etiq->dimz; z++)
00905 for( y=0; y<des->ima_etiq->dimy; y++)
00906 for( x=0; x<des->ima_etiq->dimx; x++){
00907
00908 vol[des->ima_etiq->data[z][y][x]]++;
00909
00910 env=FAUX;
00911 if( z==0 ||
00912 y==0 ||
00913 x==0 ||
00914 z==des->ima_etiq->dimz-1 ||
00915 y==des->ima_etiq->dimy-1 ||
00916 x==des->ima_etiq->dimx-1){
00917 env=VRAI;
00918 }else{
00919 for( l=-1; l<2; l++ )
00920 for( m=-1; m<2; m++ )
00921 for( n=-1; n<2; n++ ){
00922
00923
00924 if( des->ima_etiq->data[z][y][x] != des->ima_etiq->data[z+l][y+m][x+n]){
00925 env = VRAI;
00926 continue;
00927 }
00928 }
00929 }
00930
00931 if(env==VRAI) surf[des->ima_etiq->data[z][y][x]]++;
00932 }
00933
00934
00935
00936 printf("Sauvagarde des résultats dans %s\n",filename );
00937 f=fopen( filename, "w");
00938 if(f==NULL){
00939 perror("Dans calcul_attributs_objets");
00940 printf("Erreur ouverture de %s\n", filename);
00941 }
00942
00943 for( x=1; x<=nb_objet; x++){
00944 compacite = (double)vol[x] / ( (4.0/3.0) * M_PI * pow( surf[x]/(4.0*M_PI) ,1.5) );
00945 fprintf( f, "%d %d %d %.4lf\n", x, vol[x], surf[x], compacite );
00946 comp_moy += compacite/(double)nb_objet;
00947 }
00948
00949 printf("Compacitee moyenne: %lf\n", comp_moy);
00950
00951
00952 free( vol);
00953 free( surf);
00954 }
00955
00956
00957
00958
00959
00960
00961
00973 int eval_volume_calc(eval_volume_t* des, ima3Du1* imaIn){
00974
00975 unsigned long int nb_objet_reel, nb_etiq_utilise;
00976
00977 eval_etiquetage_strict(imaIn, des->ima_etiq, des->classe, &nb_etiq_utilise, &nb_objet_reel);
00978
00979
00980 printf("Nombre d'objets: %d\n", nb_objet_reel);
00981
00982
00983 printf("Calcul compacite ...\n");
00984 calcul_attributs_objets(des, "attr.txt", nb_objet_reel);
00985
00986 }
00987
00988
00989
00990
00991 int eval_volume_ferm(eval_volume_t* des){
00992
00993
00994 liberer_ima3Du8( des->ima_etiq);
00995
00996 free(des->ima_etiq);
00997
00998
00999 }