lreggrow.c

00001 /*
00002 *    Copyright (c) 2007. The BATI team. All right reserved.
00003 *
00004 *    This file is part of BATI library.
00005 *
00006 *    BATI library is free software: you can redistribute it and/or modify
00007 *    it under the terms of the GNU General Public License as published by
00008 *    the Free Software Foundation, either version 3 of the License, or
00009 *    (at your option) any later version.
00010 *
00011 *    BATI library  is distributed in the hope that it will be useful,
00012 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *    GNU General Public License for more details.
00015 *
00016 *    You should have received a copy of the GNU General Public License
00017 *    along with BATI library.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00033 #include "image.h"
00034 #include "proto2D.h"
00035 #include <stdlib.h>
00036 #include <math.h>
00037 #include "reggrow.h"
00038 
00039 #define ABSOL(x,y)  (((x) > (y))? abs(x-y) : abs(y-x))
00040 #define MAX(x,y) (((x)>(y))? (x):(y))
00041 #define MIN(x,y) (((x)<(y))? (x):(y))
00042 #define ETMAX 65535L            /* nbre maximum d'etiquettes */
00043 
00044 
00045 /* **********************  LECTURE DE PARAMETRES   *************************/
00059 param * reggrow_lect(reggrow_t *des, param *ptp, char *debq){
00060   char question[500];
00061 
00062   sprintf(question, "%s nb d'iteration ", debq); 
00063   lec_param(question, ptp);
00064   des->nb_loop = atoi(ptp->rep);
00065   ptp = ptp->next; 
00066 
00067   sprintf(question, "%s seuil de depart aggreg de 2 regions ", debq); 
00068   lec_param(question, ptp);
00069   des->seuil0 = atoi(ptp->rep);
00070   ptp = ptp->next;
00071  
00072   sprintf(question, "%s increment du seuil ", debq); 
00073   lec_param(question, ptp);
00074   des->step = atoi(ptp->rep);
00075   ptp = ptp->next; 
00076 
00077   sprintf(question, "%s taille minimum d'une region ", debq); 
00078   lec_param(question, ptp);
00079   des->taille = atoi(ptp->rep);
00080   ptp = ptp->next;
00081 
00082   return(ptp);
00083 }
00084 
00085 
00086 
00087 
00088 
00089 etiq(unsigned char *iorg,/* adr de l'image origine (initiale ou segmentee) */
00090      int *ilab,/* adresse de l'image destination (etiquettes) */
00091      int Y,/* taille de l'image */
00092      int X,/* taille de l'image */
00093      int seuil,/* seuil d'agregation de deux regions */
00094      int *pnlab,
00095      int *pneff)
00096 {
00097         int i,j;
00098         unsigned char *io;      /* pointeur intermediaire image origine */
00099         int *il;                /* pointeur intermediaire image etiquettes */
00100 
00101         int reg,k;
00102 
00103         int *ptet;              /* pointeur tableau d'etiquettes */
00104         
00105         int count;              /* compteur des etiquettes */
00106         int cas;                                
00107 
00108 
00109 /* ===========================================================================
00110 *               initialisation du tableau de chainage
00111 * ===========================================================================
00112 */
00113                 ptet = (int*)calloc(ETMAX,sizeof(*ptet)); /* allocation du tableau */
00114                 if(ptet == NULL){
00115                   printf("error ALLOC\n");
00116                   exit(1);
00117                 }
00118 
00119                 for(k = 0;k < ETMAX ; k++ )             /* initialisation */
00120                    ptet[k] = k;  
00121 
00122                 count = 0;
00123                 
00124 /* =============================================================================
00125 *               initialisation de l'image des etiquettes
00126 * =============================================================================
00127 */
00128                 printf("init image\n");
00129                 il = ilab - 1;
00130                 for(i = Y; i--;) 
00131                   for(j = X; j--;) {
00132                      ++il;
00133                      *il = 0;
00134                 }
00135 
00136 /* ===========================================================================
00137 *               traitement de la premiere ligne
00138 * ===========================================================================
00139 */
00140                 il = ilab - 1;
00141                 *++il = 0;              /* premier pixel etiquete a 0 */
00142                 io = iorg - 1;
00143                 ++io;
00144 
00145 /* etiquetage des autres pixels de la ligne */
00146 
00147                 j = X - 1;
00148                 while(j--) {
00149                    ++io; ++il;
00150                    cas = 0;
00151                                 
00152                    if(ABSOL(*io,*(io - 1)) < seuil)
00153                       cas += 2;
00154                    ordre(cas,il,ptet,&count,X);
00155                 }
00156 
00157 /* =========================================================================
00158 *               traitement pour les autres lignes
00159 * =========================================================================
00160 */
00161                 for(i = Y - 1; i--;)
00162                    for(j = X; j--;) {
00163                       ++io; ++il;
00164                                 /* traitement de la premiere colonne */
00165 
00166                         if(j == X) {            
00167                            cas = 0;
00168                            if(ABSOL( *io , *(io - X)) < seuil)
00169                               cas += 1;
00170                            ordre(cas,il,ptet,&count,X);
00171                         } else {
00172                            cas = 0;
00173                            if(ABSOL(*io , *(io - X)) < seuil)
00174                                 cas += 1;
00175                            if(ABSOL(*io , *(io - 1)) < seuil)
00176                                 cas += 2;
00177                            if(ABSOL(*(io - 1) , *(io - X)) < seuil)
00178                                 cas += 4;
00179                            ordre(cas,il,ptet,&count,X);
00180                         }               
00181                         //printf("count = %d\n", count);
00182                         if( count >= ETMAX) {
00183                            exit(printf("too many labels nblab=%d\n",count));
00184                         abort();
00185                         }
00186                    }
00187                 *pnlab = count + 1;
00188                 retiq(ilab,Y,X,ptet,pnlab,&reg,pneff);
00189                 *pnlab = reg;
00190                 cfree(ptet);            /* liberation du tableau */
00191 
00192 }
00193 
00194 
00195 
00196     
00197 etiq1(
00198       unsigned char *iorg,      /* adresse de l'image origine (initiale ou segmentee) */
00199       int *ilab,                /* adresse de l'image destination (etiquettes) */
00200       int Y, int X,             /* taille de l'image */
00201       int seuil,                /* seuil d'agregation de deux regions */
00202       int *pnlab,
00203       int *pneff)
00204 {
00205                 int i,j;
00206                 unsigned char *io;
00207                 int *il;
00208 
00209                 int reg,k;
00210 
00211                 int *ptet;      /* pointeur d'etiquettes */
00212                 
00213                 int count;      /* compteur des etiquettes */
00214                 int cas;
00215 /*
00216  * initialisation du tableau de chainage
00217  */
00218                 ptet = (int*)calloc(ETMAX,sizeof(*ptet)); /* allocation du tableau */
00219 
00220                 for(k = 0;k < ETMAX ; k++ )     /* initialisation */
00221                    ptet[k] = k;  
00222 
00223                 count = 0;
00224                 
00225 /* 
00226 *               traitement de la premiere ligne
00227 * 
00228 */
00229 
00230                 il = ilab - 1;
00231                 *++il = 0;              /* premier pixel etiquete a 0 */
00232                 io = iorg - 1;
00233                 ++io;
00234 
00235 /* etiquetage des autres pixels de la ligne */
00236 
00237                 j = X - 1;
00238                 while(j--) {
00239                    ++io; ++il;
00240                    cas = 0;
00241                                 
00242                    if(ABSOL(*io,*(io - 1)) < seuil)
00243                         cas += 2;
00244                    ordre(cas,il,ptet,&count,X);
00245                 }
00246 
00247 /* 
00248 *               traitement pour les autres lignes
00249 *
00250 */
00251         for(i = Y - 1; i--;)
00252            for(j = X; j--;) {
00253                 ++io; ++il;
00254 
00255 /* traitement de la premiere colonne */
00256 
00257                 if(j == X) {    
00258                    cas = 0;
00259                    if(ABSOL(*io , *(io - X)) < seuil)
00260                       cas += 1;
00261                    ordre(cas,il,ptet,&count,X);
00262                 } else {
00263                    cas = 0;
00264                    if(ABSOL(*io , *(io - X)) < seuil)
00265                         cas += 1;
00266                    if(ABSOL(*io , *(io - 1)) < seuil)
00267                         cas += 2;
00268                    if(ABSOL(*(io - 1) , *(io - X)) < seuil)
00269                         cas += 4;
00270                    ordre(cas,il,ptet,&count,X);
00271                 }       
00272                 
00273                 if( count >= ETMAX)
00274                    exit(printf("too many labels nblab=%d\n",count));
00275            }
00276         
00277         *pnlab = count + 1;
00278         retiq(ilab,Y,X,ptet,pnlab,&reg,pneff);
00279         *pnlab = reg;
00280         cfree(ptet);            /* liberation du tableau */
00281 
00282 }
00283 
00284 
00285 
00286 /* **********************  INITIALISATION  *****************************/
00296 int reggrow_init(reggrow_t *des, imau1 *im0, imau1 *imres){
00297   /* image resultat */ 
00298   alloc_imau1_as( im0, imres);
00299   return(0);  
00300 }
00301 
00302 
00303 
00304 
00305 moyenne(
00306      unsigned char *iorg,
00307   unsigned char *ides,
00308   int *ilab,
00309   int Y,int X,
00310   int nlab,
00311 int taille,                     /* taille minimum d'une region */
00312 int *nreg)                      /* nombre de  region */
00313 {
00314         int i,j;
00315         unsigned char *io,*ds;
00316         int *il, val;
00317         int k,n;
00318         int *lut;
00319         long *npel,*sums;
00320 
00321         if ((lut = (int*)calloc(nlab,sizeof(*lut))) == NULL)
00322                 exit(printf("no more free space\n"));
00323         if ((npel = (long *)calloc(nlab,sizeof(*npel))) == NULL)
00324                 exit(printf("no more free space\n"));
00325         if ((sums = (long *)calloc(nlab,sizeof(*sums))) == NULL)
00326                 exit(printf("no more free space\n"));
00327 
00328         /* initialisation des tableaux */
00329         for(k = nlab; k--;) {
00330           lut[k]=0;
00331           npel[k] = 0;
00332           sums[k] = 0;
00333         }
00334 
00335         /* balayage de l'image */
00336 
00337         io = iorg - 1;
00338         il = ilab - 1;
00339         for(i = Y; i--;)
00340            for(j = X; j--;) {
00341                 val = *++il;
00342                 npel[val]++;
00343                 sums[val] = sums[val] +  (long)*++io;
00344            }
00345 
00346         /* calcul de la lut */
00347         *nreg = 0;
00348         for (i = 0; i < nlab; i++) {
00349                 if (npel[i] > taille) {
00350                    lut[i] = sums[i] / npel[i];
00351                    (*nreg)++;
00352                 }
00353                 else 
00354                    lut[i] = 0x00;
00355         } 
00356 
00357         /* passage de l'image dans la lut */
00358         il = ilab - 1;
00359         ds = ides - 1;
00360         for (i = Y; i--; )
00361            for (j = X; j--; )
00362               *++ds = lut[*++il];
00363 
00364         cfree(lut);
00365         cfree(npel);
00366         cfree(sums);
00367 }
00368 
00369 
00370 ordre( int cas, 
00371        int X,
00372        int *il,
00373        int ptet[ETMAX],
00374        int *pn)
00375 {
00376 
00377         int a,b;
00378         int count;
00379 
00380         a = *(il - X);
00381         b = *(il - 1);
00382         count = *pn;
00383 
00384         switch (cas) {
00385         case 0 : {
00386                 /* on attribue une nouvelle etiquette
00387                    ou bien on ne fait rien */
00388                 *il = ++count;
00389                 *pn = count;
00390                 return;
00391                 }
00392         case 1 : {
00393                 /* propagation de l'etiquette du haut
00394                 */
00395                 *il = ptet[*(il - X)];
00396                 return;
00397                 }
00398         case 2 : {
00399                 /* propagation de l'etiquette de gauche
00400                 */
00401                 *il = *(il - 1);
00402                 return;
00403                 }
00404         case 3 : {
00405                 /* equivalence des trois etiquettes
00406                 */
00407                 
00408                 if (ptet[a] != b)
00409                         ptet[MAX(ptet[a],b)] = MIN(ptet[a],b);
00410                 *il = MIN(ptet[a],b);
00411                 return;
00412                 }
00413         case 4 : {
00414                 /* nouvelle etiquette
00415                 */
00416                 *il = ++count;
00417                 *pn = count;
00418                 return;
00419                 }
00420         case 5 : {
00421                 /* equivalence des trois etiquettes
00422                 */
00423                 
00424                 if (ptet[a] != b)
00425                         ptet[MAX(ptet[a],b)] = MIN(ptet[a],b);
00426                 *il = MIN(ptet[a],b);
00427                 return;
00428                 }
00429         case 6 : {
00430                 /* equivalence des trois etiquettes
00431                 */
00432                 
00433                 if (ptet[a] != b)
00434                         ptet[MAX(ptet[a],b)] = MIN(ptet[a],b);
00435                 *il = MIN(ptet[a],b);
00436                 return;
00437                 }
00438         case 7 : {
00439                 /* equivalence des trois etiquettes
00440                 */
00441                 
00442                 if (ptet[a] != b)
00443                 ptet[MAX(ptet[a],b)] = MIN(ptet[a],b);
00444                 *il = MIN(ptet[a],b);
00445                 return;
00446                 }
00447         default :
00448                 exit(printf("ordre: case default\n"));
00449         }
00450 }
00451 
00452 
00453 
00454 
00455 
00456 /* ============================================================================
00457 *  re-etiquetage apres mise a jour du chainage
00458 * ============================================================================
00459 */
00460 
00461 
00462 
00463 retiq(
00464       int *ilab,
00465       int Y, int X,
00466       int ptet[ETMAX],
00467       int *pnlab,
00468       int *preg,
00469       int *pneff)
00470 {
00471         int *il;
00472         int i,j;
00473         int k,kmax;
00474         int nlab;
00475 
00476         nlab = *pnlab;
00477 
00478         for (k = 0; k < nlab; k++) {
00479                 if (ptet[k] != k) 
00480                  ptet[k] = ptet[ptet[k]];
00481         }
00482 
00483         kmax = 0;
00484         *preg = 0;
00485 
00486         il = ilab - 1;
00487         for(i = Y; i--;)
00488                 for(j = X; j--;) {
00489                 ++il;
00490                 *il = ptet[*il];
00491                 if(*il > *preg) {
00492                         ++kmax;
00493                         *preg = *il;
00494                 }
00495                 }
00496         ++kmax; ++(*preg);
00497         *pneff = kmax;
00498 }
00499 
00500 
00501 
00512 int reggrow_calc(reggrow_t *des, imau1 *imaIn, imau1 *imaOut){
00513 
00514   int           n_ima;                          /* compteur d'images */
00515   unsigned char *iorg=(unsigned char *)imaIn->p[0];
00516   unsigned char *ides=(unsigned char *)imaOut->p[0];
00517   int           *ilab;                          /* images etiquettes */
00518   int           Y=imaIn->nr,X=imaIn->nc;        /* taille des images */
00519   int           nb_loop=des->nb_loop;           /* nombre d'iteration */
00520   int           seuil0=des->seuil0;             /* seuil de depart aggreg de 2 regions */
00521   int           seuil=seuil0;                   /* seuil aggregation de deux regions */
00522   int           step=des->step;                 /* increment du seuil */
00523   int           taille=des->taille;             /* taille minimum d'une region */
00524   int           nlab,neff,nreg;                 /* nombre d'etiquettes */
00525   register int          i,j;
00526 /* ===========================================================================
00527 *                               premier etiquettage
00528 * ===========================================================================
00529 */
00530 
00531   ilab = (int*)calloc( X*Y ,sizeof(int) );
00532      nlab = 0;
00533      neff = 0;
00534      etiq(iorg,ilab,Y,X,seuil,&nlab,&neff);
00535      printf("nb d'etiquettes utilisees = %d \n",nlab);
00536      printf("nb d'etiquettes effectives avant agregation = %d\n",neff);
00537 
00538      moyenne(iorg,ides,ilab,Y,X,nlab,0,&nreg);
00539      printf("nb d'etiquettes effectives apres agregation = %d\n",nreg);
00540      //if( visu == 1) { aff_sun(ides,Y,X,5); }
00541     
00542 /* ===========================================================================
00543 *                               iteration de l'etiquettage
00544 * ===========================================================================
00545 */
00546 
00547      for (i = 0; i < nb_loop; i++) {
00548 
00549        printf("iteration %d\n",i);
00550 
00551        seuil += step;
00552        printf("seuil: %d\n",seuil);
00553        
00554        etiq1(ides,ilab,Y,X,seuil,&nlab,&neff);
00555        printf("nb d'etiquettes utilisees = %d\n",nlab);
00556        printf("nb d'etiquettes effectives avant agregation = %d\n",neff);
00557        if (i == nb_loop - 1)
00558          {                                      /* derniere iteration */
00559            moyenne(iorg,ides,ilab,Y,X,nlab,taille,&nreg);
00560          }
00561        else
00562          {
00563            moyenne(iorg,ides,ilab,Y,X,nlab,0,&nreg);
00564          }
00565        printf("nb d'etiquettes effectives apres agregation = %d\n",nreg);
00566 
00567      }
00568   return(0);
00569 }
00570 

Generated on Tue Apr 22 13:31:04 2008 for ima2D by  doxygen 1.5.3