00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00043 #include "image.h"
00044 #include "proto2D.h"
00045 #include "labelcc.h"
00046 #include <stdlib.h>
00047 #include <fcntl.h>
00048
00049
00050 #define TAILLE_TABLE 0x10000
00051 #define new_object ((nbfs >= 2) ? ++objets : 1 + (objets++ % 255))
00052
00053
00054 static pixu2 *t_lut;
00055 static pixu2 etiq;
00056 static int connex_8;
00057 static int masque;
00058 static int seuil;
00059 static int negatif;
00060 static int np , nl ;
00061
00062 pixu1 **ENTREE ;
00063 pixu2 **SORTIE ;
00064
00065
00066
00067
00068
00082 param *labelcc_lect( labelcc_t *des, param *ptp, char *debq){
00083 char question[500];
00084
00085 sprintf(question, "%s connexite : 4 ou 8", debq);
00086 lec_param(question, ptp);
00087 des->connex = atoi(ptp->rep);
00088 ptp = ptp->next;
00089 if(des->connex!=4 && des->connex!=8 ){
00090 printf("\n>>ERREUR labelcc_lect : connexite %d inconnu (4 ou 8)\n",
00091 des->connex);
00092 exit(1);
00093 }
00094
00095 sprintf(question, "%s seuil : premier niveau de gris des objets", debq);
00096 lec_param(question, ptp);
00097 des->seuil = atoi(ptp->rep);
00098 ptp = ptp->next;
00099
00100 sprintf(question, "%s contraste : <0 = objets sombres, >=0 = objets claires",
00101 debq);
00102 lec_param(question, ptp);
00103 des->contraste = atoi(ptp->rep);
00104 ptp = ptp->next;
00105
00106 return(ptp);
00107 }
00108
00109
00120 int labelccu1_init(labelcc_t *des, imau1 im0, imau2 *imres){
00121
00122 imres->nc = im0.nc;
00123 imres->nr = im0.nr;
00124 sprintf(imres->nom, "%s_label_s%d", im0.nom, des->seuil);
00125 alloc_imau2(imres);
00126 }
00127
00128
00129
00141 int labelccu1_calc(labelcc_t *des, imau1 im0, imau2 *imres){
00142 int nbo;
00143 int nbfs=2;
00144
00145 nbo = ETIQ(&im0, imres, &(des->connex), &(des->seuil), &(des->contraste), &nbfs);
00146
00147 return(nbo);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 int ETIQ ( IMA_IN, IMA_EX, CONNEX, SEUIL, CONTRASTE, NBFS)
00226 imau1 *IMA_IN ;
00227 imau2 *IMA_EX ;
00228 int *CONNEX;
00229 int *SEUIL;
00230 int *CONTRASTE;
00231 int *NBFS;
00232 {
00233
00234 register unsigned int i, j;
00235 int objets;
00236 int nlf = 2;
00237 int bord = 1;
00238 int nbm = sizeof(pixu1);
00239 int nbfs;
00240 int nargs;
00241
00242
00243
00244 connex_8 = (*CONNEX != 4);
00245 negatif = (*CONTRASTE < (int) 0);
00246 seuil = negatif ? 0 : 1;
00247 if (*SEUIL > seuil) seuil = *SEUIL;
00248 nbfs = (*NBFS > 0) ? *NBFS : 0;
00249 masque = connex_8 ? 0xF : 0x7;
00250 ENTREE = IMA_IN->p ; SORTIE = IMA_EX->p ;
00251 np = IMA_IN->nc ; nl = IMA_IN->nr ;
00252
00253
00254
00255 if ((t_lut = (pixu2 *) calloc (TAILLE_TABLE, sizeof(pixu2))) == NULL) {
00256 fprintf (stderr,"\n*** ETIQ *** Memoire insuffisante.\n");
00257 exit(2);
00258 }
00259 t_lut[0] = 0;
00260
00261
00262
00263
00264 ETIQ_S1 () ;
00265
00266
00267
00268 for (objets = 1; objets <= (int) etiq; objets++) {
00269 i = objets; do { j = i; i = t_lut[i]; } while (i != j);
00270 t_lut[objets] = i;
00271 }
00272 objets = 0;
00273 for (i = 1; i <= (int) etiq; i++) {
00274 j = t_lut[i];
00275 t_lut[i] = (pixu2) ((j == i) ? new_object : t_lut[j]);
00276 }
00277 fprintf (stdout, "\n*** ETIQ *** %u objets d‚nombr‚s.\n", objets);
00278
00279
00280
00281 ETIQ_S2 () ;
00282
00283
00284 free (t_lut);
00285
00286 return ((int) objets);
00287
00288 }
00289 #undef new_object
00290
00291
00292
00293
00294
00295
00296 #define new_label(X) \
00297 if (etiq == (pixu2) (TAILLE_TABLE - 1)) { \
00298 fprintf (stderr, "\n*** ETIQ *** table satur‚e\n"); \
00299 exit (2); \
00300 } \
00301 X = ++etiq;
00302
00303 #define merge(X, Y) if (X < Y) Y = t_lut[Y] = X; else X = t_lut[X] = Y;
00304
00305 ETIQ_S1 ()
00306 {
00307
00308 register int i,j;
00309 register unsigned int ouest, aux;
00310 unsigned int nord, nord_ouest;
00311 int status;
00312 pixu2 *ptr1, *ptr2 , *bid ;
00313
00314
00315 ptr1 = (pixu2 *) malloc ( np * sizeof ( pixu2 ) ) ;
00316 ptr2 = (pixu2 *) malloc ( np * sizeof ( pixu2 ) ) ;
00317
00318 for ( i = 0 ; i < np ; ptr2[i++] = 0 ) ;
00319
00320 etiq = 0 ;
00321
00322
00323
00324 for ( j = 0 ; j < nl ; j ++ ) {
00325 bid = ptr1 ;
00326 ptr1 = ptr2 ;
00327 ptr2 = bid ;
00328
00329 if (negatif) for (i = 0 ; i < np ; i++)
00330 ptr2[i] = (pixu2) (( (int) ENTREE[j][i] <= seuil) ? -1 : 0);
00331 else
00332 if (seuil > 1) for (i = 0 ; i < np ; i++)
00333 ptr2[i] = (pixu2)(( (int) ENTREE[j][i] >= seuil) ? -1 : 0);
00334 else for ( i = 0 ; i < np ; i++ )
00335 ptr2[i] = (pixu2) ENTREE[j][i] ;
00336
00337
00338 nord_ouest = ouest = status = 0;
00339 for (i = 0 ; i < np ; i++) {
00340 status = (status << 2) & masque;
00341 if ((nord = ptr1[i]) != 0) {
00342 while ((aux = t_lut[nord]) != nord) nord = aux;
00343 status += 2;
00344 }
00345 if (ptr2[i] != 0) status++;
00346 switch (status) {
00347 case 3:
00348 case 11:
00349 ouest = nord;
00350 case 5:
00351 case 13:
00352 case 15:
00353 break;
00354
00355 case 1:
00356 new_label (ouest);
00357 t_lut[ouest] = ouest;
00358 break;
00359
00360 case 7:
00361 merge (nord, ouest);
00362 break;
00363
00364 case 9:
00365 ouest = nord_ouest;
00366 break;
00367
00368 case 6:
00369 if (connex_8) merge (nord, ouest);
00370 default:
00371 ouest = 0;
00372 }
00373 ptr2[i] = (pixu2) ouest; nord_ouest = nord;
00374 }
00375 }
00376 }
00377 #undef merge
00378 #undef new_label
00379
00380
00381
00382
00383
00384
00385 #define merge(X, Y) if (X < Y) Y = X; else X = Y;
00386
00387 ETIQ_S2 ()
00388 {
00389
00390 register int i,j;
00391 register unsigned int ouest, aux;
00392 unsigned int nord, nord_ouest;
00393 int status;
00394 pixu2 *ptr1, *ptr2 , *bid ;
00395
00396 ptr1 = (pixu2 *) malloc ( np * sizeof ( pixu2 ) ) ;
00397 ptr2 = (pixu2 *) malloc ( np * sizeof ( pixu2 ) ) ;
00398
00399 etiq = 0 ;
00400
00401 for ( i = 0 ; i < np ; ptr2[i++] = 0 ) ;
00402
00403
00404
00405
00406 for ( j = 0 ; j < nl ; j ++ ) {
00407 bid = ptr1 ;
00408 ptr1 = ptr2 ;
00409 ptr2 = bid ;
00410
00411 if (negatif) for (i = 0 ; i < np ; i++)
00412 ptr2[i] = (pixu2) (( (int) ENTREE[j][i] <= seuil) ? -1 : 0);
00413 else
00414 if (seuil > 1) for (i = 0 ; i < np ; i++)
00415 ptr2[i] = (pixu2)(( (int) ENTREE[j][i] >= seuil) ? -1 : 0);
00416 else for ( i = 0 ; i < np ; i++ )
00417 ptr2[i] = (pixu2) ENTREE[j][i] ;
00418
00419
00420 nord_ouest = ouest = status = 0;
00421 for (i = 0; i < np ; i++) {
00422 status = (status << 2) & masque;
00423 if ((nord = ptr1[i]) != 0) status += 2;
00424 if (ptr2[i] != 0) status++;
00425 switch (status) {
00426 case 3:
00427 case 11:
00428 ouest = nord;
00429 case 5:
00430 case 13:
00431 case 15:
00432 break;
00433
00434 case 1:
00435 ouest = ++etiq;
00436 break;
00437
00438 case 7:
00439 merge (nord, ouest);
00440 break;
00441
00442 case 9:
00443 ouest = nord_ouest;
00444 break;
00445
00446 case 6:
00447 if (connex_8) merge (nord, ouest);
00448 default:
00449 ouest = 0;
00450 }
00451 ptr2[i] = (pixu2) ouest;
00452 nord_ouest = nord;
00453 SORTIE[j][i] = (pixu2) t_lut[ouest];
00454 }
00455 }
00456 }
00457