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
00031
00032
00033
00034
00035
00036
#include <stdio.h>
00037
#include <stdlib.h>
00038
#include "idima.h"
00039
#include "idmac.h"
00040
#include "iderr.h"
00041
#include "idprint.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
static void _label_trans ( PPIMAGE_UCHAR,
int);
00057
static void _label_resultat ( FILE * );
00058
static void _label_debut ( PPIMAGE_SHORT,
int,
short * );
00059
static void _label_fin ( FILE*, FILE*,
int );
00060
static void _label_poursuite ( PPIMAGE_SHORT,
int ,
int );
00061
static void _label_recherche (
void );
00062
static void _label_maj_fus (
void );
00063
static void _label_maj_fn (
void );
00064
static void _label_mise_a_jour (
void );
00065
00066
00067
00068 #define Malloc(type) (type *)malloc(sizeof(type))
00069 #define NB_MAX_TRANS 25
00070 #define NB_MAX_COUL 1024
00071
00072 #define deb 0
00073
#if (deb)
00074
# define DEBUG(a) a
00075
#else
00076 # define DEBUG(a)
00077
#endif
00078
00079 typedef enum BOOL {
false,
true }
bool;
00080 typedef struct CONNEX
00081 {
00082 int trans[
NB_MAX_TRANS],
trans_cours[
NB_MAX_TRANS];
00083 short coul[
NB_MAX_COUL];
00084 int surface,
xdeb,
xfin,
ydeb,
yfin;
00085 struct CONNEX *
suivant;
00086 }
connexe;
00087 typedef struct MODELE
00088 {
00089 int surface,
xdeb,
xfin,
ydeb,
yfin;
00090 short coul[
NB_MAX_COUL];
00091 struct MODELE *
suivant;
00092 }
modele;
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
static connexe *premier,*courant,*dernier_cx,*precedent,*fus_cx,*precsup;
00106
static modele *pre_mod,*cou_mod,*der_mod;
00107
static int cou[512],sup[512],*pt_cou,*pt_sup;
00108
static int nb_gros,nb_petit,surf_tot,surf_gros,larg,surfmini;
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
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 int IdImaLabel(PPIMAGE_UCHAR im, PPIMAGE_SHORT imo,
int surf_min, FILE *fich_res, FILE *fich_mod,
int connexite)
00167
00168
00169
00170
00171
00172 {
00173
unsigned char h;
00174
short niv,couleur,ctr[1024];
00175
int compt=0,col,col1;
00176
int y,i,j,nbp,nbp2;
00177
00178
if ( !im ||
IdImaType(im) !=
IMA_UCHAR ){
00179
IdErrno =
IDERR_WRONG_TYPE;
00180
return -1;
00181 }
00182
if ( !imo ||
IdImaType(imo) !=
IMA_SHORT ){
00183
IdErrno =
IDERR_WRONG_TYPE;
00184
return -1;
00185 }
00186
00187 surfmini=surf_min;
00188 surf_tot=0;surf_gros=0;nb_petit=0;nb_gros=0;couleur=0;
00189 pt_cou=cou; pt_sup=sup;
00190
for(y=0;y<512;y++) { *pt_cou++ = -1; *pt_sup++ = -1; }
00191 pt_cou=cou; pt_sup=sup;
00192 pre_mod=
Malloc(
modele); premier=
Malloc(
connexe); dernier_cx=
Malloc(
connexe);
00193 cou_mod=pre_mod; courant=premier; premier->
suivant=dernier_cx;
00194
for(y=0;y<=
IdImaDimY(im);y++)
00195 {
00196
DEBUG(
IdPrintf(
"\n%d : ",y);)
00197 courant=premier;
00198
while(courant->
suivant != dernier_cx)
00199 {
00200 h=0;
00201 courant=courant->
suivant;
00202
while(courant->
trans_cours[h] != -1)
00203 {
00204 courant->
trans[h] = courant->
trans_cours[h];
00205 courant->
trans[++h] = -1;
00206 }
00207 courant->
trans_cours[0] = -1;
00208 }
00209 pt_cou=cou; pt_sup=sup;
00210
while(*pt_cou != -1) *pt_sup++ = *pt_cou++;
00211 *pt_sup = -1;
00212 pt_cou=cou; pt_sup=sup;
00213
if(y !=
IdImaDimY(im)) _label_trans(im,y);
00214
else {*pt_cou++ = -1; *pt_cou = -1; pt_cou=cou; pt_sup=sup; }
00215
while((*pt_cou != -1)&&(*pt_sup != -1))
00216 {
00217
if((*(pt_cou+1)+connexite) < *pt_sup) _label_debut(imo,y,&couleur);
00218
else if(*pt_cou > (*(pt_sup+1)+connexite)) _label_fin(fich_res,fich_mod,y);
00219
else _label_poursuite(imo,y,connexite);
00220 }
00221
if(*pt_cou != -1)
while(*pt_cou != -1) _label_debut(imo,y,&couleur);
00222
else while(*pt_sup != -1) _label_fin(fich_res,fich_mod,y);
00223 }
00224 _label_resultat(fich_res);
00225 der_mod=cou_mod;cou_mod=pre_mod;
00226
for(col=0;col<1024;col++) ctr[col]=0;
00227
while(cou_mod != der_mod) {
00228 cou_mod=pre_mod->
suivant;
00229
if(cou_mod->
surface >= surf_min){
00230 compt++;
00231
00232 col=0;
00233
while(cou_mod->
coul[col]) {
00234 col1=cou_mod->
coul[col++];
00235
00236 ctr[col1]=compt;
00237
if(col >=
NB_MAX_COUL-2)
00238 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00239 }
00240 }
00241 pre_mod=cou_mod;
00242 }
00243
00244 nbp=0;
00245 nbp2=0;
00246
for(i=0;i<
IdImaDimY(imo);i++)
00247
for(j=0;j<
IdImaDimX(imo);j++){
00248 niv = imo[i][j];
00249
if(niv){
00250 imo[i][j] = ctr[niv];
00251 nbp2++;
00252
if(ctr[niv]) nbp++;
00253
00254 }
00255 }
00256
00257
if((nbp != nbp2) && (surfmini < 2))
IdErrPrintf(
"Pb Tableau des niveaux\n");
00258
IdPrintf(
"Surface totale %d, des 'gros' objets: %d, Pts image: %d\n",surf_tot,surf_gros,nbp);
00259
00260
00261
00262
00263
00264 free((
char *)premier);free((
char *)dernier_cx);
00265 der_mod=cou_mod;cou_mod=pre_mod;
00266
while(cou_mod != der_mod)
00267 { cou_mod=pre_mod->
suivant; free((
char *)pre_mod);pre_mod=cou_mod;}
00268 free((
char *)der_mod);
00269
return(nb_gros);
00270 }
00271
00272
00273
00274
static void
00275 _label_trans(PPIMAGE_UCHAR im,
int lig)
00276 {
00277
int x;
00278
00279
DEBUG(
IdPrintf(
"Ligne %d\n",lig); )
00280 if( im[lig][0] ) { *pt_cou=0; }
00281
for(
x=0;
x<
IdImaDimX(im)-1;
x++)
00282 {
00283
if(im[lig][
x] < im[lig][
x+1]) *pt_cou =
x+1;
00284
else if(im[lig][
x] > im[lig][
x+1]) { *(++pt_cou) =
x; pt_cou++;}
00285 }
00286
if(im[lig][
x]) { *(++pt_cou) =
IdImaDimX(im)-1; pt_cou++; }
00287 *pt_cou++ = -1; *pt_cou = -1;
00288 pt_cou=cou; pt_sup=sup;
00289 }
00290
00291
00292
static void
00293 _label_resultat(FILE *fich_res)
00294 {
00295 fprintf(fich_res,
"Nombre d'objets = %d\t",nb_gros);
00296
if(nb_petit) fprintf(fich_res,
"plus %d de surface <= %d pixels\n",nb_petit,surfmini);
00297 fprintf(fich_res,
"Somme des Surfaces de tous les objets : %d\n",surf_tot);
00298 fprintf(fich_res,
"Somme des Surfaces des gros objets : %d\n",surf_gros);
00299 }
00300
00301
00302
00303
static void
00304 _label_debut(PPIMAGE_SHORT imo,
int lig,
short int *pcoul)
00305 {
00306
int xt;
00307
DEBUG(
IdPrintf(
"_label_debut ");)
00308
00309 (*pcoul)++;
00310
for(xt = *pt_cou;xt <= *(pt_cou+1);xt++) imo[lig][xt] = *pcoul;
00311
00312 larg = *(pt_cou+1) - *pt_cou + 1;
00313
00314 precedent=dernier_cx;
00315 precedent->
suivant=
Malloc(
connexe);
00316
00317 precedent->
trans_cours[0] = *pt_cou; precedent->
trans_cours[1] = -1;
00318 precedent->
coul[0] = *pcoul; precedent->
coul[1] = 0;
00319 precedent->
surface = larg; precedent->
ydeb = lig;
00320 precedent->
xdeb = *pt_cou++; precedent->
xfin = *pt_cou++;
00321 dernier_cx=precedent->
suivant;
00322 }
00323
00324
00325
00326
static void
00327 _label_fin(FILE *fich_res, FILE *fich_mod,
int lig)
00328 {
00329
int col,*pt_temp;
00330
bool existe;
00331
00332
DEBUG(
IdPrintf(
"_label_fin ");)
00333 existe=false;
00334 _label_recherche();
00335 fus_cx=courant; precsup=precedent;
00336 pt_temp=pt_sup;
00337 if(courant->trans_cours[0] != -1) existe=true;
00338 while(*(pt_sup+2) != -1)
00339 { pt_sup += 2;_label_recherche();
if(courant==fus_cx) {existe=
true;
break;} }
00340 pt_sup=pt_temp;
00341
if(!existe)
00342 {
00343
DEBUG(
IdPrintf(
"! ");)
00344
00345 cou_mod->suivant=Malloc(
modele);cou_mod=cou_mod->suivant;
00346 surf_tot += fus_cx->surface;
00347
00348 col=0;
00349 while(fus_cx->coul[col]) {
00350 cou_mod->
coul[col] = fus_cx->
coul[col];
00351
00352 col++;
00353
if(col >=
NB_MAX_COUL-2)
00354 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00355 }
00356 cou_mod->
coul[col] = 0;
00357 cou_mod->
surface = fus_cx->
surface;
00358 cou_mod->
xdeb = fus_cx->
xdeb; cou_mod->
xfin = fus_cx->
xfin;
00359 cou_mod->
ydeb = fus_cx->
ydeb; cou_mod->
yfin = lig-1;
00360
00361 precsup->
suivant = fus_cx->
suivant;
00362 free((
char *)fus_cx);
00363
00364
if(cou_mod->
surface >= surfmini) {
00365 nb_gros++;surf_gros += cou_mod->
surface;
00366 fprintf(fich_mod,
"%d\t%d\t",cou_mod->
xdeb,cou_mod->
ydeb);
00367 fprintf(fich_mod,
"%d\t %d\t%d\n",cou_mod->
xfin,cou_mod->
yfin,nb_gros);
00368 fprintf(fich_res,
"Objet No : %d\tSurface = %d\n",nb_gros,cou_mod->
surface);
00369 fprintf(fich_res,
"\tXmin = %d\tYmin = %d",cou_mod->
xdeb,cou_mod->
ydeb);
00370 fprintf(fich_res,
"\tXmax = %d\tYmax = %d\n",cou_mod->
xfin,cou_mod->
yfin);
00371 }
00372
else nb_petit++;
00373 }
00374 pt_sup += 2;
00375 }
00376
00377
00378
00379
static void
00380 _label_poursuite(PPIMAGE_SHORT imo,
int lig,
int connexite)
00381 {
00382
int xt,col,col1;
00383
short niveau;
00384
00385 _label_recherche();
00386
if((*(pt_sup+2) <= (*(pt_cou+1)+connexite)) && (*(pt_sup+2) != -1))
00387
00388 {
00389 fus_cx=courant;
00390 pt_sup += 2;
00391 _label_recherche();
00392
if(courant != fus_cx) {
00393
DEBUG(
IdPrintf(
"\n%d %d %d %d\n",*pt_cou,*(pt_cou+1),*pt_sup,*(pt_sup+1));)
00394 col=0;
00395 while(fus_cx->coul[col]){
00396 col++;
00397
if(col >=
NB_MAX_COUL-2)
00398 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00399 }
00400 col1=0;
00401
while(courant->
coul[col1]){
00402 fus_cx->
coul[col++] = courant->
coul[col1++];
00403
if((col1 >=
NB_MAX_COUL-2)||(col >=
NB_MAX_COUL-2))
00404 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00405
00406 }
00407 fus_cx->
coul[col] = 0;
00408 _label_maj_fus();
00409
DEBUG(
IdPrintf(
"fusion "); )
00410 }
00411
else { _label_maj_fn();
00412
DEBUG(
if(deb)
IdPrintf(
"fusion normale "); )
00413 }
00414
while((*(pt_sup+2) <= (*(pt_cou+1)+connexite)) && (*(pt_sup+2) != -1))
00415 {
00416 pt_sup += 2;
00417 fus_cx=courant;
00418 _label_recherche();
00419
if(courant != fus_cx) {
00420 col=0;
00421
while(fus_cx->
coul[col]){
00422 col++;
00423
if(col >=
NB_MAX_COUL-2)
00424 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00425 }
00426 col1=0;
00427
while(courant->
coul[col1]){
00428 fus_cx->
coul[col++] = courant->
coul[col1++];
00429
if((col1 >=
NB_MAX_COUL-2)||(col >=
NB_MAX_COUL-2))
00430 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00431 }
00432 fus_cx->
coul[col] = 0;
00433 _label_maj_fus();
00434
DEBUG(
IdPrintf(
"fusion ");)
00435 }
00436
else { _label_maj_fn();
00437
DEBUG(
IdPrintf(
"fusion normale ");)
00438 }
00439 }
00440 }
00441
00442
else {
00443 col1=0;
00444
while(courant->
coul[col1]){
00445 col1++;
00446
if(col1 >=
NB_MAX_COUL-2)
00447 {
IdErrPrintf(
"NB_MAX_COUL trop petit\n");
IdExit(0);}
00448 }
00449 niveau=courant->
coul[col1-1];
00450
DEBUG(
IdPrintf(
"niv = %d ",niveau); )
00451 DEBUG( IdPrintf("%d ",*pt_sup); )
00452 larg = *(pt_cou+1) - *pt_cou + 1;
00453 for(xt = *pt_cou;xt<= *(pt_cou+1);xt++) imo[lig][xt]=niveau;
00454 if((*(pt_cou+2) <= (*(pt_sup+1)+connexite)) && (*(pt_cou+2) != -1))
00455 {
00456
DEBUG(
IdPrintf(
"eclatement ");)
00457 _label_mise_a_jour();
00458 }
00459 else {
00460 _label_mise_a_jour();pt_sup += 2;
00461
DEBUG(
IdPrintf(
"pours. normale ");)
00462 }
00463 }
00464 }
00465
00466
00467
static void
00468 _label_recherche(
void)
00469 {
00470
bool trouve;
00471
unsigned char k;
00472
00473 trouve=
false;
00474 courant=premier;
00475
DEBUG(
IdPrintf(
"\nRech (%d): ",*pt_sup);)
00476 while((courant->suivant != dernier_cx) && (!trouve))
00477 {
00478 k=0;
00479 precedent=courant;
00480 courant=courant->
suivant;
00481
DEBUG(
IdPrintf(
"** ");)
00482 while(courant->trans[k] != -1)
00483 {
00484
DEBUG(
IdPrintf(
"%d ",courant->
trans[k]);)
00485 if(courant->trans[k] == *pt_sup) {trouve=
true;
break;}
00486 k++;
00487 }
00488 }
00489
DEBUG(
IdPrintf(
"\n");)
00490 }
00491
00492
00493
00494
00495
static void
00496 _label_maj_fus(
void)
00497 {
00498
unsigned char k,j;
00499
00500 k=0;j=0;
00501
while(fus_cx->
trans_cours[k] != -1) k++;
00502
while(courant->
trans_cours[j] != -1)
00503 { fus_cx->
trans_cours[k] = courant->
trans_cours[j]; j++; k++; }
00504 fus_cx->
trans_cours[k++] = *pt_cou;
00505 fus_cx->
trans_cours[k] = -1;
00506 k=0;j=0;
00507
while(fus_cx->
trans[k] != -1) k++;
00508
while(courant->
trans[j] != -1)
00509 {
00510
DEBUG(
IdPrintf(
"\nNo %d",courant->
trans[j]);)
00511 fus_cx->trans[k] = courant->trans[j]; j++; k++;
00512 }
00513 fus_cx->trans[k] = -1;
00514 fus_cx->surface += courant->surface;
00515 fus_cx->xdeb = min(min(fus_cx->xdeb,courant->xdeb),*pt_cou);
00516 fus_cx->xfin = max(max(fus_cx->xfin,courant->xfin),*(pt_cou+1));
00517 fus_cx->ydeb = min(fus_cx->ydeb,courant->ydeb);
00518 precedent->suivant = courant->suivant;
00519 free((
char *)courant);
00520 courant=fus_cx;
00521 }
00522
00523
00524
00525
00526 static
void
00527 _label_maj_fn(
void)
00528 {
00529
unsigned char k=0;
00530
00531
while(courant->
trans_cours[k] != -1) k++;
00532 courant->
trans_cours[k++] = *pt_cou;
00533 courant->
trans_cours[k] = -1;
00534 courant->
xdeb =
min(courant->
xdeb,*pt_cou);
00535 courant->
xfin =
max(courant->
xfin,*(pt_cou+1));
00536 }
00537
00538
00539
00540
static void
00541 _label_mise_a_jour(
void)
00542 {
00543
unsigned char k=0;
00544
00545 courant->
surface += larg;
00546
while(courant->
trans_cours[k] != -1) k++;
00547 courant->
trans_cours[k++] = *pt_cou;
00548 courant->
trans_cours[k] = -1;
00549 courant->
xdeb =
min(courant->
xdeb,*pt_cou);
00550 courant->
xfin =
max(courant->
xfin,*(pt_cou+1));
00551 pt_cou += 2;
00552 }
00553
00554
00555