/* ------------------------------------------------------------------------------------------------------------------ * Write and read values * Regardless of namespaces, the string keys app_path and data_path always refer to the location of the application's executable * and the data path, respectively. These values are never saved to the configuration, but kept in static variables. * The application makes use of this by "writing" to the configuration file after determining these values at runtime. */ void ConfigManager::Write(const wxString& name, const wxString& value, bool ignoreEmpty) { if (name.IsSameAs(CfgMgrConsts::app_path)) { return; } else if (name.IsSameAs(CfgMgrConsts::data_path)) { data_path_global = value; return; } if (ignoreEmpty && value.IsEmpty()) { UnSet(name); return; } wxString key(name); TiXmlElement* e = AssertPath(key); TiXmlElement *str = GetUniqElement(e, key); TiXmlElement *s = GetUniqElement(str, _T("str")); TiXmlText t(value.mb_str(wxConvUTF8)); t.SetCDATA(true); SetNodeText(s, t); }
/* ==================================== */ int32_t testabaisse(uint8_t *SOURCE, int32_t x, int32_t rs, int32_t N, int32_t seuil, int32_t niter, int32_t niseuil) /* ==================================== */ { int32_t t4mm, t4m, t8p, t8pp; int32_t modifie = 0; #ifdef DEBUG printf("testabaisse : point %d (%d %d), val = %d\n", x, x%rs, x/rs, SOURCE[x]); #endif nbtopo(SOURCE, x, rs, N, &t4mm, &t4m, &t8p, &t8pp); if (t4mm == 2) Set(x, COURBE); #ifdef REGULARISE if (IsSet(x, COURBE)) { int32_t valmaxmin = -1; int32_t k, y; /* si c'est un point de courbe "inconsistant", on l'abaisse def. x inconsistant : l'ecart entre F(x) et la valeur du minimum voisin le plus proche est < seuil */ for (k = 0; k < 8; k += 2) /* parcourt les voisins en 4-connexite */ { y = voisin(x, k, rs, N); if ((y != -1) && (IsSet(y, MINI)) && ((int32_t)(SOURCE[y]) > valmaxmin)) valmaxmin = (int32_t)(SOURCE[y]); } /* for k */ if ((valmaxmin > -1) && ((SOURCE[x] - (uint8_t)valmaxmin) < seuil)) { modifie = 1; SOURCE[x] = (uint8_t)valmaxmin; UnSet(x, COURBE); } } #endif /* if (!IsSet(x, COURBE) && */ if ((niter <= niseuil) || !extremite8(SOURCE, x, rs, N)) { while ((t4mm == 1) && (t8p == 1)) { modifie = 1; SOURCE[x] = alpha8m(SOURCE, x, rs, N); nbtopo(SOURCE, x, rs, N, &t4mm, &t4m, &t8p, &t8pp); } } /* if (!extremite8(SOURCE, x, rs, N)) */ #ifdef DEBUG if (modifie) printf("========> ABAISSE : %d\n", SOURCE[x]); #endif return modifie; } /* testabaisse() */
/* ==================================== */ void testmini(uint8_t *SOURCE, int32_t x, int32_t rs, int32_t N, Fifo *FIFO) /* ==================================== */ { int32_t k, y, kk, yy, w; uint8_t valmin; #ifdef REGULARISE for (k = 0; k < 8; k += 2) /* parcourt les voisins en 4-connexite */ { /* pour voir s'il existe un minimum voisin */ y = voisin(x, k, rs, N); /* a un niveau > a celui atteint par x */ if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] > SOURCE[x])) { /* ce n'est plus un minimum */ FifoPush(FIFO, y); UnSet(y, MINI); valmin = SOURCE[y]; while (! FifoVide(FIFO)) /* parcours pour demarquer l'ex minimum */ { w = FifoPop(FIFO); for (kk = 0; kk < 8; kk += 2) { yy = voisin(w, kk, rs, N); if ((yy != -1) && (SOURCE[yy] == valmin) && (IsSet(yy, MINI))) { FifoPush(FIFO, yy); UnSet(yy, MINI); } } /* for kk ... */ } /* while (! FifoVide(FIFO)) */ } /* if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] > SOURCE[x])) */ } /* for k */ #endif for (k = 0; k < 8; k += 2) /* parcourt les voisins en 4-connexite */ { /* pour voir s'il existe un minimum */ y = voisin(x, k, rs, N); /* au niveau atteint par x */ if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] == SOURCE[x])) { Set(x, MINI); break; } } /* for k */ } /* testmini() */
void Bitfield::Invert() { if( _isempty() ) { SetAll(); } else if( _isfull() ) { Clear(); } else { bt_index_t i = 0; bt_index_t s = nset; for( ; i < nbytes - 1; i++ ) b[i] = ~b[i]; if( nbits % 8 ) { for( i = 8 * (nbytes - 1); i < nbits; i++ ) { if( _isset(i) ) UnSet(i); else _set(i); } } else b[nbytes - 1] = ~b[nbytes - 1]; nset = nbits - s; } }
static ubyte tcCarFound(Car car, U32 time) { S32 i = 0, hours; Person john = dbGetObject(Person_John_Gludo); Person miles = dbGetObject(Person_Miles_Chickenwing); ubyte found = 0; /* Der Jaguar darf nicht gefunden werden - sonst k�nnte er ja */ /* nicht explodieren! */ if (car != dbGetObject(Car_Jaguar_XK_1950)) { if (tcIsCarRecognised(car, time)) { /* Wagen wird erkannt! */ Say(BUSINESS_TXT, 0, john->PictID, "CAR_RECOG"); hours = CalcRandomNr(2L, 5L); while ((i++) < hours) { AddVTime(60); inpDelay(35); ShowTime(2); } if (!tcIsCarRecognised(car, time)) { /* Wagen wird nicht gefunden */ Say(BUSINESS_TXT, 0, john->PictID, "CAR_NOT_FOUND"); car->Strike = CalcRandomNr(200, 255); } else { /* Wagen wird gefunden! */ found = 1; Say(BUSINESS_TXT, 0, john->PictID, "CAR_FOUND"); Say(BUSINESS_TXT, 0, miles->PictID, "GUTE_ARBEIT"); UnSet(dbGetObject(Person_Matt_Stuvysunt), Relation_has, car); } } } return found; }
/* ==================================== */ void saturation(int32_t rs, int32_t cs, int32_t N, uint8_t *F, Fahp * FAHP) /* ==================================== */ { int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t t4mm, t4m, t8p, t8pp; int32_t level; #ifdef DEBUG uint8_t oldFx; #endif while (!FahpVide(FAHP)) { level = FahpNiveau(FAHP); x = FahpPop(FAHP); UnSet(x, EN_FAHP); UnSet(x, EN_FAHP2); if ((F[x] > 0) && (level <= NDG_MAX)) { nbtopoh(F, x, 1, rs, N, &t4mm, &t4m, &t8p, &t8pp); if (t4mm == 1) { if (pdestr4(F, x, rs, N)) { #ifdef DEBUG oldFx = F[x]; #endif if (!ridge(F, x, rs, N)) F[x] = 0; else F[x] = alpha8m(F, x, rs, N); #ifdef DEBUG printf("point %d (%d %d), val = %d --> %d\n", x, x%rs, x/rs, oldFx, F[x]); #endif for (k = 0; k < 8; k += 1) /* parcourt les voisins en 8-connexite */ { /* pour empiler les voisins */ y = voisin(x, k, rs, N); /* non deja empiles */ if ((y != -1) && (F[y] > 0) && (! IsSet(y, EN_FAHP))) { FahpPush(FAHP, y, F[y]); Set(y, EN_FAHP); } /* if y */ } /* for k */ } /* if (pdestr4(F, x, rs, N)) */ } /* if (t4mm == 1) */ else /* t4mm != 1 */ { if (pdestr4(F, x, rs, N)) /* point divergent */ { F[x] = alpha8m(F, x, rs, N); for (k = 0; k < 8; k += 1) /* parcourt les voisins en 8-connexite */ { /* pour empiler les voisins */ y = voisin(x, k, rs, N); /* non deja empiles */ if ((y != -1) && (F[y] > 0) && (! IsSet(y, EN_FAHP))) { FahpPush(FAHP, y, F[y]); Set(y, EN_FAHP); } /* if y */ } /* for k */ } /* if (pdestr4(F, x, rs, N)) */ } /* else if (t4mm == 1) */ } /* ((F[x] > 0) && (F[x] <= NDG_MAX)) */ } /* while (! (FifoVide(FAHP) ...)) */ } /* saturation() */
int32_t MSF(struct xvimage *ga, struct xvimage *marqueurs) #undef F_NAME #define F_NAME "MSF" { int32_t i; int32_t u,v; /* une arete */ int32_t x,y,z, x_1,y_1; /* des sommets */ int32_t rs = rowsize(ga); /* taille ligne */ int32_t cs = colsize(ga); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *F = UCHARDATA(ga); /* valuation des aretes de depart */ int32_t *G = SLONGDATA(marqueurs); /* labels des sommets du graph */ int32_t N_t=2*N; /* index maximum d'un arete de ga */ Rbt *L; /* ensembles des aretes adjacentes à exactement un label */ if (depth(ga) != 1){ //fprintf(stderr, "%s: cette version ne traite pas les images volumiques, je refile le bebe à une autre version\n", F_NAME); return MSF3d(ga, marqueurs); } if ((rowsize(marqueurs) != rs) || (colsize(marqueurs) != cs)){ fprintf(stderr, "%s: incompatible image sizes\n", F_NAME); return 0; } IndicsInit(N_t); L = mcrbt_CreeRbtVide(N_t); for(u = 0; u < N_t; u ++){ if( ( (u < N) && (u%rs < rs-1)) || ((u >= N) && (u < N_t - rs))){ x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if((mcmin(G[x],G[y]) == 0) && (mcmax(G[x],G[y]) > 0)){ /* u est growing edge */ mcrbt_RbtInsert(&L, (TypRbtKey)F[u], u); Set(u, TRUE); }else Set(u, FALSE); }else Set(u,FALSE); } while(!mcrbt_RbtVide(L)){ u = RbtPopMin(L); #ifdef DEBUG printf("poped arete u no: %d de niveau %d\n",u,F[u]); #endif x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if(G[x] > G[y]){z=x; x=y; y=z;} #ifdef DEBUG printf("extremites de u (%d,%d);(%d,%d) \n",x%rs, x/rs, y%rs, y/rs); #endif if((mcmin(G[x],G[y]) == 0) && (mcmax(G[x],G[y]) > 0)){ /* si u est une growing edge */ #ifdef DEBUG printf("label x: %d, label y :%d\n", G[x], G[y]); #endif G[x] = G[y]; /* parcours des aretes incidente à x */ for(i = 0; i < 4; i++){ v = incidente(x,i,rs,N); if((v != -1) && (!IsSet(v, TRUE))){ /* si v n'est pas dans L */ #ifdef DEBUG printf("aretes incidentes F[%d] %d\n", v, F[v]); #endif x_1 = Sommetx(v,N,rs); y_1 = Sommety(v,N,rs); #ifdef DEBUG printf("extremites de v (%d), incidente à u (%d,%d);(%d,%d) \n",v, x_1%rs, x_1/rs, y_1%rs, y_1/rs); #endif if((mcmin(G[x_1],G[y_1]) == 0) && (mcmax(G[x_1],G[y_1]) > 0)){ /* v est une growing edge */ mcrbt_RbtInsert(&L, (TypRbtKey)F[v], v); Set(v,TRUE); } } } } UnSet(u,TRUE); } for(u = 0; u < N_t; u++) if( ((u < N) && (u%rs < rs-1)) || ((u >= N) && (u < N_t - rs))){ if(G[Sommetx(u,N,rs)] != G[Sommety(u,N,rs)])/*F[u]=255*/; else F[u] = 0; } /* Terminer indicateur + R&B tree ... */ IndicsTermine(); mcrbt_RbtTermine(L); return 1; }
int32_t MSF4d(struct GA4d *ga, struct xvimage4D *marqueurs) #undef F_NAME #define F_NAME "MSF4d" { int32_t i; int32_t u,v; /* une arete */ int32_t x,y,z, x_1,y_1; /* des sommets */ int32_t rs = rowsize(ga); /* taille ligne */ int32_t cs = colsize(ga); /* taille colone */ int32_t ps = rs * cs; /* taille d'un plan */ int32_t ds = depth(ga); /* nbre de plans */ int32_t vs = ps*ds; /* taille volume */ int32_t ss = seqsizeGA(ga); /* nbre de volules*/ int32_t N = ss * vs; uint8_t *F = UCHARDATA(ga); /* graphe d'arere 4d */ uint8_t **G; /* image de marqueurs 4D */ int32_t N_t=4*N; /* index maximum d'une arete de ga */ Rbt *L; /* ensembles des aretes adjacentes à exactement un label */ G = (uint8_t **)malloc(sizeof(char *) * ss); for(i = 0; i < ss; i++) G[i] = UCHARDATA(marqueurs->frame[i]); if ((rowsize(marqueurs->frame[0]) != rs) || (colsize(marqueurs->frame[0]) != cs) || (depth(marqueurs->frame[0]) != ds) || (marqueurs->ss != ss)) { fprintf(stderr, "%s: incompatible image sizes\n", F_NAME); return 0; } IndicsInit(N_t); /*Pas du tout robuste c'est juste qqch pour passer sur des images 4d du coeur*/ L = mcrbt_CreeRbtVide(N_t/10); for(u = 0; u < N_t; u ++){ if( ( (u < N) && (u%rs < rs-1)) || ( (u >= N) && (u < 2*N) && ( (u%ps) < (ps-rs) ) ) || ( (u >= 2*N) && (u < 3*N) && ( (u%vs) < (vs-ps) ) ) || ( (u >= 3*N) && ( (u%N) < (N-vs) ) ) ){ #ifdef DEBUG printf("F[(%d,%d,%d,%d),%d] = %d\n", u%rs, (u%ps)/rs, (u%vs)/ps, (u%N)/vs, u/N,F[u]); #endif x = Sommetx4d(u,N,rs,ps,vs); y = Sommety4d(u,N,rs,ps,vs); /* On pourrait faire plus rapide avec une representation memoire plus adequat des images 4d */ if((mcmin(G[x/vs][x%vs],G[y/vs][y%vs]) == 0) && (mcmax(G[x/vs][x%vs],G[y/vs][y%vs]) > 0)){ /* u est growing edge */ /* printf("Initialisation: ds Rbt: (%d,%d)\n", x,y);*/ mcrbt_RbtInsert(&L, (TypRbtKey)F[u], u); Set(u, TRUE); }else Set(u, FALSE); }else Set(u,FALSE); } printf("Initialisation OK \n"); while(!mcrbt_RbtVide(L)){ u = RbtPopMin(L); #ifdef DEBUG printf("Arete poped F[(%d,%d,%d,%d),%d] = %d\n", u%rs, (u%ps)/rs, (u%vs)/ps, (u%N)/vs, u/N,F[u]); #endif x = Sommetx4d(u,N,rs,ps,vs); y = Sommety4d(u,N,rs,ps,vs); #ifdef DEBUG printf("extremites de u (%d,%d);(%d,%d) \n",x%rs, x/rs, y%rs, y/rs); #endif if((mcmin(G[x/vs][x%vs],G[y/vs][y%vs]) == 0) && (mcmax(G[x/vs][x%vs],G[y/vs][y%vs]) > 0)){ /* si u est une growing edge */ #ifdef DEBUG printf("Arete growing F[(%d,%d,%d,%d),%d] = %d\n", u%rs, (u%ps)/rs, (u%vs)/ps, (u%N)/vs, u/N,F[u]); #endif if(G[x/vs][x%vs] > G[y/vs][y%vs]){z=x; x=y; y=z;} G[x/vs][x%vs] = G[y/vs][y%vs]; /* parcours des aretes incidente à x */ for(i = 0; i < 8; i++){ v = incidente4d(x,i,rs,N,ps,vs); if((v != -1) && (!IsSet(v, TRUE))){ /* si v n'est pas dans L */ #ifdef DEBUG printf("Arete incidentes F[(%d,%d,%d,%d),%d] = %d\n", v%rs, (v%ps)/rs, (v%vs)/ps, (v%N)/vs, v/N,F[v]); #endif x_1 = Sommetx4d(v,N,rs,ps,vs); y_1 = Sommety4d(v,N,rs,ps,vs); #ifdef DEBUG printf("extremites de v (%d), incidente à u (%d,%d);(%d,%d) \n",v, x_1%rs, x_1/rs, y_1%rs, y_1/rs); #endif if((mcmin(G[x_1/vs][x_1%vs],G[y_1/vs][y_1%vs]) == 0) && (mcmax(G[x_1/vs][x_1%vs],G[y_1/vs][y_1%vs]) > 0)){ /* v est une growing edge */ #ifdef DEBUG printf("Arete pushed F[(%d,%d,%d,%d),%d] = %d\n", v%rs, (v%ps)/rs, (v%vs)/ps, (v%N)/vs, v/N,F[v]); #endif mcrbt_RbtInsert(&L, (TypRbtKey)F[v], v); Set(v,TRUE); } } } } UnSet(u,TRUE); } printf("Label map of MSF OK \n"); for(u = 0; u < N_t; u++) if( ( (u < N) && (u%rs < rs-1)) || ( (u >= N) && (u < 2*N) && ( (u%ps) < (ps-rs) ) ) || ( (u >= 2*N) && (u < 3*N) && ( (u%vs) < (vs-ps) ) ) || ( (u >= 3*N) && ( (u%N) < (N-vs) ) ) ){ x = Sommetx4d(u,N,rs,ps,vs); y = Sommety4d(u,N,rs,ps,vs); if(G[x/vs][x%vs] != G[y/vs][y%vs]) F[u] = 255; else F[u] = 0; } /* Terminer indicateur + R&B tree ... */ IndicsTermine(); mcrbt_RbtTermine(L); return 1; }
/*=====================================================================================*/ list * MSF_Prim(MergeTree * MT) /*=====================================================================================*/ /*Segment a tree into two components. Returns a list of nodes correspunding to the Max Spanning Forest cut, computed using Prim's algorithm */ { int32_t i, j,u,v, x,y,z, x_1,y_1; int nb_markers; int nb_leafs; long N, M; // -------- Gathering usefull input graph (MT) informations ----------- float val=0; //weight parameter for leafs. mtree * T= MT->tree; // mergeTreePrint(T); float * W = MT->weights; JCctree *CT = T->CT; int root_node = CT->root; //M = nb nodes M = CT->nbnodes; //N = nb_edges nb_leafs = 0; for (i = 0; i < M; i++) if (CT->tabnodes[i].nbsons == 0) nb_leafs++; nb_markers = nb_leafs+1; N=M+nb_markers; M=N-1; //init Prim //Creates a Red-Black tree to sort edges Rbt *L; IndicsInit(M); L = mcrbt_CreeRbtVide(M); i=0; int sizeL = 0; // Set for already checked edges for(u = 0; u < M; u ++) Set(u, false); // marked nodes uint32_t * SeededNodes = (uint32_t*)malloc(nb_markers*sizeof(uint32_t)); if (SeededNodes == NULL) { fprintf(stderr, "prim : malloc failed\n"); exit(0);} // Resulting node labeling goes into G2 uint8_t * G2 = (uint8_t*)calloc(N ,sizeof(uint8_t)); // fill the array SeededNodes with marked index nodes // fill the tree L only with the marked edges SeededNodes[0]= M; j=1; for (i = 0; i < CT->nbnodes; i++) if (CT->tabnodes[i].nbsons == 0) { SeededNodes[j]= i+CT->nbnodes; G2[SeededNodes[j]] = 2; mcrbt_RbtInsert(&L, (TypRbtKey)(val), SeededNodes[j]); sizeL++; // fprintf(stderr,"L=%d", sizeL); Set(SeededNodes[j], true); j++; } G2[root_node]=1; mcrbt_RbtInsert(&L, (TypRbtKey)(1-W[root_node]), root_node); sizeL++; Set(root_node, true); // weights float * Weights = (float *)malloc(M*sizeof(float)); for(j=0;j<CT->nbnodes;j++) Weights[j]=W[j]; for(j=0;j<nb_leafs;j++) Weights[CT->nbnodes+j]=val; // While there exists unprocessed nodes while(sizeL != 0) { //Pick an edge u of min weight in the tree. u = RbtPopMin(L); // fprintf(stderr, "pop %d\n", u); sizeL--; // Find its extreme nodes (x,y) x = u; // x = G->Edges[0][u]; if (u<CT->nbnodes) y= CT->tabnodes[u].father; else if(u!=M) y= u-CT->nbnodes; else y=root_node; if (y==-1)y=M; //y = G->Edges[1][u]; // y must correspond to the marked node. if(G2[x] > G2[y]) {z=x; x=y; y=z;} // if one node is labeled if((minimum(G2[x],G2[y]) == 0) && (maximum(G2[x],G2[y]) > 0)) { // assign the same label to the other one G2[x] = G2[y]; //fprintf(stderr,"Map[%d]=Map[%d]\n",x,y); // select neighbors edges to place them in the tree j= nb_neighbors(u, CT, nb_leafs); //fprintf(stderr,"nb_neigbors= %d \n",j); for (i=0;i<j;i++) { v = neighbor(u, i, CT, nb_leafs, SeededNodes); if (v==-1)v=M; // fprintf(stderr," %d ",v); // if the edge v is not processed yet if(!IsSet(v, true)) { // Find its extreme nodes (x_1,y_1) x_1 = v; if (v<CT->nbnodes) y_1= CT->tabnodes[v].father; else if(v!=M) y_1= v-CT->nbnodes; else y_1 = root_node; if (y_1==-1)y_1=M; //fprintf(stderr," [%d %d] ",x_1, y_1); if((minimum(G2[x_1],G2[y_1]) == 0) && (maximum(G2[x_1],G2[y_1]) > 0)) { //fprintf(stderr,"( insert %d) ",v); mcrbt_RbtInsert(&L, (TypRbtKey)(1-Weights[v]), v); sizeL++; Set(v,true); } } } // fprintf(stderr," \n"); } UnSet(u,true); } /* for (i=0; i<N; i++) printf("Map[%d]=%d \n",i,G2[i]-1);*/ // Process the tree to find the cut list * cut = NULL; for (i = 0; i < CT->nbnodes; i++) { // nodes having a different value than their father are in the cut if ((CT->tabnodes[i].father != -1) && (G2[CT->tabnodes[i].father] != G2[i])) Insert3(&cut, i); // leafs having the same label as the root are in the cut if ((CT->tabnodes[i].nbsons == 0) && (G2[i]-1==0)) Insert3(&cut, i); } if (cut == NULL) Insert3(&cut, root_node); // PrintList(cut); IndicsTermine(); free(G2); mcrbt_RbtTermine(L); free(SeededNodes); free(Weights); return cut; }
/* ==================================== */ int32_t lsquelsmoothval(struct xvimage *image, // entree/sortie: image originale / squelette struct xvimage *dx, // entree/sortie: distance / distance topologique struct xvimage *ni, // entree/sortie: niveaux - image 1D struct xvimage *gr, // entree: gradient int32_t connex, int32_t val_inhibit, int32_t rayon) /* ==================================== */ #undef F_NAME #define F_NAME "lsquelsmoothval" { int32_t k; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t N = rs * cs; /* taille image */ struct xvimage *dt; /* pour le calcul de la "distance topologique" */ uint32_t *DT; /* fonction "distance topologique" */ uint8_t *IM = UCHARDATA(image); /* l'image de depart */ uint32_t *DX = ULONGDATA(dx); /* fonction distance au complementaire de IM */ uint8_t *NI = UCHARDATA(ni); /* fonction niveau (1D) - taille N * 1 */ uint8_t *GR = UCHARDATA(gr); /* fonction gradient */ uint32_t d; Rbt * RBT; int32_t taillemaxrbt; Liste * cx; // pour le cercle de centre x Liste * cy; // pour le cercle de centre y uint32_t dmax; IndicsInit(N); if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != 1)) { fprintf(stderr, "%s() : bad size for dx\n", F_NAME); return(0); } if (datatype(dx) != VFF_TYP_4_BYTE) { fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME); return(0); } if ((rowsize(ni) != N) || (colsize(ni) != 1) || (depth(ni) != 1)) { fprintf(stderr, "%s() : bad size for ni\n", F_NAME); return(0); } dt = copyimage(dx); DT = ULONGDATA(dt); taillemaxrbt = 2 * rs + 2 * cs ; /* cette taille est indicative, le RBT est realloue en cas de depassement */ RBT = mcrbt_CreeRbtVide(taillemaxrbt); if (RBT == NULL) { fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME); return(0); } for (dmax = 0, x = 0; x < N; x++) if (DX[x] > dmax) dmax = DX[x]; // INITIALISATION DT for (x = 0; x < N; x++) if (IM[x]) DT[x] = INFINI; else DT[x] = 0; // INITIALISATION DU RBT for (x = 0; x < N; x++) if (IM[x] && (DX[x] != val_inhibit) && bordext8(IM, x, rs, N)) { mcrbt_RbtInsert(&RBT, DX[x], x); Set(x, EN_RBT); } // if, for cx = CreeListeVide(2*rs + 2*cs); cy = CreeListeVide(2*rs + 2*cs); d = 1; if (connex == 4) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); UnSet(x, EN_RBT); #ifdef DEBUG printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]); #endif if (simple4(IM, x, rs, N)) { if (smooth(image, x, rayon, cx, cy)) { NI[d] = GR[x]; DT[x] = d; IM[x] = 0; d++; for (k = 0; k < 8; k += 1) /* parcourt les voisins en 8-connexite */ { /* pour empiler les voisins */ y = voisin(x, k, rs, N); /* non deja empiles */ if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT))) { mcrbt_RbtInsert(&RBT, DX[y], y); Set(y, EN_RBT); } /* if y */ } /* for k */ } else { DX[x] += INCR_PRIO; if (DX[x] > dmax) break; mcrbt_RbtInsert(&RBT, DX[x], x); Set(x, EN_RBT); } } // if (simple4(IM, x, rs, N)) } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 4) */ else if (connex == 8) { printf("connex 8 NYI\n"); } /* if (connex == 8) */ // RECUPERATION DU RESULTAT d = 0; // valeur pour l'infini: plus grande valeur finie + 1 for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x]; d += 1; for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x]; /* ================================================ */ /* UN PEU DE MENAGE */ /* ================================================ */ IndicsTermine(); mcrbt_RbtTermine(RBT); freeimage(dt); ListeTermine(cx); ListeTermine(cy); return(1); } /* lsquelsmoothval() */
/* ==================================== */ int32_t lsquelval3d(struct xvimage *image, // entree/sortie: image originale / squelette struct xvimage *dx, // entree/sortie: distance / distance topologique int32_t connex, int32_t val_inhibit) /* ==================================== */ { int32_t i, j, k; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t ps = rs * cs; /* taille plan */ int32_t ds = depth(image); int32_t N = ds * ps; /* taille image */ struct xvimage *dt; /* pour le calcul de la "distance topologique" */ uint8_t *IM = UCHARDATA(image); /* l'image de depart */ uint32_t *DX; /* fonction distance au complementaire de IM */ uint32_t *DT; /* fonction "distance topologique" */ uint32_t d; Rbt * RBT; int32_t taillemaxrbt; int32_t mctopo3d_t6mm, mctopo3d_t26mm, t6p, mctopo3d_t26p; IndicsInit(N); mctopo3d_init_topo3d(); if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != ds)) { fprintf(stderr, "%s() : bad size for dx\n", F_NAME); return(0); } if (datatype(dx) != VFF_TYP_4_BYTE) { fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME); return(0); } DX = ULONGDATA(dx); dt = copyimage(dx); DT = ULONGDATA(dt); taillemaxrbt = 2 * rs * cs + 2 * rs * ds + 2 * ds * cs; /* cette taille est indicative, le RBT est realloue en cas de depassement */ RBT = mcrbt_CreeRbtVide(taillemaxrbt); if (RBT == NULL) { fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME); return(0); } /* ================================================ */ /* PREMIERE PHASE */ /* ================================================ */ #ifdef VERBOSE printf("1ere etape\n"); #endif // INITIALISATION DT for (x = 0; x < N; x++) if (IM[x]) DT[x] = -1; else DT[x] = 0; // INITIALISATION DU RBT for (x = 0; x < N; x++) if (IM[x] && (DX[x] != val_inhibit) && mctopo3d_bordext26(IM, x, rs, ps, N)) { mcrbt_RbtInsert(&RBT, DX[x], x); Set(x, EN_RBT); } // if, for d = 1; if (connex == 6) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); UnSet(x, EN_RBT); if (mctopo3d_simple6(IM, x, rs, ps, N)) { DT[x] = d; IM[x] = 0; d++; for (k = 0; k < 26; k += 1) /* parcourt les voisins en 26-connexite */ { /* pour empiler les voisins */ y = voisin26(x, k, rs, ps, N); /* non deja empiles */ if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT))) { mcrbt_RbtInsert(&RBT, DX[y], y); Set(y, EN_RBT); } /* if y */ } /* for k */ } // if (mctopo3d_simple6(IM, x, rs, N)) } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 6) */ else if (connex == 26) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); UnSet(x, EN_RBT); if (mctopo3d_simple26(IM, x, rs, ps, N)) { DT[x] = d; IM[x] = 0; d++; for (k = 0; k < 26; k += 1) /* parcourt les voisins en 26-connexite */ { /* pour empiler les voisins */ y = voisin26(x, k, rs, ps, N); /* non deja empiles */ if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT))) { mcrbt_RbtInsert(&RBT, DX[y], y); Set(y, EN_RBT); } /* if y */ } /* for k */ } // if (mctopo3d_simple26(IM, x, rs, N)) } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 26) */ /* ================================================ */ /* SECONDE PHASE */ /* ================================================ */ #ifdef VERBOSE printf("2eme etape\n"); #endif // INITIALISATION DU RBT for (k = 1; k < ds-1; k++) for (j = 1; j < cs-1; j++) for (i = 1; i < rs-1; i++) { x = k * ps + j * rs + i; if (DT[x]) mcrbt_RbtInsert(&RBT, DT[x], x); } if (connex == 6) { int32_t abaisse; while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); do { abaisse = 0; mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &t6p, &mctopo3d_t26mm); if ((t6p == 1) && (mctopo3d_t26mm == 1)) { mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &t6p, &mctopo3d_t26mm); if ((t6p == 1) && (mctopo3d_t26mm == 1)) { d = mctopo3d_alpha26m_l((int32_t *)DT, x, rs, ps, N); d = mcmin((DT[x]-1),(d+1)); DT[x] = d; abaisse = 1; } } } while (abaisse); } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 6) */ else if (connex == 26) { int32_t abaisse; while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); do { abaisse = 0; mctopo3d_nbtopoh3d6_l((int32_t *)DT, x, DT[x], rs, ps, N, &mctopo3d_t26p, &mctopo3d_t6mm); if ((mctopo3d_t26p == 1) && (mctopo3d_t6mm == 1)) { mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &mctopo3d_t26p, &mctopo3d_t6mm); if ((mctopo3d_t26p == 1) && (mctopo3d_t6mm == 1)) { d = mctopo3d_alpha26m_l((int32_t *)DT, x, rs, ps, N); d = mcmin((DT[x]-1),(d+1)); DT[x] = d; abaisse = 1; } } } while (abaisse); } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 26) */ // RECUPERATION DU RESULTAT d = 0; for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x]; d += 1; for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x]; /* ================================================ */ /* UN PEU DE MENAGE */ /* ================================================ */ mctopo3d_termine_topo3d(); IndicsTermine(); mcrbt_RbtTermine(RBT); freeimage(dt); return(1); } /* lsquelval3d() */
/* ==================================== */ int32_t lsquelval(struct xvimage *image, // entree/sortie: image originale / squelette struct xvimage *dx, // entree/sortie: distance / distance topologique int32_t connex, int32_t val_inhibit) /* ==================================== */ #undef F_NAME #define F_NAME "lsquelval" { int32_t k; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t N = rs * cs; /* taille image */ struct xvimage *dt; /* pour le calcul de la "distance topologique" */ uint8_t *IM = UCHARDATA(image); /* l'image de depart */ uint32_t *DX; /* fonction distance au complementaire de IM */ uint32_t *DT; /* fonction "distance topologique" */ uint32_t d; Rbt * RBT; int32_t taillemaxrbt; IndicsInit(N); if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != 1)) { fprintf(stderr, "%s() : bad size for dx\n", F_NAME); return(0); } if (datatype(dx) != VFF_TYP_4_BYTE) { fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME); return(0); } DX = ULONGDATA(dx); dt = copyimage(dx); DT = ULONGDATA(dt); taillemaxrbt = 2 * rs + 2 * cs ; /* cette taille est indicative, le RBT est realloue en cas de depassement */ RBT = mcrbt_CreeRbtVide(taillemaxrbt); if (RBT == NULL) { fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME); return(0); } /* ================================================ */ /* PREMIERE PHASE */ /* ================================================ */ #ifdef VERBOSE printf("1ere etape\n"); #endif // INITIALISATION DT for (x = 0; x < N; x++) if (IM[x]) DT[x] = INFINI; else DT[x] = 0; // INITIALISATION DU RBT for (x = 0; x < N; x++) if (IM[x] && (DX[x] != val_inhibit) && bordext8(IM, x, rs, N)) { mcrbt_RbtInsert(&RBT, DX[x], x); Set(x, EN_RBT); } // if, for d = 1; if (connex == 4) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); UnSet(x, EN_RBT); #ifdef DEBUG printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]); #endif if (simple4(IM, x, rs, N)) { DT[x] = d; IM[x] = 0; d++; for (k = 0; k < 8; k += 1) /* parcourt les voisins en 8-connexite */ { /* pour empiler les voisins */ y = voisin(x, k, rs, N); /* non deja empiles */ if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT))) { mcrbt_RbtInsert(&RBT, DX[y], y); Set(y, EN_RBT); } /* if y */ } /* for k */ } // if (simple4(IM, x, rs, N)) } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 4) */ else if (connex == 8) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); UnSet(x, EN_RBT); #ifdef DEBUG printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]); #endif if (simple8(IM, x, rs, N)) { DT[x] = d; IM[x] = 0; d++; for (k = 0; k < 8; k += 1) /* parcourt les voisins en 8-connexite */ { /* pour empiler les voisins */ y = voisin(x, k, rs, N); /* non deja empiles */ if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT))) { mcrbt_RbtInsert(&RBT, DX[y], y); Set(y, EN_RBT); } /* if y */ } /* for k */ } // if (simple8(IM, x, rs, N)) } /* while (!mcrbt_RbtVide(RBT)) */ } /* if (connex == 8) */ #ifdef DEBUG writeimage(dt, "_dt"); #endif /* ================================================ */ /* SECONDE PHASE */ /* ================================================ */ #ifdef SECONDE_PHASE stabilite = 0; while (!stabilite) { #ifdef VERBOSE printf("2eme etape\n"); #endif stabilite = 1; // INITIALISATION DU RBT for (j = 1; j < cs-1; j++) for (i = 1; i < rs-1; i++) { x = j * rs + i; if (DT[x] && (DT[x] != INFINI)) mcrbt_RbtInsert(&RBT, DT[x], x); } if (connex == 4) { while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); #ifdef DEBUG printf("pop x = %d,%d, dt = %ld\n", x%rs, x/rs, DT[x]); #endif if (abaisse4(x, DT, rs, N)) { stabilite = 0; #ifdef DEBUG printf("abaisse a %ld\n", DT[x]); #endif } // if (abaisse4(x, DT, rs, N)) } // while (!mcrbt_RbtVide(RBT)) } // if (connex == 4) else if (connex == 8) { int32_t abaisse; while (!mcrbt_RbtVide(RBT)) { x = RbtPopMin(RBT); #ifdef DEBUG printf("pop x = %d,%d, dt = %d\n", x%rs, x/rs, DT[x]); #endif if (abaisse8(x, DT, rs, N)) { stabilite = 0; #ifdef DEBUG printf("abaisse a %ld\n", DT[x]); #endif } // if (abaisse8(x, DT, rs, N)) } // while (!mcrbt_RbtVide(RBT)) } // if (connex == 8) } // while (!stabilite) #endif // RECUPERATION DU RESULTAT d = 0; // valeur pour l'infini: plus grande valeur finie + 1 for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x]; d += 1; for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x]; /* ================================================ */ /* UN PEU DE MENAGE */ /* ================================================ */ IndicsTermine(); mcrbt_RbtTermine(RBT); freeimage(dt); return(1); } /* lsquelval() */
/* ==================================== */ int32_t lsquel(struct xvimage *image, int32_t seuil, int32_t niseuil) /* ==================================== */ { int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *SOURCE = UCHARDATA(image); /* l'image de depart */ struct xvimage *lab; int32_t *M; /* l'image d'etiquettes de composantes connexes */ int32_t nminima; /* nombre de minima differents */ Fifo * FIFOn; Fifo * FIFOs; Fifo * FIFOe; Fifo * FIFOo; Fifo * FIFOna; Fifo * FIFOsa; Fifo * FIFOea; Fifo * FIFOoa; Fifo * FIFOtmp; Fifo * FIFO; int32_t niter; #ifdef PERF chrono chrono1; #endif if (depth(image) != 1) { fprintf(stderr, "lsquel: cette version ne traite pas les images volumiques\n"); exit(0); } #ifdef PERF start_chrono(&chrono1); /* pour l'analyse de performances */ #endif lab = allocimage(NULL, rs, cs, 1, VFF_TYP_4_BYTE); if (lab == NULL) { fprintf(stderr, "lhtkern: allocimage failed\n"); return 0; } M = SLONGDATA(lab); if (!llabelextrema(image, 4, LABMIN, lab, &nminima)) { fprintf(stderr, "lhtkern: llabelextrema failed\n"); return 0; } IndicsInit(N); FIFO = CreeFifoVide(N); FIFOn = CreeFifoVide(N/2); FIFOs = CreeFifoVide(N/2); FIFOe = CreeFifoVide(N/2); FIFOo = CreeFifoVide(N/2); if ((FIFO == NULL) && (FIFOn == NULL) && (FIFOs == NULL) && (FIFOe == NULL) && (FIFOo == NULL)) { fprintf(stderr, "lsquel() : CreeFifoVide failed\n"); return(0); } /* ================================================ */ /* DEBUT ALGO */ /* ================================================ */ /* ========================================================= */ /* INITIALISATION DES FIFOs: empile les voisins des minima */ /* ========================================================= */ for (x = 0; x < N; x++) { if (M[x] != 0) /* le pixel appartient a un minimum */ { Set(x, MINI); y = voisin(x, NORD, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOn, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, NORD+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOn, y); Set(y, EN_FIFO); } #endif y = voisin(x, EST, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOe, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, EST+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOe, y); Set(y, EN_FIFO); } #endif y = voisin(x, SUD, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOs, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, SUD+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOs, y); Set(y, EN_FIFO); } #endif y = voisin(x, OUEST, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOo, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, OUEST+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOo, y); Set(y, EN_FIFO); } #endif } /* if (M[x] != 0) */ } /* for x */ freeimage(lab); FIFOna = CreeFifoVide(N/4); FIFOsa = CreeFifoVide(N/4); FIFOea = CreeFifoVide(N/4); FIFOoa = CreeFifoVide(N/4); if ((FIFOna == NULL) && (FIFOsa == NULL) && (FIFOea == NULL) && (FIFOoa == NULL)) { fprintf(stderr, "lsquel() : CreeFifoVide failed\n"); return(0); } /* ================================================ */ /* DEBUT SATURATION */ /* ================================================ */ niter = 0; while (! (FifoVide(FIFOn) && FifoVide(FIFOe) && FifoVide(FIFOs) && FifoVide(FIFOo))) { niter++; while (! FifoVide(FIFOn)) { x = FifoPop(FIFOn); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOn)) */ while (! FifoVide(FIFOs)) { x = FifoPop(FIFOs); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOs)) */ while (! FifoVide(FIFOe)) { x = FifoPop(FIFOe); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOe)) */ while (! FifoVide(FIFOo)) { x = FifoPop(FIFOo); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOo)) */ FIFOtmp = FIFOn; FIFOn = FIFOna; FIFOna = FIFOtmp; FIFOtmp = FIFOe; FIFOe = FIFOea; FIFOea = FIFOtmp; FIFOtmp = FIFOs; FIFOs = FIFOsa; FIFOsa = FIFOtmp; FIFOtmp = FIFOo; FIFOo = FIFOoa; FIFOoa = FIFOtmp; } /* while (! (FifoVide(FIFOn) && FifoVide(FIFOe) && FifoVide(FIFOs) && FifoVide(FIFOo))) */ /* ================================================ */ /* UN PEU DE MENAGE */ /* ================================================ */ IndicsTermine(); FifoTermine(FIFO); FifoTermine(FIFOn); FifoTermine(FIFOe); FifoTermine(FIFOs); FifoTermine(FIFOo); FifoTermine(FIFOna); FifoTermine(FIFOea); FifoTermine(FIFOsa); FifoTermine(FIFOoa); #ifdef PERF save_time(N, read_chrono(&chrono1), "lsquel", image->name); #endif return(1); }
/* ==================================== */ int32_t lpropgeo( struct xvimage *img1, struct xvimage *mask, int32_t connex, int32_t function ) /* ==================================== */ #undef F_NAME #define F_NAME "lpropgeo" { int32_t k; int32_t w; int32_t x; int32_t y; uint8_t min; uint8_t max; uint8_t moy; uint8_t minb; uint8_t maxb; uint8_t moyb; uint8_t valcomp; int32_t valcomplong; int32_t mintrouve; int32_t maxtrouve; int32_t moytrouve; int32_t incr_vois; int32_t incr_voisb; int32_t sumndg; /* pour calculer la moyenne sur la composante */ int32_t surf; /* pour calculer la surface de la composante */ int32_t sumndgb; /* pour calculer la moyenne sur le bord */ int32_t sumndgc; /* pour calculer la variance sur le bord */ int32_t surfb; /* pour calculer la surface du bord */ double moybd; /* moyenne sur le bord */ double devb; /* deviation (ecart-type) sur le bord */ int32_t tmp; uint8_t *SOURCE = UCHARDATA(img1); uint8_t *MASK = UCHARDATA(mask); int32_t *MASKLONG = SLONGDATA(mask); int32_t rs = rowsize(img1); int32_t cs = colsize(img1); int32_t N = rs * cs; Lifo * LIFO; #ifdef PERF chrono chrono1; #endif if (depth(img1) != 1) { fprintf(stderr, "%s: cette version ne traite pas les images volumiques\n", F_NAME); return 0; } if (img1->data_storage_type != VFF_TYP_1_BYTE) return lpropgeolong(img1, mask, connex, function); if ((rowsize(mask) != rs) || (colsize(mask) != cs)) { fprintf(stderr, "%s: incompatible image sizes\n", F_NAME); return 0; } switch (connex) { case 4: incr_vois = 2; incr_voisb = 1; break; case 8: incr_vois = 1; incr_voisb = 2; break; default: fprintf(stderr, "%s: mauvaise connexite: %d\n", F_NAME, connex); return 0; } /* switch (connex) */ #ifdef PERF /* pour l'analyse de performances */ start_chrono(&chrono1); #endif IndicsInit(N); LIFO = CreeLifoVide(N); if (LIFO == NULL) { fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME); return(0); } if (mask->data_storage_type == VFF_TYP_1_BYTE) { for (x = 0; x < N; x++) /* recherche dans toute l'image */ { if (!MASK[x]) SOURCE[x] = NDG_MIN; if (MASK[x] && (!IsSet(x, TRAITE1))) /* on est dans une CC non traitee */ { valcomp = MASK[x]; LifoPush(LIFO, x); Set(x, TRAITE1); min = SOURCE[x]; max = SOURCE[x]; minb = NDG_MAX; maxb = NDG_MIN; sumndg = 0; surf = 0; sumndgb = 0; sumndgc = 0; surfb = 0; while (! LifoVide(LIFO)) /* parcourt la CC */ { w = LifoPop(LIFO); if ((SOURCE[w] < min)) min = SOURCE[w]; if ((SOURCE[w] > max)) max = SOURCE[w]; surf += 1; sumndg += SOURCE[w]; for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == valcomp) && (!IsSet(y, TRAITE1))) { LifoPush(LIFO, y); Set(y, TRAITE1); } } /* for k ... */ for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { y = voisin(w, k, rs, N); #ifdef VALEURTABOUE if ((y != -1) && (MASK[y] == 0) && (!IsSet(y, TRAITE1)) && (SOURCE[y] != VALEURTABOUE)) #else if ((y != -1) && (MASK[y] == 0) && (!IsSet(y, TRAITE1))) #endif { if ((SOURCE[y] < minb)) minb = SOURCE[y]; if ((SOURCE[y] > maxb)) maxb = SOURCE[y]; surfb += 1; sumndgb += SOURCE[y]; sumndgc += SOURCE[y] * SOURCE[y]; Set(y, TRAITE1); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ moy = (uint8_t)(sumndg/surf); if (surfb > 0) { moyb = (uint8_t)(sumndgb/surfb); moybd = ((double)sumndgb)/surfb; } else { moyb = 0; moybd = 0.0; } devb = sqrt(((double)sumndgc)/surfb - ((double)sumndgb * sumndgb)/(surfb * surfb)); #ifdef DEBUG printf("composante %d - surf=%d ; sumndg=%d ; surfb=%d ; sumndgb=%d ; max=%d\n", valcomplong, surf, sumndg, surfb, sumndgb, max); #endif LifoPush(LIFO, x); Set(x, TRAITE2); mintrouve = 0; maxtrouve = 0; moytrouve = 0; while (! LifoVide(LIFO)) /* RE-parcourt la CC */ { w = LifoPop(LIFO); switch (function) { case MIN1: if ((SOURCE[w] == min) && !mintrouve) { Set(w, MINIMUM); mintrouve = 1; } break; case MAX1: if ((SOURCE[w] == max) && !maxtrouve) { Set(w, MAXIMUM); maxtrouve = 1; } break; case MOY1: if ((SOURCE[w] == moy) && !moytrouve) { Set(w, MOYEN); moytrouve = 1; } break; case MIN: SOURCE[w] = min; break; case MAX: SOURCE[w] = max; break; case MOY: SOURCE[w] = moy; break; case MINB: SOURCE[w] = minb; break; case MAXB: SOURCE[w] = maxb; break; case MOYB: SOURCE[w] = moyb; break; case RANDB: tmp = (int32_t)Normal(moybd, devb); if (tmp > (int32_t)NDG_MAX) tmp = (int32_t)NDG_MAX; if (tmp < (int32_t)NDG_MIN) tmp = (int32_t)NDG_MIN; SOURCE[w] = (uint8_t)tmp; break; default: fprintf(stderr, "%s: bad argument\n", F_NAME); return(0); } for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { /* pour les demarquer (TRAITE1) */ y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == 0) && (IsSet(y, TRAITE1))) UnSet(y, TRAITE1); } /* for k ... */ for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == valcomp) && (!IsSet(y, TRAITE2))) { LifoPush(LIFO, y); Set(y, TRAITE2); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ } /* if (MASK[x] && (!IsSet(x, TRAITE1))) */ } /* for (x = 0; x < N; x++) */ } /* if (mask->data_storage_type == VFF_TYP_1_BYTE) */ else if (mask->data_storage_type == VFF_TYP_4_BYTE) { for (x = 0; x < N; x++) /* recherche dans toute l'image */ { if (!MASKLONG[x]) SOURCE[x] = NDG_MIN; if (MASKLONG[x] && (!IsSet(x, TRAITE1))) /* on est dans une CC non traitee */ { valcomplong = MASKLONG[x]; LifoPush(LIFO, x); Set(x, TRAITE1); #ifdef DEBUG printf("Set TRAITE1 %d (%d,%d)\n",x, x%rs, x/rs); #endif min = SOURCE[x]; max = SOURCE[x]; sumndg = 0; surf = 0; sumndgb = 0; sumndgc = 0; surfb = 0; while (! LifoVide(LIFO)) /* parcourt la CC */ { w = LifoPop(LIFO); if ((SOURCE[w] < min)) min = SOURCE[w]; if ((SOURCE[w] > max)) max = SOURCE[w]; surf += 1; sumndg += SOURCE[w]; for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == valcomplong) && (!IsSet(y, TRAITE1))) { LifoPush(LIFO, y); Set(y, TRAITE1); #ifdef DEBUG printf("Set TRAITE1 %d (%d,%d)\n",y, y%rs, y/rs); #endif } } /* for k ... */ for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { y = voisin(w, k, rs, N); #ifdef VALEURTABOUE if ((y != -1) && (MASKLONG[y] == 0) && (!IsSet(y, TRAITE1)) && (SOURCE[y] != VALEURTABOUE)) #else if ((y != -1) && (MASKLONG[y] == 0) && (!IsSet(y, TRAITE1))) #endif { if ((SOURCE[y] < minb)) minb = SOURCE[y]; if ((SOURCE[y] > maxb)) maxb = SOURCE[y]; surfb += 1; sumndgb += SOURCE[y]; sumndgc += SOURCE[y] * SOURCE[y]; Set(y, TRAITE1); #ifdef DEBUG printf("Set TRAITE1 %d (%d,%d)\n",y, y%rs, y/rs); #endif } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ moy = (uint8_t)(sumndg/surf); if (surfb > 0) { moyb = (uint8_t)(sumndgb/surfb); moybd = ((double)sumndgb)/surfb; } else { moyb = 0; moybd = 0.0; } devb = sqrt(((double)sumndgc)/surfb - ((double)sumndgb * sumndgb)/(surfb * surfb)); #ifdef DEBUG printf("composante %d - surf=%d ; sumndg=%d ; surfb=%d ; sumndgb=%d ; max=%d\n", valcomplong, surf, sumndg, surfb, sumndgb, max); #endif LifoPush(LIFO, x); Set(x, TRAITE2); mintrouve = 0; maxtrouve = 0; moytrouve = 0; while (! LifoVide(LIFO)) /* RE-parcourt la CC */ { w = LifoPop(LIFO); switch (function) { case MIN1: if ((SOURCE[w] == min) && !mintrouve) { Set(w, MINIMUM); mintrouve = 1; } break; case MAX1: if ((SOURCE[w] == max) && !maxtrouve) { Set(w, MAXIMUM); maxtrouve = 1; } break; case MOY1: if ((SOURCE[w] == moy) && !moytrouve) { Set(w, MOYEN); moytrouve = 1; } break; case MIN: SOURCE[w] = min; break; case MAX: SOURCE[w] = max; break; case MOY: SOURCE[w] = moy; break; case MINB: SOURCE[w] = minb; break; case MAXB: SOURCE[w] = maxb; break; case MOYB: SOURCE[w] = moyb; break; case RANDB: tmp = (int32_t)Normal(moybd, devb); if (tmp > (int32_t)NDG_MAX) tmp = (int32_t)NDG_MAX; if (tmp < (int32_t)NDG_MIN) tmp = (int32_t)NDG_MIN; SOURCE[w] = (uint8_t)tmp; break; default: fprintf(stderr, "%s: bad argument\n", F_NAME); return(0); } for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { /* pour les demarquer (TRAITE1) */ y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == 0) && (IsSet(y, TRAITE1))) { UnSet(y, TRAITE1); #ifdef DEBUG printf("UnSet TRAITE1 %d (%d,%d)\n",y, y%rs, y/rs); #endif } } /* for k ... */ for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == valcomplong) && (!IsSet(y, TRAITE2))) { LifoPush(LIFO, y); Set(y, TRAITE2); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ } /* if (MASKLONG[x] && (!IsSet(x, TRAITE1))) */ } /* for (x = 0; x < N; x++) */ } /* if (mask->data_storage_type == VFF_TYP_4_BYTE) */ else { fprintf(stderr, "%s: bad storage type\n", F_NAME); return(0); } if (function == MIN1) for (x = 0; x < N; x++) if (IsSet(x, MINIMUM)) SOURCE[x] = NDG_MAX; else SOURCE[x] = NDG_MIN; if (function == MAX1) for (x = 0; x < N; x++) if (IsSet(x, MAXIMUM)) SOURCE[x] = NDG_MAX; else SOURCE[x] = NDG_MIN; if (function == MOY1) for (x = 0; x < N; x++) if (IsSet(x, MOYEN)) SOURCE[x] = NDG_MAX; else SOURCE[x] = NDG_MIN; LifoTermine(LIFO); IndicsTermine(); return(1); } /* lpropgeo() */
/* ==================================== */ int32_t lpropgeolong( struct xvimage *img1, struct xvimage *mask, int32_t connex, int32_t function ) /* ==================================== */ #undef F_NAME #define F_NAME "lpropgeolong" { int32_t k; int32_t w; int32_t x; int32_t y; int32_t min; int32_t max; int32_t moy; uint8_t valcomp; int32_t valcomplong; int32_t mintrouve; int32_t maxtrouve; int32_t moytrouve; int32_t incr_vois; int32_t incr_voisb; int32_t sumndg; /* pour calculer la moyenne sur la composante */ int32_t surf; /* pour calculer la surface de la composante */ int32_t *SOURCE = SLONGDATA(img1); uint8_t *MASK = UCHARDATA(mask); int32_t *MASKLONG = SLONGDATA(mask); int32_t rs = rowsize(img1); int32_t cs = colsize(img1); int32_t N = rs * cs; Lifo * LIFO; #ifdef PERF chrono chrono1; #endif if (depth(img1) != 1) { fprintf(stderr, "%s: cette version ne traite pas les images volumiques\n", F_NAME); return 0; } if (img1->data_storage_type != VFF_TYP_4_BYTE) { fprintf(stderr, "%s: datatype for arg1 must be int32_t\n", F_NAME); return 0; } if ((rowsize(mask) != rs) || (colsize(mask) != cs)) { fprintf(stderr, "%s: incompatible image sizes\n", F_NAME); return 0; } switch (connex) { case 4: incr_vois = 2; incr_voisb = 1; break; case 8: incr_vois = 1; incr_voisb = 2; break; default: fprintf(stderr, "%s: mauvaise connexite: %d\n", F_NAME, connex); return 0; } /* switch (connex) */ #ifdef PERF /* pour l'analyse de performances */ start_chrono(&chrono1); #endif IndicsInit(N); LIFO = CreeLifoVide(N); if (LIFO == NULL) { fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME); return(0); } if (mask->data_storage_type == VFF_TYP_1_BYTE) { for (x = 0; x < N; x++) /* recherche dans toute l'image */ { if (!MASK[x]) SOURCE[x] = 0; if (MASK[x] && (!IsSet(x, TRAITE1))) /* on est dans une CC non traitee */ { valcomp = MASK[x]; LifoPush(LIFO, x); Set(x, TRAITE1); min = SOURCE[x]; max = SOURCE[x]; surf = 0; while (! LifoVide(LIFO)) /* parcourt la CC */ { w = LifoPop(LIFO); if ((SOURCE[w] < min)) min = SOURCE[w]; if ((SOURCE[w] > max)) max = SOURCE[w]; surf += 1; sumndg += SOURCE[w]; for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == valcomp) && (!IsSet(y, TRAITE1))) { LifoPush(LIFO, y); Set(y, TRAITE1); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ moy = (int32_t)(sumndg/surf); LifoPush(LIFO, x); Set(x, TRAITE2); mintrouve = 0; maxtrouve = 0; moytrouve = 0; while (! LifoVide(LIFO)) /* RE-parcourt la CC */ { w = LifoPop(LIFO); switch (function) { case MIN: SOURCE[w] = min; break; case MAX: SOURCE[w] = max; break; case MOY: SOURCE[w] = moy; break; default: fprintf(stderr, "%s: bad argument\n", F_NAME); return(0); } for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { /* pour les demarquer (TRAITE1) */ y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == 0) && (IsSet(y, TRAITE1))) UnSet(y, TRAITE1); } /* for k ... */ for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASK[y] == valcomp) && (!IsSet(y, TRAITE2))) { LifoPush(LIFO, y); Set(y, TRAITE2); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ } /* if (MASK[x] && (!IsSet(x, TRAITE1))) */ } /* for (x = 0; x < N; x++) */ } /* if (mask->data_storage_type == VFF_TYP_1_BYTE) */ else if (mask->data_storage_type == VFF_TYP_4_BYTE) { for (x = 0; x < N; x++) /* recherche dans toute l'image */ { if (!MASKLONG[x]) SOURCE[x] = NDG_MIN; if (MASKLONG[x] && (!IsSet(x, TRAITE1))) /* on est dans une CC non traitee */ { valcomplong = MASKLONG[x]; LifoPush(LIFO, x); Set(x, TRAITE1); #ifdef DEBUG printf("Set TRAITE1 %d (%d,%d)\n",x, x%rs, x/rs); #endif min = SOURCE[x]; max = SOURCE[x]; sumndg = 0; surf = 0; while (! LifoVide(LIFO)) /* parcourt la CC */ { w = LifoPop(LIFO); if ((SOURCE[w] < min)) min = SOURCE[w]; if ((SOURCE[w] > max)) max = SOURCE[w]; surf += 1; sumndg += SOURCE[w]; for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == valcomplong) && (!IsSet(y, TRAITE1))) { LifoPush(LIFO, y); Set(y, TRAITE1); #ifdef DEBUG printf("Set TRAITE1 %d (%d,%d)\n",y, y%rs, y/rs); #endif } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ moy = (int32_t)(sumndg/surf); LifoPush(LIFO, x); Set(x, TRAITE2); mintrouve = 0; maxtrouve = 0; moytrouve = 0; while (! LifoVide(LIFO)) /* RE-parcourt la CC */ { w = LifoPop(LIFO); switch (function) { case MIN: SOURCE[w] = min; break; case MAX: SOURCE[w] = max; break; case MOY: SOURCE[w] = moy; break; default: fprintf(stderr, "%s: bad argument\n", F_NAME); return(0); } for (k = 0; k < 8; k += incr_voisb) /* parcourt les voisins dans le complementaire */ { /* pour les demarquer (TRAITE1) */ y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == 0) && (IsSet(y, TRAITE1))) { UnSet(y, TRAITE1); #ifdef DEBUG printf("UnSet TRAITE1 %d (%d,%d)\n",y, y%rs, y/rs); #endif } } /* for k ... */ for (k = 0; k < 8; k += incr_vois) /* parcourt les voisins */ { y = voisin(w, k, rs, N); if ((y != -1) && (MASKLONG[y] == valcomplong) && (!IsSet(y, TRAITE2))) { LifoPush(LIFO, y); Set(y, TRAITE2); } } /* for k ... */ } /* while (! LifoVide(LIFO)) */ } /* if (MASKLONG[x] && (!IsSet(x, TRAITE1))) */ } /* for (x = 0; x < N; x++) */ } /* if (mask->data_storage_type == VFF_TYP_4_BYTE) */ else { fprintf(stderr, "%s: bad storage type\n", F_NAME); return(0); } LifoTermine(LIFO); IndicsTermine(); return(1); } /* lpropgeolong() */
/* ==================================== */ int32_t lgeoeros3d( struct xvimage *g, struct xvimage *f, int32_t connex, int32_t niter) /* reconstruction de g sous f */ /* g : image marqueur */ /* f : image masque */ /* connex : 6 ou 18 ou 26 */ /* niter : nombre d'iterations (ou -1 pour saturation) */ /* resultat dans g */ /* ==================================== */ #undef F_NAME #define F_NAME "lgeoeros3d" { int32_t nbchang, iter; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t rs = rowsize(g); /* taille ligne */ int32_t cs = colsize(g); /* taille colonne */ int32_t d = depth(g); /* nombre plans */ int32_t n = rs * cs; /* taille plan */ int32_t N = n * d; /* taille image */ uint8_t *G = UCHARDATA(g); /* l'image marqueur */ uint8_t *F = UCHARDATA(f); /* l'image masque */ uint8_t *H; /* image de travail */ uint8_t *temp; uint8_t inf; Fifo * FIFO[2]; if ((rowsize(f) != rs) || (colsize(f) != cs) || (depth(f) != d)) { fprintf(stderr, "%s: incompatible sizes\n", F_NAME); return 0; } FIFO[0] = CreeFifoVide(N); FIFO[1] = CreeFifoVide(N); if ((FIFO[0] == NULL) || (FIFO[1] == NULL)) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } IndicsInit(N); for (x = 0; x < N; x++) /* mise en fifo initiale de tous les points */ { FifoPush(FIFO[1], x); Set(x, 1); } H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"%s : malloc failed for H\n", F_NAME); return(0); } for (x = 0; x < N; x++) /* force G à être >= F */ if (G[x] < F[x]) G[x] = F[x]; if (connex == 26) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k < 26; k += 1) { y = voisin26(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 26; k += 1) { y = voisin26(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else if (connex == 18) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k < 18; k += 1) { y = voisin18(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 18; k += 1) { y = voisin18(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else if (connex == 6) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k <= 10; k += 2) { y = voisin6(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k <= 10; k += 2) { y = voisin6(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else { fprintf(stderr, "%s: bad connexity\n", F_NAME); return 0; } /* remet le resultat dans g si necessaire */ if (G != UCHARDATA(g)) { for (x = 0; x < N; x++) (UCHARDATA(g))[x] = G[x]; free(G); } else free(H); FifoTermine(FIFO[0]); FifoTermine(FIFO[1]); IndicsTermine(); return 1; } // lgeoeros3d(
/* ==================================== */ int32_t lgeodilat( struct xvimage *g, struct xvimage *f, int32_t connex, int32_t niter) /* dilatation geodesique de g sous f */ /* g : image marqueur */ /* f : image masque */ /* connex : 4 ou 8 */ /* niter : nombre d'iterations (ou -1 pour saturation) */ /* resultat dans g */ /* ==================================== */ #undef F_NAME #define F_NAME "lgeodilat" { int32_t nbchang, iter; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t rs = rowsize(g); /* taille ligne */ int32_t cs = colsize(g); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *G = UCHARDATA(g); /* l'image marqueur */ uint8_t *F = UCHARDATA(f); /* l'image masque */ uint8_t *H; /* image de travail */ uint8_t *temp; uint8_t sup; Fifo * FIFO[2]; int32_t incr_vois; switch (connex) { case 4: incr_vois = 2; break; case 8: incr_vois = 1; break; } /* switch (connex) */ if ((rowsize(f) != rs) || (colsize(f) != cs)) { fprintf(stderr, "%s: incompatible sizes\n", F_NAME); return 0; } if (depth(f) != 1) { fprintf(stderr, "%s: only works for 2d images\n", F_NAME); return 0; } FIFO[0] = CreeFifoVide(N); FIFO[1] = CreeFifoVide(N); if ((FIFO[0] == NULL) || (FIFO[1] == NULL)) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } IndicsInit(N); for (x = 0; x < N; x++) /* mise en fifo initiale de tous les points */ { FifoPush(FIFO[1], x); Set(x, 1); } H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"%s : malloc failed for H\n", F_NAME); return(0); } for (x = 0; x < N; x++) /* force G à être <= F */ if (G[x] > F[x]) G[x] = F[x]; iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); sup = G[x]; for (k = 0; k < 8; k += incr_vois) { y = voisin(x, k, rs, N); if ((y != -1) && (G[y] > sup)) sup = G[y]; } /* for k */ sup = mcmin(sup, F[x]); if (G[x] != sup) /* changement: on enregistre x ainsi que ses voisins */ { nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 8; k += 1) { y = voisin(x, k, rs, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = sup; } /* while ! FifoVide */ /* echange les roles de G et H */ temp = G; G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); /* remet le resultat dans g si necessaire */ if (G != UCHARDATA(g)) { for (x = 0; x < N; x++) (UCHARDATA(g))[x] = G[x]; free(G); } else free(H); FifoTermine(FIFO[0]); FifoTermine(FIFO[1]); IndicsTermine(); return 1; } /* lgeodilat() */
/* ==================================== */ static void Watershed(struct xvimage *image, int32_t connex, Fahs * FAHS, int32_t *CM, ctree * CT) /* ==================================== */ // // inondation a partir des voisins des maxima, suivant les ndg decroissants // nouvelle (08/03) caracterisation des points destructibles // nouvelle (09/03) construction de l'arbre des composantes // Nouvelle (05/05) lca en temps constant + qq optimisation de l'article JMIV (najmanl) #undef F_NAME #define F_NAME "Watershed" { uint8_t *F = UCHARDATA(image); int32_t rs = rowsize(image); int32_t ps = rs * colsize(image); int32_t N = ps * depth(image); int32_t i, k, x, y; int32_t c; /* une composante */ int32_t tabcomp[26]; /* liste de composantes */ int32_t nbelev; /* nombre d'elevations effectuees */ int32_t lcalevel; /* niveau du lca */ int32_t incr_vois; #ifndef LCASLOW int32_t logn, nbRepresent; int32_t *Euler, *Depth, *Represent, *Number, **Minim; #endif // INITIALISATIONS FahsFlush(FAHS); // Re-initialise la FAHS #ifndef LCASLOW Euler = (int32_t *)calloc(2*CT->nbnodes-1, sizeof(int32_t)); Represent = (int32_t *)calloc(CT->nbnodes, sizeof(int32_t)); Depth = (int32_t *)calloc(CT->nbnodes, sizeof(int32_t)); Number = (int32_t *)calloc(CT->nbnodes, sizeof(int32_t)); if ((Euler == NULL) || (Represent == NULL) || (Depth == NULL) || (Number == NULL)) { fprintf(stderr, "%s : malloc failed\n", F_NAME); return; } Minim = LCApreprocess(CT, Euler, Depth, Represent, Number, &nbRepresent, &logn); #ifdef _DEBUG_ printf("Comparison Slow/Fast lca\n"); { int32_t i,j, anc; int32_t nbErrors = 0; for (i=0; i<CT->nbnodes; i++) for (j=0; j<CT->nbnodes; j++) { if ((CT->tabnodes[i].nbsons > -1) && (CT->tabnodes[j].nbsons > -1)) { anc = Represent[LowComAncFast(i,j,Euler,Number,Depth,Minim)]; if (anc != LowComAncSlow(CT,i,j)) { nbErrors++; printf("Error node lca(%d, %d) = %d ou %d ?\n", i, j, anc, LowComAncSlow(CT,i,j)); } else { printf("Ok node lca(%d, %d) = %d\n", i, j, anc); } } } printf("Nb errors = %d\n",nbErrors); } fflush(stdout); #endif // _DEBUG_ #endif //ifndef LCASLOW switch (connex) { case 4: incr_vois = 2; break; case 8: incr_vois = 1; break; } /* switch (connex) */ // etiquetage des c-maxima (doit pouvoir se faire au vol lors de la construction de l'arbre) for (i = 0; i < N; i++) { c = CM[i]; if (CT->tabnodes[c].nbsons == 0) { Set(i,MASSIF); } } // for (i = 0; i < N; i++) // empile les points for (i = 0; i < N; i++) { #ifdef OLDVERSION // empile tous les points Set(i,EN_FAHS); FahsPush(FAHS, i, NDG_MAX - F[i]); #else // empile les points voisins d'un minima char flag=0; switch (connex) { case 4: case 8: for (k = 0; (k < 8) && (flag == 0); k += incr_vois) { y = voisin(i, k, rs, N); if ((y != -1) && (IsSet(y,MASSIF))) { flag = 1; } } break; case 6: for (k = 0; k <= 10; k += 2) { y = voisin6(i, k, rs, ps, N); if ((y != -1) && (IsSet(y,MASSIF))) { flag = 1; } } break; case 18: for (k = 0; k < 18; k += 1) { y = voisin18(i, k, rs, ps, N); if ((y != -1) && (IsSet(y,MASSIF))) { flag = 1; } } break; case 26: for (k = 0; k < 26; k += 1) { y = voisin26(i, k, rs, ps, N); if ((y != -1) && (IsSet(y,MASSIF))) { flag = 1; } } break; } /* switch (connex) */ if (flag) { Set(i,EN_FAHS); FahsPush(FAHS, i, NDG_MAX - F[i]); } #endif } // for (i = 0; i < N; i++) // BOUCLE PRINCIPALE nbelev = 0; while (!FahsVide(FAHS)) { x = FahsPop(FAHS); UnSet(x,EN_FAHS); W_Constructible(x, F, rs, ps, N, connex, CT, CM, tabcomp, &c, &lcalevel #ifndef LCASLOW , Euler, Represent, Depth, Number, Minim #endif ); if (c != -1) { nbelev++; F[x] = lcalevel; // eleve le niveau du point x CM[x] = c; // maj pointeur image -> composantes Set(x,MODIFIE); if (CT->tabnodes[c].nbsons == 0) // feuille { Set(x,MASSIF); } // if feuille else if (CT->tabnodes[c].nbsons > 1) // noeud { } #ifdef PARANO else printf("%s : ERREUR COMPOSANTE BRANCHE!!!\n", F_NAME); #endif // empile les c-voisins de x non marques MASSIF ni EN_FAHS switch (connex) { case 4: case 8: for (k = 0; k < 8; k += incr_vois) { y = voisin(x, k, rs, N); if ((y != -1) && (!IsSet(y,MASSIF)) && (!IsSet(y,EN_FAHS))) { Set(y,EN_FAHS); FahsPush(FAHS, y, NDG_MAX - F[y]); } } break; case 6: for (k = 0; k <= 10; k += 2) { y = voisin6(x, k, rs, ps, N); if ((y != -1) && (!IsSet(y,MASSIF)) && (!IsSet(y,EN_FAHS))) { Set(y,EN_FAHS); FahsPush(FAHS, y, NDG_MAX - F[y]); } } break; case 18: for (k = 0; k < 18; k += 1) { y = voisin18(x, k, rs, ps, N); if ((y != -1) && (!IsSet(y,MASSIF)) && (!IsSet(y,EN_FAHS))) { Set(y,EN_FAHS); FahsPush(FAHS, y, NDG_MAX - F[y]); } } break; case 26: for (k = 0; k < 26; k += 1) { y = voisin26(x, k, rs, ps, N); if ((y != -1) && (!IsSet(y,MASSIF)) && (!IsSet(y,EN_FAHS))) { Set(y,EN_FAHS); FahsPush(FAHS, y, NDG_MAX - F[y]); } } break; } /* switch (connex) */ } // if (c != -1)} } // while (!FahsVide(FAHS)) #ifdef VERBOSE printf("Nombre d'elevations %d\n", nbelev); #endif #ifndef LCASLOW free(Euler); free(Represent); free(Depth); free(Number); free(Minim[0]); free(Minim); #endif //LCASLOW } // Watershed()