/* ==================================== */ int32_t lremspnoise( struct xvimage *image, int32_t g, int32_t k) /* g : nombre de niveaux d'ecart */ /* k : nombre de voisins consideres */ /* ==================================== */ { int32_t i, v, n, j, m, nv; uint8_t *pt; int32_t rs = image->row_size; int32_t cs = image->col_size; int32_t N = rs * cs; uint8_t *imagetmp; if (depth(image) != 1) { fprintf(stderr, "lhtkern: cette version ne traite pas les images volumiques\n"); exit(0); } pt = UCHARDATA(image); imagetmp = (uint8_t *)calloc(1,N*sizeof(char)); if (imagetmp == NULL) { printf("lremspnoise() : malloc failed\n"); return(0); } /* ---------------------------------------------------------- */ /* calcul du resultat */ /* ---------------------------------------------------------- */ for (i = 0; i < N; i++) { /* detection du bruit : compte le nombre de voisins qui different de plus de g niveaux */ n = 0; nv = 0; m = 0; for (v = 0; v < 8; v++) /* 8-voisins */ if ((j = voisin(i, v, rs, N)) != -1) { if (mcabs(((int32_t)pt[i] - (int32_t)pt[j]) >= g)) n++; nv++; /* compte les voisins */ m += pt[j]; /* pour le calcul de la moyenne */ } if (n >= k) { /* moyennage : remplace la valeur du point par la moyenne de ses 8 voisins */ imagetmp[i] = (uint8_t)(m / nv); } else imagetmp[i] = pt[i]; } for (i = 0; i < N; i++) pt[i] = imagetmp[i]; free(imagetmp); return 1; }
/* =============================================================== */ int32_t l3dseltype(struct xvimage * k, uint8_t d1, uint8_t d2, uint8_t a1, uint8_t a2, uint8_t b1, uint8_t b2) /* =============================================================== */ /* Selects the elements x of the Khalimsky volume \b k which satisfy the following inequalities : \b a1 <= a(x) <= \b a2 \b b1 <= b(x) <= \b b2 \b d1 <= d(x) <= \b d2 where d(x) = dimension of x a(x) = number of elements under x of dimension d(x) - 1 b(x) = number of elements over x of dimension d(x) + 1 */ #undef F_NAME #define F_NAME "l3dseltype" { index_t rs, cs, ps, ds, N, i1, j1, k1, i2, j2, k2, x, y; uint8_t * K; struct xvimage * kp; uint8_t * KP; index_t tab[27]; int32_t n, u, a, b, d; rs = rowsize(k); cs = colsize(k); ds = depth(k); ps = rs * cs; N = ps * ds; K = UCHARDATA(k); kp = allocimage(NULL, rs, cs, ds, VFF_TYP_1_BYTE); if (kp == NULL) { fprintf(stderr,"%s : allocimage failed\n", F_NAME); return(0); } KP = UCHARDATA(kp); memset(KP, 0, N); for (k1 = 0; k1 < ds; k1++) for (j1 = 0; j1 < cs; j1++) for (i1 = 0; i1 < rs; i1++) { x = k1*ps + j1*rs + i1; d = DIM3D(i1,j1,k1); if (K[x] && (d1 <= d) && (d <= d2)) { Alphacarre3d(rs, cs, ds, i1, j1, k1, tab, &n); for (a = u = 0; u < n; u++) /* parcourt les eventuels alpha-voisins */ { y = tab[u]; i2 = y%rs; j2 = (y%ps)/rs; k2 = y/ps; if (K[y] && (DIM3D(i2,j2,k2) == (d-1))) a++; } if ((a1 <= a) && (a <= a2)) { Betacarre3d(rs, cs, ds, i1, j1, k1, tab, &n); for (b = u = 0; u < n; u++) /* parcourt les eventuels beta-voisins */ { y = tab[u]; i2 = y%rs; j2 = (y%ps)/rs; k2 = y/ps; if (K[y] && (DIM3D(i2,j2,k2) == (d+1))) b++; } if ((b1 <= b) && (b <= b2)) { KP[x] = NDG_MAX; } } } } // for k1, j1, i1 for (x = 0; x < N; x++) K[x] = KP[x]; freeimage(kp); return 1; } /* l3dseltype() */
/* =============================================================== */ int32_t ltaf(struct xvimage * image, int32_t connexmin, int32_t rayon) /* =============================================================== */ #undef F_NAME #define F_NAME "ltaf" { struct xvimage * copy; int32_t rs, cs, ds, ps, N; int32_t ndes; rs = rowsize(image); /* taille ligne */ cs = colsize(image); /* taille colonne */ ps = rs * cs; /* taille plan */ ds = depth(image); /* nombre plans */ N = ds * ps; /* taille image */ if (rayon == -1) rayon = 2000000000; if (ds == 1) /* ======================= 2D ========================*/ { copy = copyimage(image); if (copy == NULL) { fprintf(stderr, "%s: copyimage failed\n", F_NAME); return 0; } do { if (! lhthindelta(image, NULL, rayon, connexmin)) { fprintf(stderr, "%s: lhthindelta failed\n", F_NAME); return 0; } ndes = p_despics(image, connexmin); if (! lhtkernu(image, copy, connexmin)) { fprintf(stderr, "%s: lhtkernu failed\n", F_NAME); return 0; } memcpy(UCHARDATA(copy), UCHARDATA(image), N); if (! lhthickdelta(image, NULL, rayon, connexmin)) { fprintf(stderr, "%s: lhthickdelta failed\n", F_NAME); return 0; } ndes += p_despuits(image, connexmin); if (! lhtkern(image, copy, connexmin)) { fprintf(stderr, "%s: lhtkern failed\n", F_NAME); return 0; } if (ndes) memcpy(UCHARDATA(copy), UCHARDATA(image), N); } while (ndes); } else /* ============================== 3D ================================*/ { fprintf(stderr, "%s: 3D Not Yet Implemented\n", F_NAME); return 0; } freeimage(copy); return 1; } /* ltaf() */
/* ==================================== */ int32_t lmaxdiameter(struct xvimage *image, int32_t connex) /* ==================================== */ { int32_t x; /* index muet de pixel */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t ds = depth(image); /* nb plans */ int32_t ps = rs * cs; /* taille plan */ int32_t N = ps * ds; /* taille image */ uint8_t *I = UCHARDATA(image); /* l'image de depart */ struct xvimage *tmp; uint8_t *T; //GUJUN int32_t x1, x1max; int32_t y1, y1max; int32_t z1, z1max; int32_t x2, x2max; int32_t y2, y2max; int32_t z2, z2max; double distance = -1; double temp = 0; int32_t i; switch(datatype(image)) { case VFF_TYP_1_BYTE: tmp = copyimage(image); if (tmp == NULL) { fprintf(stderr, "lmaxdiameter: copyimage failed\n"); return 0; } T = UCHARDATA(tmp); switch (connex) { case 4: for (x = 0; x < N; x++) if (T[x] && (nbvoisc8(T,x,rs,N)) == 0) I[x] = NDG_MIN; break; case 8: for (x = 0; x < N; x++) if (T[x] && (nbvoisc4(T,x,rs,N)) == 0) I[x] = NDG_MIN; break; case 6: for (x = 0; x < N; x++) if (T[x] && (mctopo3d_nbvoisc6(T,x,rs,ps,N)) == 0) I[x] = NDG_MIN; break; case 18: for (x = 0; x < N; x++) if (T[x] && (mctopo3d_nbvoisc18(T,x,rs,ps,N)) == 0) I[x] = NDG_MIN; break; case 26: for (x = 0; x < N; x++) if (T[x] && (mctopo3d_nbvoisc26(T,x,rs,ps,N)) == 0) I[x] = NDG_MIN; break; default: fprintf(stderr, "lmaxdiameter: mauvaise connexite: %d\n", connex); return 0; } /* switch (connex) */ //GUJun //Deux dimentions x et y if ((connex == 4)||(connex == 8)) { for( x = 0; x < N; x++) { // Le premier point au border if( I[x] != NDG_MIN ) { x1 = x%rs; y1 = x/rs; for (i = x+1; i < N; i++) { //Le deuxième point au border if( I[i] != NDG_MIN ) { x2 = i%rs; y2 = i/rs; temp = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); //Le plus int32_t axe if (temp > distance) { distance = temp; x1max = x1; y1max = y1; x2max = x2; y2max = y2; } } } } } for( x = 0; x < N; x++) I[x] = NDG_MIN; I[x1max+y1max*rs] = NDG_MAX; I[x2max+y2max*rs] = NDG_MAX; } //Trois dimentions x,y et z else if ((connex == 6)||(connex == 18)||(connex == 26)) { for ( x = 0; x < N; x++) { if( I[x] != NDG_MIN ) { z1 = x/ps; x1 = (x%ps)%rs; y1 = (x%ps)/rs; for(i = x+1; i < N; i++) { if( I[i] != NDG_MIN ) { z2 = i/ps; x2 = (i%ps)%rs; y2 = (i%ps)/rs; temp = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2)); if (temp > distance) { distance = temp; x1max = x1; y1max = y1; z1max = z1; x2max = x2; y2max = y2; z2max = z2; } } } } } for( x = 0; x < N; x++) I[x] = NDG_MIN; I[x1max+y1max*rs+z1max*ps] = NDG_MAX; I[x2max+y2max*rs+z2max*ps] = NDG_MAX; } //GUJun break; default: fprintf(stderr,"lmaxdiameter() : bad data type %d\n", datatype(image)); return 0; } /* switch(datatype(image)) */ if (distance == -1) { fprintf(stderr,"lmaxdiameter() : not enough data\n"); return 0; } freeimage(tmp); return(1); }
/* ==================================== */ int32_t lfiltreordre3d(struct xvimage *f, struct xvimage *m, int32_t xc, int32_t yc, int32_t zc, double r) /* r : rang ramene a une echelle 0..1 (ex: 0.5 -> filtre median) */ /* m : masque representant l'element structurant */ /* xc, yc, zc : coordonnees du "centre" de l'element structurant */ /* ==================================== */ { int32_t rang; int32_t x,y,z; register int32_t i, j, k; /* index muet */ register int32_t n, o, p; /* index muet */ int32_t rs = rowsize(f); /* taille ligne */ int32_t cs = colsize(f); /* taille colonne */ int32_t ds = depth(f); /* nb plans */ int32_t ps = rs * cs; /* taille plan */ int32_t N = ps * ds; /* taille image */ int32_t rsm = rowsize(m); /* taille ligne masque */ int32_t csm = colsize(m); /* taille colonne masque */ int32_t dsm = depth(m); /* nb plans masque */ int32_t psm = rsm * csm; /* taille plan masque */ int32_t Nm = psm * dsm; /* taille masque */ uint8_t *M = UCHARDATA(m); uint8_t *F = UCHARDATA(f); uint8_t *H; /* image de travail */ int32_t nptb; /* nombre de points de l'e.s. */ int32_t *tab_es_x; /* liste des coord. x des points de l'e.s. */ int32_t *tab_es_y; /* liste des coord. y des points de l'e.s. */ int32_t *tab_es_z; /* liste des coord. z des points de l'e.s. */ uint8_t *tab_es_val; /* liste des valeurs des points de l'e.s. */ int32_t c; H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"lfiltreordre3d() : malloc failed for H\n"); return(0); } for (x = 0; x < N; x++) H[x] = F[x]; nptb = 0; for (i = 0; i < Nm; i += 1) if (M[i]) nptb += 1; rang = (int32_t)((double)(nptb - 1) * r); #ifdef VERBOSE printf("r = %g ; nptb = %d ; rang = %d\n", r, nptb, rang); #endif tab_es_x = (int32_t *)calloc(1,nptb * sizeof(int32_t)); tab_es_y = (int32_t *)calloc(1,nptb * sizeof(int32_t)); tab_es_z = (int32_t *)calloc(1,nptb * sizeof(int32_t)); tab_es_val = (uint8_t *)calloc(1,nptb * sizeof(char)); if ((tab_es_x == NULL) || (tab_es_y == NULL) || (tab_es_z == NULL) || (tab_es_val == NULL)) { fprintf(stderr,"lfiltreordre3d() : malloc failed for tab_es\n"); return(0); } n = 0; for (k = 0; k < dsm; k += 1) for (j = 0; j < csm; j += 1) for (i = 0; i < rsm; i += 1) if (M[k * psm + j * rsm + i]) { tab_es_x[n] = i; tab_es_y[n] = j; tab_es_z[n] = k; n += 1; } for (z = 0; z < ds; z++) for (y = 0; y < cs; y++) for (x = 0; x < rs; x++) { for (c = 0; c < nptb ; c += 1) { o = z + tab_es_z[c] - zc; p = y + tab_es_y[c] - yc; n = x + tab_es_x[c] - xc; if ((o >= 0) && (o < ds) && (p >= 0) && (p < cs) && (n >= 0) && (n < rs)) tab_es_val[c] = H[o * ps + p * rs + n]; else tab_es_val[c] = 0; } F[z * ps + y * rs + x] = lfiltreordre_SelectionStochastique(tab_es_val, 0, nptb - 1, rang); } free(H); free(tab_es_x); free(tab_es_y); free(tab_es_z); free(tab_es_val); return 1; } /* lfiltreordre3d() */
/* =============================================================== */ int32_t latf_old(struct xvimage * image, int32_t connexmin, int32_t rayonmin, int32_t rayonmax) /* =============================================================== */ #undef F_NAME #define F_NAME "latf" { struct xvimage * copy; int32_t rayon; int32_t rs, cs, ds, ps, N; int32_t ndes; rs = rowsize(image); /* taille ligne */ cs = colsize(image); /* taille colonne */ ps = rs * cs; /* taille plan */ ds = depth(image); /* nombre plans */ N = ds * ps; /* taille image */ if (ds == 1) /* ======================= 2D ========================*/ { if (rayonmin == 0) { p_despics(image, connexmin); p_despuits(image, connexmin); rayonmin++; } copy = copyimage(image); if (copy == NULL) { fprintf(stderr, "%s: copyimage failed\n", F_NAME); return 0; } for (rayon = rayonmin; rayon <= rayonmax; rayon++) { #ifdef VERBOSE fprintf(stderr, "%s: rayon = %d\n", F_NAME, rayon); #endif do { if (! lhthindelta(image, NULL, rayon, connexmin)) { fprintf(stderr, "%s: lhthindelta failed\n", F_NAME); return 0; } ndes = p_despics(image, connexmin); if (! lhtkernu(image, copy, connexmin)) { fprintf(stderr, "%s: lhtkernu failed\n", F_NAME); return 0; } } while (ndes); memcpy(UCHARDATA(copy), UCHARDATA(image), N); do { if (! lhthickdelta(image, NULL, rayon, connexmin)) { fprintf(stderr, "%s: lhthickdelta failed\n", F_NAME); return 0; } ndes = p_despuits(image, connexmin); if (! lhtkern(image, copy, connexmin)) { fprintf(stderr, "%s: lhtkern failed\n", F_NAME); return 0; } } while (ndes); if (rayon < rayonmax) memcpy(UCHARDATA(copy), UCHARDATA(image), N); } /* for (rayon = 1; rayon <= rayonmax; rayon++) */ } else /* ============================== 3D ================================*/ { fprintf(stderr, "%s: 3D Not Yet Implemented\n", F_NAME); return 0; } freeimage(copy); return 1; } /* latf_old() */
/* waterfall vu comme une succession de LPE sur les aretes*/ int32_t main_cascade(struct xvimage *image, struct xvimage *ga, int32_t param) /* 4 connexite uniquement Construit le graphe d'arete de saillance pour les cascades*/ /* ==================================== */ #undef F_NAME #define F_NAME "main_cascade" { int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *F = UCHARDATA(image); /* l'image de depart */ uint8_t *G = UCHARDATA(ga); /* le GA de sortie */ int32_t *Label1, *Label2; struct GrapheValue *g1, *g2; int32_t i,k,y; int32_t nbregions; if ( (Label1 = malloc(sizeof(int32_t) * N)) == NULL){ fprintf(stderr, "%s: Erreur de malloc\n", F_NAME); exit(0); } if ( (Label2 = malloc(sizeof(int32_t) * N)) == NULL){ fprintf(stderr, "%s: Erreur de malloc\n", F_NAME); exit(0); } for(i = 0; i < 2*N; i++) G[i] = 0; //printf("Initialisation du Ga out done \n"); g1 = initGrapheValue(N, 4*N - 2*rs - 2*cs); /* nbre d'arete du graphe 4-connexe symetrique correspondant */ //printf("Initialisation du graphe utile \n"); for(i = 0; i < N; i++){ Label1[i] = i; for (k = 0; k < 4; k += 2){ if((y = voisin(i, k, rs, N)) != -1) switch(param){ case 0: updateArcValue(g1,i, y, (uint8_t)mcmax(F[i],F[y])); break; case 1: updateArcValue(g1,i, y, (uint8_t)mcabs((int32_t)F[i] - (int32_t)F[y])); break; default: fprintf(stderr,"%s: Mauvais parametre \n", F_NAME); exit(0); } } } //printf("Graphe utile calcule \n"); nbregions = (int32_t)lpeGrapheAreteValuee(g1, Label2); //printf("LPE du graphe utile done et nb regions %d\n",nbregions); fflush(stdout); while(nbregions > 1){ //printf("Un etage de la hierarchie \n"); g2 = initGrapheValue((int32_t)nbregions, (int32_t)mcmin(nbregions*(nbregions-1), (int32_t)(4*N - 2*rs - 2*cs)) ); //printf("2eme graphe initialise \n"); for(i = 0; i < N; i++){ for(k=0; k < 2; k++) if((y = voisin(i, 2*k, rs, N)) != -1){ if(Label2[Label1[i]] != Label2[Label1[y]]){ // Mise a jour de la carte de saillance du waterfall G[incidente(i,k,rs,N)] ++; switch(param){ case 0: updateArcValue(g2,Label2[Label1[i]], Label2[Label1[y]], mcmax(F[i],F[y])); break; case 1: updateArcValue(g2,Label2[Label1[i]], Label2[Label1[y]], (uint8_t)mcabs((int32_t)F[i] - (int32_t)F[y])); break; default: fprintf(stderr,"%s: Mauvais parametre \n", F_NAME); exit(0); } } } } for(i = 0; i < N; i++){ Label1[i] = Label2[Label1[i]]; } termineGrapheValue(g1); g1 = g2; nbregions = (int32_t)lpeGrapheAreteValuee(g1, Label2); } termineGrapheValue(g1); free(Label1); free(Label2); return 1; }
/* ==================================== */ int32_t lfiltreordre(struct xvimage *f, struct xvimage *m, int32_t xc, int32_t yc, double r) /* r : rang ramene a une echelle 0..1 (ex: 0.5 -> filtre median) */ /* m : masque representant l'element structurant */ /* xc, yc : coordonnees du "centre" de l'element structurant */ /* ==================================== */ { int32_t rang; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ register int32_t i, j; /* index muet */ register int32_t k, l; /* index muet */ int32_t rs = rowsize(f); /* taille ligne */ int32_t cs = colsize(f); /* taille colonne */ int32_t N = rs * cs; /* taille image */ int32_t rsm = rowsize(m); /* taille ligne masque */ int32_t csm = colsize(m); /* taille colonne masque */ int32_t Nm = rsm * csm; uint8_t *M = UCHARDATA(m); uint8_t *F = UCHARDATA(f); uint8_t *H; /* image de travail */ int32_t nptb; /* nombre de points de l'e.s. */ int32_t *tab_es_x; /* liste des coord. x des points de l'e.s. */ int32_t *tab_es_y; /* liste des coord. y des points de l'e.s. */ uint8_t *tab_es_val; /* liste des valeurs des points de l'e.s. */ int32_t c; if (depth(f) != 1) { fprintf(stderr, "lfiltreordre: cette version ne traite pas les images volumiques\n"); exit(0); } H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"lfiltreordre() : malloc failed for H\n"); return(0); } for (x = 0; x < N; x++) H[x] = F[x]; nptb = 0; for (i = 0; i < Nm; i += 1) if (M[i]) nptb += 1; rang = (int32_t)((double)(nptb - 1) * r); #ifdef VERBOSE printf("r = %g ; nptb = %d ; rang = %d\n", r, nptb, rang); #endif tab_es_x = (int32_t *)calloc(1,nptb * sizeof(int32_t)); tab_es_y = (int32_t *)calloc(1,nptb * sizeof(int32_t)); tab_es_val = (uint8_t *)calloc(1,nptb * sizeof(char)); if ((tab_es_x == NULL) || (tab_es_y == NULL) || (tab_es_val == NULL)) { fprintf(stderr,"lfiltreordre() : malloc failed for tab_es\n"); return(0); } k = 0; for (j = 0; j < csm; j += 1) for (i = 0; i < rsm; i += 1) if (M[j * rsm + i]) { tab_es_x[k] = i; tab_es_y[k] = j; k += 1; } for (y = 0; y < cs; y++) for (x = 0; x < rs; x++) { for (c = 0; c < nptb ; c += 1) { l = y + tab_es_y[c] - yc; k = x + tab_es_x[c] - xc; if ((l >= 0) && (l < cs) && (k >= 0) && (k < rs)) tab_es_val[c] = H[l * rs + k]; else tab_es_val[c] = 0; } F[y * rs + x] = lfiltreordre_SelectionStochastique(tab_es_val, 0, nptb - 1, rang); } free(H); free(tab_es_x); free(tab_es_y); free(tab_es_val); return 1; } /* lfiltreordre() */
/* ==================================== */ 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); }
/* Calcul la carte de saillance à partir du CT de saillance du ga d'origine et du flow mapping (label) du ga */ int32_t computeSaliencyMap(JCctree *CT, struct xvimage *ga, int32_t *label, int32_t *attribut) { 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); /* l'image de depart */ int32_t u,x,y,i,j,c1; /* la valeur maximum de l'attribut est à la racine */ double facteur = 1/(double)attribut[CT->root]; double exp = 1+log(1+attribut[CT->root]/256.0); #ifdef LCAFAST /* Structure de donnée pour lca fast */ int32_t logn, nbRepresent; int32_t *Euler, *Depth, *Represent, *Number, **Minim; Euler = (int32_t *)calloc(2*CT->nbnodes-1, sizeof(int32_t)); Represent = (int32_t *)calloc(2*CT->nbnodes-1, 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(0); } Minim = jccomptree_LCApreprocess(CT, Euler, Depth, Represent, Number, &nbRepresent, &logn); //printf("LCApreprocess done\n"); #endif for(j = 0; j < cs; j++) for(i = 0; i < rs -1; i++){ u = j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if((x < 0) || (y < 0) || (x >= N) || (y >= N) ){ printf("erreur index !!!!!\n"); exit(0); } if(label[x] != label[y]){ #ifdef LCAFAST c1 = Represent[jccomptree_LowComAncFast((int32_t)label[x], (int32_t)label[y], Euler, Number, Depth, Minim)]; #endif #ifndef LCAFAST c1 = jccomptree_LowComAncSlow(CT, (int32_t)label[x], (int32_t)label[y]); #endif F[u] = (uint8_t)(mcmin(pow(facteur * (double)attribut[c1], 1/exp), 1) * 255); } else F[u] =0; } /* puis les aretes verticales */ for(j = 0; j < cs -1; j++) for(i = 0; i < rs; i++) { u = N + j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if((x < 0) || (y < 0) || (x >= N) || (y >= N)){ printf("erreur index !!!!!\n"); exit(0); } if(label[x] != label[y]){ #ifdef LCAFAST c1 = Represent[jccomptree_LowComAncFast((int32_t)(label[x]), (int32_t)(label[y]), Euler, Number, Depth, Minim)]; #endif #ifndef LCAFAST c1 = jccomptree_LowComAncSlow(CT, (int32_t)label[x], (int32_t)label[y]); #endif if(c1 < 0){ printf("Erreur de lca pour %d %d retourne %d\n", (int32_t)(label[x]), (int32_t)(label[y]), c1); exit(0); } F[u] = (uint8_t)(mcmin(pow(facteur * (double)attribut[c1], 1/exp), 1) * 255); } else F[u] = 0; } #ifdef LCAFAST free(Euler); free(Represent); free(Depth); free(Number); free(Minim[0]); free(Minim); #endif return(1); }
/* ==================================== */ int32_t lminima( struct xvimage *image, char* str_connexity ) /* ==================================== */ { int32_t nblabels, connex, i; // struct xvimage * image; struct xvimage * result; uint8_t * I; int32_t * IL; int32_t N; int32_t * R; N = rowsize(image) * colsize(image) * depth(image); if (str_connexity[0] == 'b') { connex = atoi(str_connexity+1); } else connex = atoi(str_connexity); result = allocimage(NULL, rowsize(image), colsize(image), depth(image), VFF_TYP_4_BYTE); if (result == NULL) { fprintf(stderr, "allocimage failed\n"); exit(1); } R = SLONGDATA(result); if ((connex == 0) && strcmp(str_connexity, "b0") && strcmp(str_connexity, "b1")) { if (datatype(image) == VFF_TYP_1_BYTE) { uint8_t absmin; I = UCHARDATA(image); absmin = I[0]; for (i = 1; i < N; i++) if (I[i] < absmin) absmin = I[i]; for (i = 0; i < N; i++) if (I[i] == absmin) I[i] = NDG_MAX; else I[i] = NDG_MIN; } else if (datatype(image) == VFF_TYP_4_BYTE) { int32_t absmin; IL = SLONGDATA(image); absmin = IL[0]; for (i = 1; i < N; i++) if (IL[i] < absmin) absmin = IL[i]; for (i = 0; i < N; i++) if (IL[i] == absmin) IL[i] = (int32_t)NDG_MAX; else IL[i] = (int32_t)NDG_MIN; } else { fprintf(stderr, "wrong image type\n"); exit(1); } } else { if (! llabelextrema(image, connex, LABMIN, result, &nblabels)) { fprintf(stderr, "llabelextrema failed\n"); exit(1); } #ifdef VERBOSE printf("NOMBRE DE MINIMA : %d\n", nblabels-1); #endif if (datatype(image) == VFF_TYP_1_BYTE) { I = UCHARDATA(image); for (i = 0; i < N; i++) if (R[i]) I[i] = NDG_MAX; else I[i] = NDG_MIN; } else if (datatype(image) == VFF_TYP_4_BYTE) { IL = SLONGDATA(image); for (i = 0; i < N; i++) if (R[i]) IL[i] = (int32_t)NDG_MAX; else IL[i] = (int32_t)NDG_MIN; } } freeimage(result); return 1; } /* lminima */
/* mBorderWshed2d was previously called flowLPE2d*/ struct xvimage *mBorderWshed2d(struct xvimage *ga) #undef F_NAME #define F_NAME "mBorderWshed2d" { int32_t i,j,k,x,y,z,u, nlabels; struct xvimage *res; uint32_t *Eminima; uint32_t *Vminima; 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); /* l'image de depart */ uint8_t *VF; /* fonction indicatrice sur les sommets */ Lifo *L; /******************INITIALISATION*********************/ if(!jclabelextrema(ga, &Eminima, 1, &nlabels)) { fprintf(stderr,"%s erreur de label extrema \n",F_NAME); exit(1); } //printf("nlabels %d \n", nlabels); if( (res = allocimage(NULL, rs, cs, 1, VFF_TYP_4_BYTE)) == NULL) { fprintf(stderr,"%s erreur de allocimage \n", F_NAME); exit(1); } Vminima = SLONGDATA(res); if( (VF = malloc(sizeof(uint8_t) * N)) == NULL) { fprintf(stderr,"%s ne peut allouer VF \n", F_NAME); exit(1); } /* Valuation des sommets et calcul de V_M a partir de E_M */ for(i = 0; i < N; i++) { VF[i] = 255; Vminima[i] = 0; for(k = 0; k < 4; k++) if( (u = incidente(i, k, rs, N)) != -1) { if(F[u] < VF[i]) VF[i] = F[u]; if(Eminima[u] > 0) Vminima[i] = Eminima[u]; } } /* Initialisation de la FIFO */ L = CreeLifoVide(2*N); /* nbre maximum d'arete ds un ga 4 connexe sans regarder les bords */ /* Les aretes adjacentes a un minimum sont inserees dans L */ /* on explore d'abord les aretes horizontales */ for(j = 0; j < cs; j++) for(i = 0; i < rs -1; i++){ u = j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if( (mcmin(Vminima[x], Vminima[y]) == 0) && /* un des deux sommets non ds un minima */ (mcmax(Vminima[x], Vminima[y]) > 0) ) /* et l'autre dans un minima */ LifoPush(L,u); } /* puis les aretes verticales */ for(j = 0; j < cs -1; j++) for(i = 0; i < rs; i++) { u = N + j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if( (mcmin(Vminima[x], Vminima[y]) == 0) && /* un des deux sommets non ds un minima */ (mcmax(Vminima[x], Vminima[y]) > 0) ) /* et l'autre dans un minima */ LifoPush(L,u); } /*************BOUCLE PRINCIPALE*****************/ while(!LifoVide(L)) { u = LifoPop(L); x = Sommetx(u, N, rs); y = Sommety(u, N, rs); if (VF[x] > VF[y]) {z = y; y = x; x = z;} if((VF[x] < F[u]) && (VF[y] == F[u])){ /* u est une arete de bord */ F[u] = VF[x]; VF[y] = F[u]; Eminima[u] = Vminima[x]; Vminima[y] = Vminima[x]; for(k = 0; k < 8; k +=2){ if( (z = voisin(y, k, rs, N)) != -1) if( (Vminima[z] == 0)) LifoPush(L, Arete(y,z,rs,N)); } /* for(k = 0 .. */ } /* if( (VF[x] < ... */ }/* while(!LifoVide... */ free(Eminima); free(VF); return res; }
/* mBorderWshed2d was previously called flowLPE2d*/ struct xvimage *mBorderWshed2drapide(struct xvimage *ga) #undef F_NAME #define F_NAME "mBorderWshed2drapide" { int32_t i,j,k,x,y,z,w,u, nlabels, label; struct xvimage *res; // uint32_t *Eminima; int32_t *Vminima; 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); /* l'image de depart */ uint8_t *VF; /* fonction indicatrice sur les sommets */ Lifo *L; /******************INITIALISATION*********************/ /* if(!jclabelextrema(ga, &Eminima, 1, &nlabels)) { fprintf(stderr,"%s erreur de label extrema \n",F_NAME); exit(1); }*/ if( (res = allocimage(NULL, rs, cs, 1, VFF_TYP_4_BYTE)) == NULL) { fprintf(stderr,"%s erreur de allocimage \n", F_NAME); exit(1); } Vminima = SLONGDATA(res); if( (VF = malloc(sizeof(uint8_t) * N)) == NULL) { fprintf(stderr,"%s ne peut allouer VF \n", F_NAME); exit(1); } /* Valuation des sommets */ for(i = 0; i < N; i++) { VF[i] = 255; Vminima[i] = -1; for(k = 0; k < 4; k++) if( (u = incidente(i, k, rs, N)) != -1) if(F[u] < VF[i]) VF[i] = F[u]; } /* Initialisation de la FIFO */ L = CreeLifoVide(2*N); /* nbre maximum d'arete ds un ga 4 connexe sans regarder les bords */ /* Calcul des sommets qui sont dans des minima de F */ nlabels = 0; for(x = 0; x < N; x++){ if(Vminima[x] == -1){ /* On trouve un sommet non encore etiquete */ nlabels ++; Vminima[x] = nlabels; LifoPush(L,x); while(!LifoVide(L)) { w = LifoPop(L); label = Vminima[w]; for(k = 0; k < 4; k++) if( (u = incidente(w, k, rs, N)) != -1){ if(F[u] == VF[w]){ switch(k){ case 0: y = w+1; break; /* EST */ case 1: y = w-rs; break; /* NORD */ case 2: y = w-1; break; /* OUEST */ case 3: y = w+rs; break; /* SUD */ } if( (label > 0) && (VF[y] < VF[w]) ){ label = 0; nlabels --; Vminima[w] = label; LifoPush(L,w); } else if(VF[y] == VF[w]){ if( ( (label > 0) && (Vminima[y] == -1) ) || ( (label == 0) && (Vminima[y] != 0)) ){ Vminima[y] = label; LifoPush(L,y); } } } } } } } // printf("nlabels %d \n",nlabels); /* Les aretes adjacentes a un minimum sont inserees dans L */ /* on explore d'abord les aretes horizontales */ for(j = 0; j < cs; j++) for(i = 0; i < rs -1; i++){ u = j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if( (mcmin(Vminima[x], Vminima[y]) == 0) && /* un des deux sommets non ds un minima */ (mcmax(Vminima[x], Vminima[y]) > 0) ) /* et l'autre dans un minima */ LifoPush(L,u); } /* puis les aretes verticales */ for(j = 0; j < cs -1; j++) for(i = 0; i < rs; i++) { u = N + j * rs + i; x = Sommetx(u,N,rs); y = Sommety(u,N,rs); if( (mcmin(Vminima[x], Vminima[y]) == 0) && /* un des deux sommets non ds un minima */ (mcmax(Vminima[x], Vminima[y]) > 0) ) /* et l'autre dans un minima */ LifoPush(L,u); } /*************BOUCLE PRINCIPALE*****************/ while(!LifoVide(L)) { u = LifoPop(L); x = Sommetx(u, N, rs); y = Sommety(u, N, rs); if (VF[x] > VF[y]) {z = y; y = x; x = z;} if((VF[x] < F[u]) && (VF[y] == F[u])){ /* u est une arete de bord */ F[u] = VF[x]; VF[y] = F[u]; // Eminima[u] = Vminima[x]; Vminima[y] = Vminima[x]; for(k = 0; k < 8; k +=2){ if( (z = voisin(y, k, rs, N)) != -1) if( (Vminima[z] == 0)) LifoPush(L, Arete(y,z,rs,N)); } /* for(k = 0 .. */ } /* if( (VF[x] < ... */ }/* while(!LifoVide... */ // free(Eminima); free(VF); return res; }// mBorderWshed2drapide(...)
/* ==================================== */ int32_t lpoint(struct xvimage * image1, int32_t x, int32_t y, int32_t z, float v) /* ==================================== */ #undef F_NAME #define F_NAME "lpoint" { int32_t rs, cs, d, n; rs = rowsize(image1); cs = colsize(image1); d = depth(image1); n = rs * cs; /* ---------------------------------------------------------- */ /* calcul du resultat */ /* ---------------------------------------------------------- */ if (datatype(image1) == VFF_TYP_1_BYTE) { uint8_t *pt1 = UCHARDATA(image1); if ((x >= 0) && (x < rs) && (y >= 0) && (y < cs) && (z >= 0) && (z < d) && (v >= NDG_MIN) && (v <= NDG_MAX)) pt1[z * n + y * rs + x] = (uint8_t)v; else { fprintf(stderr, "%s : out of range\n", F_NAME); return 0; } } else if (datatype(image1) == VFF_TYP_4_BYTE) { int32_t *pt1 = SLONGDATA(image1); if ((x >= 0) && (x < rs) && (y >= 0) && (y < cs) && (z >= 0) && (z < d) && (v >= 0)) pt1[z * n + y * rs + x] = (int32_t)v; else { fprintf(stderr, "%s : out of range\n", F_NAME); return 0; } } else if (datatype(image1) == VFF_TYP_FLOAT) { float *pt1 = FLOATDATA(image1); if ((x >= 0) && (x < rs) && (y >= 0) && (y < cs) && (z >= 0) && (z < d)) pt1[z * n + y * rs + x] = v; else { fprintf(stderr, "%s : out of range\n", F_NAME); return 0; } } else { fprintf(stderr, "%s: bad data type\n", F_NAME); return 0; } return 1; } // lpoint()
/*=====================================================================================*/ float * Overlap(struct xvimage * Isegment, struct xvimage * Imask, int nb_classes) /*=====================================================================================*/ // Computes the overlap score between a segment and the ground truth. // Overlap scores are given for each classes and stacked in a tensor. // inputs : * segment: binary image: foreground backround segmentation // * mask: ground truth image: integers between 1 and 22 { int i, j, k, p, q; // get pointer to Isegment and Imask uint8_t *segment = UCHARDATA(Isegment); uint8_t *mask = UCHARDATA(Imask); int rs = rowsize(Isegment); int cs = colsize(Isegment); int N = rs*cs; Lifo * LIFO; LIFO = CreeLifoVide(N); if (LIFO == NULL) { fprintf(stderr, "Overlap : CreeLifoVide failed\n"); exit(0); } float * overlaping_class = (float*)calloc(nb_classes ,sizeof(float)); float * union_class = (float*)calloc(nb_classes ,sizeof(float)); uint8_t * Mrk = (uint8_t*)calloc(N ,sizeof(uint8_t)); if (Mrk == NULL) { fprintf(stderr, "Overlap : malloc failed\n"); exit(0); } // first pass to count the nb of different ground truth class intersecting with the segment for (i=0;i<N;i++) if (segment[i]==255) overlaping_class[mask[i]-1]++; // useful for inter // second pass to compute the union for each present class for (j=0;j<nb_classes;j++) { if (overlaping_class[j]>0.5) //for each class present in the segment { for (i=0;i<N;i++) // for each pixel { if ((segment[i]==255)&&(mask[i]==j+1)) { LifoPush(LIFO, i); Mrk[i] = true; } } union_class[j] = overlaping_class[j]; while (!LifoVide(LIFO)) { p = LifoPop(LIFO); Mrk[p]=true; for (k = 0; k < 8; k += 2) { q = voisin(p, k, rs, N); if (q!=-1) if ((Mrk[q]==false)&&(mask[q]==mask[p])) { union_class[j]++; LifoPush(LIFO, q); Mrk[q]=true; } } } //last pass: overlap = intersection/union overlaping_class[j]=overlaping_class[j]/union_class[j]; } } LifoTermine(LIFO); free(Mrk); free(union_class); return overlaping_class; }