Beispiel #1
0
/* ==================================== */
void empilevoisins(int32_t x, int32_t rs, int32_t N, Fifo *FIFOna, Fifo *FIFOea, Fifo *FIFOsa, Fifo *FIFOoa)
/* ==================================== */
{
  int32_t y, z, k;

  /* x est un point qui vient de passer a 0 */
  for (k = 0; k < 8; k++)
  {
    y = voisin(x, k, rs, N);
    if ((y!=-1) && !IsSet(y,MINI) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N))
    { 
      z = voisin(y, NORD, rs, N);
      if ((z != 0) && IsSet(z, MINI))
      { FifoPush(FIFOna, y); Set(y, EN_FIFO); goto nextk; }
      z = voisin(y, SUD, rs, N);
      if ((z != 0) && IsSet(z, MINI))
      { FifoPush(FIFOsa, y); Set(y, EN_FIFO); goto nextk; }
      z = voisin(y, EST, rs, N);
      if ((z != 0) && IsSet(z, MINI))
      { FifoPush(FIFOea, y); Set(y, EN_FIFO); goto nextk; }
      z = voisin(y, OUEST, rs, N);
      if ((z != 0) && IsSet(z, MINI))
      { FifoPush(FIFOoa, y); Set(y, EN_FIFO); goto nextk; }
    }
nextk: ;
  }
} /* empilevoisins() */
Beispiel #2
0
int* voisinageTriangle(std::vector<Triangle> listeTriangle){

	int* voisinage = new int[3*listeTriangle.size()];
	
	for(int i = 0; i<3*listeTriangle.size(); i++){
		voisinage[i] = -1;
	}
	
	int indice = 0;
	
	for(int i =0; i< listeTriangle.size(); i++){
	
		indice = 0;
		for(int j =0; j< listeTriangle.size(); j++){
		
			if( !listeTriangle.at(i).compareTriangle(listeTriangle.at(j)) && voisin(listeTriangle.at(i), listeTriangle.at(j)) ){
				voisinage[3*i + indice] = j;
				indice++;
			}
		}
	}
	
	return voisinage;

}
Beispiel #3
0
/* ==================================== */
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() */
Beispiel #4
0
/* ==================================== */
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() */
Beispiel #5
0
/* ==================================== */
int32_t lerosfast(struct xvimage *f, uint8_t *mask)
/* mask : masque du 8-voisinage representant l'element structurant */
/* ==================================== */
{
  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(f);         /* taille ligne */
  int32_t cs = colsize(f);         /* taille colonne */
  int32_t N = rs * cs;             /* taille image */
  uint8_t *F = UCHARDATA(f);
  uint8_t *H;                     /* image de travail */
  uint8_t inf;

  if (depth(f) != 1) 
  {
    fprintf(stderr, "ldilatfast: cette version ne traite pas les images volumiques\n");
    return 0;
  }

  H = (uint8_t *)calloc(1,N*sizeof(char));
  if (H == NULL)
  {   fprintf(stderr,"lerosfast() : malloc failed for H\n");
      return(0);
  }
  for (x = 0; x < N; x++) H[x] = F[x];

  for (x = 0; x < N; x++)
  {
    inf = H[x];                         /* l'ES est reflexif */
    for (k = 0; k < 8; k += 1)
    {
      if (mask[k])                      /* element structurant */
      {
        y = voisin(x, k, rs, N);
        if ((y != -1) && (H[y] < inf)) inf = H[y];
#ifdef BORDZERO
        if (y == -1) inf = NDG_MIN;
#endif
      }
    } /* for k */
    F[x] = inf;
  }

  free(H);
  return 1;
}
Beispiel #6
0
/* ==================================== */
int32_t abaisse8(int32_t x, int32_t *DT, int32_t rs, int32_t N)
/* ==================================== */
{
  int32_t y, k, abaisse;
  int32_t t4mm, t4m, t8p, t8pp;
  uint32_t d, old;

  old = DT[x];

  do
  {
    abaisse = 0;
    nbtopoh_l(DT, x, DT[x], rs, N, &t4mm, &t4m, &t8p, &t8pp);
    if ((t8p == 1) && (t4mm == 1))
    {
      nbtopoh_l(DT, x, DT[x]-1, rs, N, &t4mm, &t4m, &t8p, &t8pp);
      if ((t8p == 1) && (t4mm == 1))
      {
        d = alpha8m_l(DT, x, rs, N);
        d = mcmin((DT[x]-1),(d+1));
        DT[x] = d;
        abaisse = 1;
#ifdef DEBUG
        printf("pre-abaisse a d = %ld\n", d);
#endif
#ifndef OLD_VERSION
        for (k = 0; k < 8; k += 1)         /* parcourt les voisins en 8-connexite  */
        {
          y = voisin(x, k, rs, N);
          if ((y != -1) && (DT[y] <= DT[x]) && (DT[y]==alpha8p_l(DT, y, rs, N)))
          {
            DT[x] += 1; abaisse = 0; break;
          } /* if y */
        } /* for k */      
#endif
      }
    } // if ((t8p == 1) && (t4mm == 1))
  } while (abaisse);
  if (DT[x] < old) return 1; else return 0;
} // abaisse8()
Beispiel #7
0
/* ==================================== */
int32_t ldir(struct xvimage * image1, int32_t dir)
/* ==================================== */
{
  int32_t i, v;
  uint8_t *pt1;
  int32_t rs, cs, N;

  if (depth(image1) != 1) 
  {
    fprintf(stderr, "ldir: cette version ne traite pas les images volumiques\n");
    return 0;
  }

  rs = rowsize(image1);
  cs = colsize(image1);
  N = rs * cs;
  
  IndicsInit(N);

  /* ---------------------------------------------------------- */
  /* calcul du resultat */
  /* ---------------------------------------------------------- */
  pt1 = UCHARDATA(image1);
  for (i = 0; i < N; i++)
    if (pt1[i])
    {
      v = voisin(i, dir, rs, N);
      if ((v != -1) && (pt1[v] < pt1[i]))
         Set(i,0);
    }

  for (i = 0; i < N; i++) if (IsSet(i,0)) pt1[i] = NDG_MAX; else pt1[i] = NDG_MIN;

  IndicsTermine();
  return 1;
}
Beispiel #8
0
/* ==================================== */
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() */
Beispiel #9
0
/* ==================================== */
int32_t lattribute(
        struct xvimage *img, /* image de depart */
        int32_t connex,          /* 4, 8  */
        int32_t typregion,       /* = <LABMIN | LABMAX | LABPLATEAU> */
        int32_t attrib,          /* 0: surface, 1: perimetre, 2: circularite, 3: nb. trous, 
                                4: excentricite, 5: orientation, 6: diamètre vertical, 7: diamètre horizontal */
        int32_t seuil,           /* en dessous (<=) de seuil, l'attribut est mis a 0 */
        struct xvimage *lab, /* resultat: image d'attributs */
        int32_t *nlabels)        /* resultat: nombre de regions traitees */
/* ==================================== */
#undef F_NAME
#define F_NAME "lattribute"
{
  int32_t k, l;
  index_t w, x, y, z;
  uint8_t *SOURCE = UCHARDATA(img);
  int32_t *LABEL = SLONGDATA(lab);
  index_t rs = rowsize(img);
  index_t cs = colsize(img);
  index_t d = depth(img);
  index_t N = rs * cs;          /* taille image */
  Lifo * LIFO;
  int32_t label;
  int32_t area;
  int32_t perim;
  int32_t min, max;
  int32_t val_attrib;
  double mx1, my1; // cumuls des variables x et y
  double mx2, my2, mxy2; // cumuls des x^2, y^2 et xy
  int32_t incr_vois;

  if (datatype(lab) != VFF_TYP_4_BYTE) 
  {
    fprintf(stderr, "%s: le resultat doit etre de type VFF_TYP_4_BYTE\n", F_NAME);
    return 0;
  }

  if ((rowsize(lab) != rs) || (colsize(lab) != cs) || (depth(lab) != d))
  {
    fprintf(stderr, "%s: tailles images incompatibles\n", F_NAME);
    return 0;
  }

  if (depth(img) != 1) 
  {
    fprintf(stderr, "%s: cette version ne traite pas les images volumiques\n", F_NAME);
    exit(0);
  }

  switch (connex)
  {
    case 4: incr_vois = 2; break;
    case 8: incr_vois = 1; break;
    default: 
      fprintf(stderr, "%s: mauvaise connexite: %d\n", F_NAME, connex);
      return 0;
  } /* switch (connex) */

  /* le LABEL initialement est mis a NONMARQUE */
  for (x = 0; x < N; x++) LABEL[x] = NONMARQUE;

  LIFO = CreeLifoVide(N);
  if (LIFO == NULL)
    {   fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME);
      return(0);
  }

  *nlabels = 0;

if ((typregion == LABMIN) || (typregion == LABMAX))
{
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)   /* on trouve un point x non etiquete */
    {
      *nlabels += 1;
      LABEL[x] = MARQUE;
#ifdef DEBUGTROU
printf("AMORCE p=%d,%d h=%d set LABEL = %d\n", x%rs, x/rs, SOURCE[x], LABEL[x]);
#endif
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
	case PERIM: val_attrib = 0; break;
	case TROUS: val_attrib = 0; break;
	case CIRC: area = perim = 0; break;
	case EXCEN: 
	case ORIEN: area = 0; mx1 = my1 = mx2 = my2 = mxy2 = 0.0; break;
        case VDIAM: min = cs-1; max = 0; break;
        case HDIAM: min = rs-1; max = 0; break;
        default: 
          fprintf(stderr, "%s: mauvais attribut: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);         /* on va parcourir le plateau auquel appartient x */
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        label = LABEL[w];
        if (label == MARQUE)     /* c'est une propagation de "marquage" : pour l'instant, */
	{                        /* on croit qu'on est dans un extremum */         
          switch (attrib)
          {
  	    case AREA: val_attrib++; break;
  	    case VDIAM: if (w/rs < min) min = w/rs; else if (w/rs > max) max = w/rs; break;
  	    case HDIAM: if (w%rs < min) min = w%rs; else if (w%rs > max) max = w%rs; break;
  	    case EXCEN:
  	    case ORIEN: area++; mx1 += w%rs; my1 += w/rs; mxy2 += (w%rs) * (w/rs);
                        mx2 += (w%rs) * (w%rs); my2 += (w/rs) * (w/rs); break;
  	    case PERIM: 
              if (w%rs==rs-1) val_attrib++; /* point de bord */
              if (w<rs)       val_attrib++; /* point de bord */
              if (w%rs==0)    val_attrib++; /* point de bord */
              if (w>=N-rs)    val_attrib++; /* point de bord */
              for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
              {
                y = voisin(w, k, rs, N);
                if ((y != -1) && (SOURCE[y] != SOURCE[w])) val_attrib++;
              } /* for k */
            break;
            case CIRC:
              area++;
              if (w%rs==rs-1) perim++; /* point de bord */
              if (w<rs)       perim++; /* point de bord */
              if (w%rs==0)    perim++; /* point de bord */
              if (w>=N-rs)    perim++; /* point de bord */
              for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
              {
                y = voisin(w, k, rs, N);
                if ((y != -1) && (SOURCE[y] != SOURCE[w])) perim++;
              } /* for k */
              break;
	  } /* switch (attrib) */
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if (y != -1)
            {
              if (((typregion == LABMIN) && (SOURCE[y] < SOURCE[w])) || 
                  ((typregion == LABMAX) && (SOURCE[y] > SOURCE[w])))
              {   /* w non dans un minimum (resp. maximum) */
                if (label == MARQUE)
		{
                  label = NONEXTREM;
                  *nlabels -= 1;
                  LABEL[w] = label;
                  LifoPush(LIFO, w);
		}
              } 
              else
              if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE))
              {
                LABEL[y] = label;
#ifdef DEBUGTROU
printf(" p=%d,%d h=%d set LABEL = %d\n", y%rs, y/rs, SOURCE[y], LABEL[y]);
#endif
                LifoPush(LIFO, y);
                if (attrib == TROUS)
	        {
                  int32_t masque = 0, imasque = 1;
                  /* fabrique le masque des voisins de y MARQUES */
                  for (l = 0; l < 8; l += 1)
                  {
                    z = voisin(y, l, rs, N);
                    if ((z != -1) && (LABEL[z] == MARQUE))
                      masque |= imasque; 
                    imasque = imasque << 1;
                  } /* for k ... */
#ifdef DEBUGTROU
printf(" p=%d,%d h=%d masque=%x t4m=%d t8b=%d\n", y%rs, y/rs, SOURCE[y], masque, t4(masque), t8b(masque));
#endif
                  if (connex == 4) 
                    { val_attrib += (t4(masque) - 1); if (t8b(masque) == 0) val_attrib--; }
                  else
                    { val_attrib += (t8(masque) - 1); if (t4b(masque) == 0) val_attrib--; }
	        } /* if (attrib == TROUS) */
              } /* if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE)) */
            } /* if (y != -1) */
          } /* for k ... */
	} /* if (label == MARQUE) */
        else                           /* propagation de "demarquage" */
	{
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if (y != -1)
            {
              if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] != NONEXTREM))
              {
                LABEL[y] = NONEXTREM;
                LifoPush(LIFO, y);
              } /* if .. */
            } /* if (y != -1) */
          } /* for k ... */
	} /* else if (label == MARQUE) */
      } /* while (! LifoVide(LIFO)) */

      if (label == MARQUE)
      {
        if (attrib == CIRC) 
	{
          val_attrib = (int32_t)(256 * 4 * M_PI * (double)area / (double)(perim * perim));
          if (val_attrib > 255)
	  {
            fprintf(stderr, "WARNING: indice de circularite > 255 : %d, a=%d, p=%d\n", 
                            val_attrib, area, perim);
            val_attrib = 255;
	  }
	}
        if (attrib == EXCEN) val_attrib = excentricity(mx1, my1, mx2, my2, mxy2, area);
        if (attrib == ORIEN) val_attrib = orientation(mx1, my1, mx2, my2, mxy2, area);
        if (attrib == VDIAM) val_attrib = max - min + 1;
        if (attrib == HDIAM) val_attrib = max - min + 1;
        if (val_attrib <= seuil) val_attrib = 0;
#ifdef VERBOSE
printf("valeur attribut = %d\n", val_attrib);
#endif
        LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
        LABEL[x] = val_attrib;
        while (! LifoVide(LIFO))
        {
          w = LifoPop(LIFO);
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if ((y != -1) && (LABEL[y] == MARQUE)) 
            {
              LABEL[y] = val_attrib;
              LifoPush(LIFO, y);
	    }
          } /* for k ... */
	} /* while (! LifoVide(LIFO)) */
      } /* if (label == MARQUE) */

    } /* if (LABEL[x] != -1) */
  } /* for (x = 0; x < N; x++) */
} /* if ((typregion == LABMIN) || (typregion == LABMAX)) */
else
{
  if (attrib == TROUS)
  {
    fprintf(stderr, "%s: attribut TROUS non compatible avec typreg = PLA\n", F_NAME);
    return 0;
  }
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)
    {
      *nlabels += 1;
      LABEL[x] = *nlabels;
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
        case VDIAM: min = cs-1; max = 0; break;
        case HDIAM: min = rs-1; max = 0; break;
	case PERIM: val_attrib = 0; break;
	case CIRC: area = perim = 0; break;
	case EXCEN: 
	case ORIEN: area = 0; mx1 = my1 = mx2 = my2 = mxy2 = 0.0; break;
        default: 
          fprintf(stderr, "%s: mauvais attribut: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        switch (attrib)
        {
	  case AREA: val_attrib++; break;
  	  case VDIAM: if (w/rs < min) min = w/rs; else if (w/rs > max) max = w/rs; break;
  	  case HDIAM: if (w%rs < min) min = w%rs; else if (w%rs > max) max = w%rs; break;
	  case EXCEN:
	  case ORIEN: area++; mx1 += w%rs; my1 += w/rs; mxy2 += (w%rs) * (w/rs);
                      mx2 += (w%rs) * (w%rs); my2 += (w/rs) * (w/rs); break;
  	  case PERIM: 
            if (w%rs==rs-1) val_attrib++; /* point de bord */
            if (w<rs)       val_attrib++; /* point de bord */
            if (w%rs==0)    val_attrib++; /* point de bord */
            if (w>=N-rs)    val_attrib++; /* point de bord */
            for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
            {
              y = voisin(w, k, rs, N);
              if ((y != -1) && (SOURCE[y] != SOURCE[w])) val_attrib++;
            } /* for k */
          break;
          case CIRC:
            area++;
            if (w%rs==rs-1) perim++; /* point de bord */
            if (w<rs)       perim++; /* point de bord */
            if (w%rs==0)    perim++; /* point de bord */
            if (w>=N-rs)    perim++; /* point de bord */
            for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
            {
              y = voisin(w, k, rs, N);
              if ((y != -1) && (SOURCE[y] != SOURCE[w])) perim++;
            } /* for k */
            break;
	} /* switch (attrib) */

        for (k = 0; k < 8; k += incr_vois)
        {
          y = voisin(w, k, rs, N);
          if ((y != -1) && (LABEL[y] == NONMARQUE) && (SOURCE[y] == SOURCE[w]))
          {
            LABEL[y] = MARQUE;
            LifoPush(LIFO, y);
          } /* if y ... */
        } /* for k ... */
      } /* while (! LifoVide(LIFO)) */

      if (attrib == CIRC) 
      {
        val_attrib = (int32_t)(256 * 4 * M_PI * (double)area / (double)(perim * perim));
        if (val_attrib > 255)
	{
          fprintf(stderr, "WARNING: indice de circularite > 255 : %d, a=%d, p=%d\n", 
                          val_attrib, area, perim);
          val_attrib = 255;
	}
      }
      if (attrib == EXCEN) val_attrib = excentricity(mx1, my1, mx2, my2, mxy2, area);
      if (attrib == ORIEN) val_attrib = orientation(mx1, my1, mx2, my2, mxy2, area);
      if (attrib == VDIAM) val_attrib = max - min + 1;
      if (attrib == HDIAM) val_attrib = max - min + 1;
      if (val_attrib <= seuil) val_attrib = 0;

      LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
      LABEL[x] = val_attrib;
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        for (k = 0; k < 8; k += incr_vois)
        {
          y = voisin(w, k, rs, N);
          if ((y != -1) && (LABEL[y] == MARQUE)) 
          {
            LABEL[y] = val_attrib;
            LifoPush(LIFO, y);
	  }
        } /* for k ... */
      } /* while (! LifoVide(LIFO)) */
    } /* if (LABEL[x] == NONMARQUE) */
  } /* for (x = 0; x < N; x++) */
} /* else if ((typregion == LABMIN) || (typregion == LABMAX)) */

  LifoTermine(LIFO);

  *nlabels += 1; /* pour le niveau 0 */
  return(1);
} // lattribute()
Beispiel #10
0
/* ==================================== */
int32_t lnbvois(
  struct xvimage * image,
  int32_t connex)
/* ==================================== */
{
  int32_t nvois, k;
  int32_t p, q;
  int32_t rs = rowsize(image);
  int32_t cs = colsize(image);
  int32_t ds = depth(image);
  int32_t ps = rs * cs;          /* taille plan */
  int32_t N = ps * ds;           /* taille image */
  uint8_t *F = UCHARDATA(image);      /* l'image de depart */

  switch (connex)
  {
    case 4: 
      for (p = 0; p < N; p++)
        if (F[p])
        {
          nvois = 0;                /* compte le nombre de voisins non nuls */
          for (k = 0; k < 8; k += 2)
          {
            q = voisin(p, k, rs, N);
            if ((q != -1) && (F[q])) nvois++;
          }
          F[p] = nvois;
        }
      break;
    case 8: 
      for (p = 0; p < N; p++)
        if (F[p])
        {
          nvois = 0;                /* compte le nombre de voisins non nuls */
          for (k = 0; k < 8; k += 1)
          {
            q = voisin(p, k, rs, N);
            if ((q != -1) && (F[q])) nvois++;
          }
          F[p] = nvois;
        }
      break;
    case 6: 
      for (p = 0; p < N; p++)
        if (F[p])
        {
          nvois = 0;                /* compte le nombre de voisins non nuls */
          for (k = 0; k <= 10; k += 2)
          {
            q = voisin6(p, k, rs, ps, N);
            if ((q != -1) && (F[q])) nvois++;
          }
          F[p] = nvois;
        }
      break;
    case 18: 
      for (p = 0; p < N; p++)
        if (F[p])
        {
          nvois = 0;                /* compte le nombre de voisins non nuls */
          for (k = 0; k < 18; k += 1)
          {
            q = voisin18(p, k, rs, ps, N);
            if ((q != -1) && (F[q])) nvois++;
          }
          F[p] = nvois;
        }
      break;
    case 26: 
      for (p = 0; p < N; p++)
        if (F[p])
        {
          nvois = 0;                /* compte le nombre de voisins non nuls */
          for (k = 0; k < 26; k += 1)
          {
            q = voisin26(p, k, rs, ps, N);
            if ((q != -1) && (F[q])) nvois++;
          }
          F[p] = nvois;
        }
      break;
    default: 
      fprintf(stderr, "lnbvois: mauvaise connexite: %d\n", connex);
      return 0;
  } /* switch (connex) */
  return 1;
}
Beispiel #11
0
/* ==================================== */
int32_t ldilatbin_ldilatbin(struct xvimage *f, struct xvimage *m, int32_t xc, int32_t yc)
/* m : masque representant l'element structurant */
/* xc, yc : coordonnees de l'origine de l'element structurant */
/* ==================================== */
{
  int32_t x, y, z, w;              /* index muet de pixel */
  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 */
  uint8_t sup;
  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 c;
  int32_t frontiere;

  if (depth(f) != 1) 
  {
    fprintf(stderr, "ldilatbin_ldilatbin: cette version ne traite pas les images volumiques\n");
    return 0;
  }

  if (!M[yc * rsm + xc]) /* l'element structurant N'est PAS reflexif */
  {
    fprintf(stderr, "ldilatbin_ldilatbin: l'element structurant doit etre reflexif\n");
    return 0;
  }

  H = (uint8_t *)calloc(1,N*sizeof(char));
  if (H == NULL)
  {  
     fprintf(stderr,"ldilatbin_ldilatbin() : malloc failed for H\n");
     return(0);
  }

  memcpy(H, F, N);

  nptb = 0;
  for (i = 0; i < Nm; i += 1)
    if (M[i])
      nptb += 1;

  tab_es_x = (int32_t *)calloc(1,nptb * sizeof(int32_t));
  tab_es_y = (int32_t *)calloc(1,nptb * sizeof(int32_t));
  if ((tab_es_x == NULL) || (tab_es_y == NULL))
  {  
     fprintf(stderr,"ldilatbin_ldilatbin() : 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++)
  {
    /* verifie si (x,y) est un point de la frontiere de l'objet */
    w = y * rs + x;
    if (H[w])
    {
      frontiere = 0;
      for (k = 0; k < 8; k += 2) /* on cherche une frontiere 8-connexe */
      {
        z = voisin(w, k, rs, N);
        if ((z != -1) && (!H[z])) { frontiere = 1; break; }
      } /* for k... */

      if (!frontiere) 
        F[w] = NDG_MAX;
      else
      {
        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))
	    F[l * rs + k] = NDG_MAX;
        }
      }
    }
  }

  free(H);
  free(tab_es_x);
  free(tab_es_y);
  return 1;
}
Beispiel #12
0
/* ==================================== */
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() */
Beispiel #13
0
/* ==================================== */
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() */
Beispiel #14
0
/*  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(...)
Beispiel #15
0
/*  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;
}
Beispiel #16
0
/* ==================================== */
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() */
Beispiel #17
0
/* ==================================== */
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()
Beispiel #18
0
/* ==================================== */
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;
}
Beispiel #19
0
/* 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;
}
Beispiel #20
0
/* ==================================== */
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() */
Beispiel #21
0
/* ==================================== */
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() */
Beispiel #22
0
/* ==================================== */
static int32_t TrouveComposantes(int32_t x, uint8_t *F, int32_t rs, int32_t ps, int32_t N, int32_t connex, 
                             int32_t *CM, int32_t *tabcomp)
/* ==================================== */
// variante sans simplification 
// place la plus haute composante (ou l'une des plus hautes) en premier
{
  int32_t k, y, n = 1, maxval = F[x], first = 1;

  switch (connex)
  {
  case 4:
    for (k = 0; k < 8; k += 2) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin(x, k, rs, N);
      if ((y != -1) && (F[y] > maxval)) maxval = F[y];
    } /* for (k = 0; k < 8; k += 2) */
    if (maxval == F[x]) return 0;
    for (k = 0; k < 8; k += 2) // parcourt les c-voisins y de x d'un niveau > F[x]

    { y = voisin(x, k, rs, N);
      if ((y != -1) && (F[y] > F[x]))
      {	if (first && (F[y] == maxval)) { tabcomp[0] = CM[y]; first = 0; }
	else                           { tabcomp[n] = CM[y]; n++; }
      }
    } break;
  case 8:
    for (k = 0; k < 8; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin(x, k, rs, N);
      if ((y != -1) && (F[y] > maxval)) maxval = F[y];
    } /* for (k = 0; k < 8; k += 1) */
    if (maxval == F[x]) return 0;
    for (k = 0; k < 8; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin(x, k, rs, N);
      if ((y != -1) && (F[y] > F[x]))
      {	if (first && (F[y] == maxval)) { tabcomp[0] = CM[y]; first = 0; }
	else                           { tabcomp[n] = CM[y]; n++; }
      }
    } break;
  case 6:
    for (k = 0; k <= 10; k += 2) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin6(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > maxval)) maxval = F[y];
    }
    if (maxval == F[x]) return 0;
    for (k = 0; k <= 10; k += 2) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin6(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > F[x]))
      {	if (first && (F[y] == maxval)) { tabcomp[0] = CM[y]; first = 0; }
	else                           { tabcomp[n] = CM[y]; n++; }
      }
    } break;
  case 18:
    for (k = 0; k < 18; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin18(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > maxval)) maxval = F[y];
    }
    if (maxval == F[x]) return 0;
    for (k = 0; k < 18; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin18(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > F[x]))
      {	if (first && (F[y] == maxval)) { tabcomp[0] = CM[y]; first = 0; }
	else                           { tabcomp[n] = CM[y]; n++; }
      }
    } break;
  case 26:
    for (k = 0; k < 26; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin26(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > maxval)) maxval = F[y];
    }
    if (maxval == F[x]) return 0;
    for (k = 0; k < 26; k += 1) // parcourt les c-voisins y de x d'un niveau > F[x]
    { y = voisin26(x, k, rs, ps, N);
      if ((y != -1) && (F[y] > F[x]))
      {	if (first && (F[y] == maxval)) { tabcomp[0] = CM[y]; first = 0; }
	else                           { tabcomp[n] = CM[y]; n++; }
      }
    } break;
  } // switch (connex)
  return n;
} // TrouveComposantes() 
Beispiel #23
0
/* ==================================== */
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);
}
Beispiel #24
0
/* ==================================== */
int32_t lkern(struct xvimage *image, int32_t connex)
/* ==================================== */
{ 
  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(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 */
  Fahp * FAHP;
  int32_t t4mm, t4m, t8p, t8pp;
#ifdef DEBUG
  uint8_t oldFx;
#endif

  if (depth(image) != 1) 
  {
    fprintf(stderr, "lkern: cette version ne traite pas les images volumiques\n");
    exit(0);
  }

  IndicsInit(N);

  FAHP = CreeFahpVide(N);
  if (FAHP == NULL)
  {   fprintf(stderr, "lkern() : CreeFahpVide failed\n");
      return(0);
  }

  /* ================================================ */
  /*                  DEBUT ALGO                      */
  /* ================================================ */

  /* empile tous les voisins des points du bord */

  for (x = rs + 1, y = (cs-2) * rs + 1; x < 2*rs-1; x++, y++)
  {
    FahpPush(FAHP, x, F[x]); Set(x, EN_FAHP);
    FahpPush(FAHP, y, F[y]); Set(y, EN_FAHP);
  }

  for (x = 2*rs+1 , y = 3*rs-2; x < (cs-2)*rs+1; y += rs, x += rs)
  {
    FahpPush(FAHP, x, F[x]); Set(x, EN_FAHP);
    FahpPush(FAHP, y, F[y]); Set(y, EN_FAHP);
  }

  saturation(rs, cs, N, F, FAHP);

  /* met a 0 les puits et les interieurs de plateaux (T-- = 0) */
  /* et empile les voisins */

  for (x = 0; x < N; x++)
  if ((x%rs != rs-1) && (x >= rs) && (x%rs != 0) && (x < N-rs) && /* non point de bord */
      (F[x] != 0))
  {
    nbtopo(F, x, rs, N, &t4mm, &t4m, &t8p, &t8pp);
    if (t4mm == 0)
    {
      F[x] = 0;
      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 (t4mm == 0) */
    saturation(rs, cs, N, F, FAHP);
  } /* for (x = 0; x < N; x++) */

  /* ================================================ */
  /* UN PEU DE MENAGE                                 */
  /* ================================================ */

  IndicsTermine();
  FahpTermine(FAHP);
  return(1);
}
Beispiel #25
0
/* ==================================== */
int32_t lamont(
        struct xvimage *m,
        struct xvimage *f,
        int32_t connex,
        int32_t strict) 
/* connex : 4, 8 (en 2D), 6, 18, 26 (en 3D) */
/* ==================================== */
#undef F_NAME 
#define F_NAME "lamont"
{
  int32_t i, j, k;                 /* index muet de pixel */
  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 *F = SLONGDATA(f);
  uint8_t *M = UCHARDATA(m);
  Fifo * FIFO;
  int32_t incr_vois;

  if ((rowsize(m) != rs) || (colsize(m) != cs) || (depth(m) != ds))
  {
    fprintf(stderr, "%s: incompatible sizes\n", F_NAME);
    return 0;
  }

  if ((datatype(m) != VFF_TYP_1_BYTE) || (datatype(f) != VFF_TYP_4_BYTE))
  {
    fprintf(stderr, "%s: incompatible types\n", F_NAME);
    return 0;
  }

  switch (connex)
  {
    case 4: incr_vois = 2; break;
    case 8: incr_vois = 1; break;
  } /* switch (connex) */

  FIFO = CreeFifoVide(N);
  if (FIFO == NULL)
  {   fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME);
      return(0);
  }

  for (i = 0; i < N; i++) if (M[i]) FifoPush(FIFO, i); 

  if ((connex == 4) || (connex == 8))
  {
    if (ds != 1)
    {
      fprintf(stderr,"%s : connexity 4 or 8 not defined for 3D\n", F_NAME);
      return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 8; k += incr_vois)
      {
        j = voisin(i, k, rs, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 8; k += incr_vois)
      {
        j = voisin(i, k, rs, N);
//printf("i=%d ; j=%d ; Mj=%d ; Fj=%ld ; Fi=%ld\n", i, j, M[j], F[j], F[i]);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 6)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 10; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 10; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 18)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 18 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 18; k += 1)
      {
        j = voisin18(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }

      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 18; k += 1)
      {
        j = voisin18(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }

      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 26)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 26; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 26; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  FifoTermine(FIFO);
  return 1;
} /* lamont() */
Beispiel #26
0
/* ==================================== */
int32_t lselectcomp(
        struct xvimage *f,
        int32_t connex,
        int32_t x, 
        int32_t y, 
        int32_t z) 
/* extrait la composante connexe de f (image binaire) 
   qui contient le point (x,y,z) */
/* connex : 4, 8 (en 2D), 6, 18, 26 (en 3D) */
/* connex : 60, 260 (en 3D): idem 6 et 26 mais dans le plan xy seulement */
/* ==================================== */
#undef F_NAME 
#define F_NAME "lselectcomp"
{
  int32_t i;                       /* index muet de pixel */
  int32_t j;                       /* index muet (generalement un voisin de x) */
  int32_t k;                       /* 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 */
  uint8_t *F = UCHARDATA(f);
  Fifo * FIFO;
  int32_t incr_vois;

  switch (connex)
  {
    case 4: incr_vois = 2; break;
    case 8: incr_vois = 1; break;
  } /* switch (connex) */

  FIFO = CreeFifoVide(N);
  if (FIFO == NULL)
  {   fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME);
      return(0);
  }

  for (i = 0; i < N; i++) if (F[i]) F[i] = 254;
  i = z*ps + y*rs + x;
  if (F[i]) { FifoPush(FIFO, i); F[i] += 1; }

  if ((connex == 4) || (connex == 8))
  {
    if (ds != 1)
    {   fprintf(stderr,"%s : connexity 4 or 8 not defined for 3D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 8; k += incr_vois)
      {
        j = voisin(i, k, rs, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 6)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 10; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 18)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 18 not defined for 2D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 18; k += 1)
      {
        j = voisin18(i, k, rs, ps, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 26)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 26; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 60)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 6; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 260)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME);
        return(0);
    }
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 9; k <= 16; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  FifoTermine(FIFO);
  for (i = 0; i < N; i++) if (F[i] != 255) F[i] = 0;
  return 1;
} /* lselectcomp() */
Beispiel #27
0
/*=====================================================================================*/
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;
}