Beispiel #1
0
/*-----------------------------------------------------------------
 * Core routine for msskl_filter
 *  - suffix "np" stands for "no padding"
 *  - assumes image is properly padded!
 *  - does not trimm result
 *  - assume shp already allocated
 *  - useful inside loops
 *-----------------------------------------------------------------*/
AnimalExport int
msskl_filter_np(Img *shp, Img *sklimg, annotated_skl *skl, int thresh)
{
   int i,j,k;
   int maxrad, r, c, *pt;
   SEDR *sedr;
   unsigned d;
   unsigned p, pf;

   r = skl->skl->rows;
   c = skl->skl->cols;
   maxrad = skl->maxradius;

   if (thresh > 0) {
      sklimg = new_img(r, c);
      for (i=0; i < r * c; i++)
         sklimg->data[i] = (skl->skl->data[i] >= (puint32) thresh);
   }

   sedr = grow_sedr(maxrad);   
   if (!sedr)
      return false;
   pt = sedr->pt;
   for (i=maxrad; i<shp->rows-maxrad; i++) 
      for (j=maxrad; j<shp->cols-maxrad; j++)
         if ( RC(sklimg, i-maxrad, j-maxrad) == 1 ) {  // found skeleton
            /* 
                Paints digital circle around the skeleton with radius equal 
                to the distance-transform value at each point. There should be a
                more efficient way to do this without using SEDR.
             */
            d = RC(skl->dt, i-maxrad, j-maxrad);

            /* distance 0 */
            RC(shp,i,j) = FG;
            p = 2;

            for (k=1; k < (int)sedr->length && sedr->sqrd_dist[k] <= d; k++) {
               pf = sedr->npts[k];
                  do {
                     RC(shp,i + pt[p], j + pt[p+1]) = FG;
                     p+=2;

                     // unrolling
                     RC(shp,i + pt[p], j + pt[p+1]) = FG;
                     p+=2;

                     RC(shp,i + pt[p], j + pt[p+1]) = FG;
                     p+=2;

                     RC(shp,i + pt[p], j + pt[p+1]) = FG;
                     p+=2;
                  } while (p < pf);
            }
         }
   return true;
}
Beispiel #2
0
AnimalExport nhood *
circular_nhood(double rad)
{
   SEDR *s;
   int *dx, *dy;
   unsigned k, p, n, *pt;
   nhood *nhood;

   s = grow_sedr(rad);
      if (!s) return NULL;
   pt = s->pt;

   nhood = new_nhood( (2*ceil(rad)+1)*(2*ceil(rad)+1) );
   dx = nhood->dx;
   dy = nhood->dy;


   /* -- distance 0 -- */ 
   dy[0] = 0;
   dx[0] = 0;

   n=1;
   p=2;
   /* -- remaining distances -- */             
   for (k=1; k < s->length && non_negative_dbl(rad - s->distance[k]); k++) {
      do {
         dy[n] = pt[p];
         dx[n++] = pt[++p];
         ++p;

         // unrolling
         dy[n] = pt[p];
         dx[n++] = pt[++p];
         ++p;

         dy[n] = pt[p];
         dx[n++] = pt[++p];
         ++p;

         dy[n] = pt[p];
         dx[n++] = pt[++p];
         ++p;
      } while (p < s->npts[k]);
   }

   realloc_nhood(nhood, n);

   /* @@@ seria eficiente ordenar pontos na ordem "raster" */
   return nhood;
}
Beispiel #3
0
AnimalExport ann_img *
exact_propagation(Img *image, ImgPUInt32 *label, list *seed, char side)
{
   char *fname="exact_propagation";
   SEDR *sedr;
   int maxrad, r, c, prev_col, n, rw, cl, i, j, 
       x, y, *pt, *pi, *pf, *lut, d, cp;
   unsigned maxdist, k, pos;
   int *p;  /* @@@ perhaps a register variable is faster */
   ImgPUInt32 *lbl_img, *dist, *pred;
   puint32 *lbl_data, *dist_data, *pred_data;
   pixval *img_data;
   Img *img;
   list_ptr ptr;
	ann_img *aimg;

   r = image->rows; c = image->cols;

   /* estimate the maximum distance to grow */
   if (side != INTERIOR)
      maxrad = ceil(hypot(r,c)); 
   else { 
      maxrad = (int) (ceil((float)MIN(r,c)/2)); 
      for (n=0,i=0; i<r*c; i++)
         n += (image->data[i] == FG);
      maxrad = MIN(maxrad,(int) ceil(sqrt((double)n) / 2));
   }

   sedr = grow_sedr(maxrad);
   if (!sedr) {
      animal_err_register (fname, ANIMAL_ERROR_FAILURE,"");
      return NULL;                                    
   }
   img  = impad(image, maxrad, maxrad, 0); 
   img_data = img->data;
   prev_col = c;
   r = img->rows; c = img->cols;
   n=r*c;


   dist = new_img_puint32(r,c);
   dist_data = dist->data;
   lut = dist->lut;     /* table for (r,c) indexing */
	lbl_img = impad_puint32(label, maxrad, maxrad, 0);
   lbl_data = lbl_img->data;
	pred = new_img_puint32(r,c);
   pred_data = pred->data;

   /*
      We must mark as INVALID_DIST only those pixels that _will_ be 
      processed by the propagation. 
   */
   switch (side) {
      case INTERIOR:
         for (i=0; i<n; i++) {
            pred_data[i] = prev_col*(i/c-maxrad) + i%c - maxrad;
            if (img_data[i] == FG && lbl_data[i] == 0) /* (**) */
               dist_data[i] = INVALID_DIST;
         }
         /* OBS: condition (**) tests for lbl_data[i] == 0 because the
          * seed pixels don't need processing. In fact, the for loop
          * for the propagation starts at i=1 (distance =1), not i=0
          * (distance == 0). */
         break;
      case EXTERIOR:
         for (i=0; i<n; i++) {
            pred_data[i] = prev_col*(i/c-maxrad) + i%c - maxrad;
            if (img_data[i] == BG) 
               dist_data[i] = INVALID_DIST;
         }
         break;
      case BOTH:
         for (i=0; i<n; i++) {
            pred_data[i] = prev_col*(i/c-maxrad) + i%c - maxrad;
            if (lbl_data[i] == 0)
               dist_data[i] = INVALID_DIST;
         }
			break;
      default:
         ANIMAL_ERR_FIRST("exact_propagation", ANIMAL_ERROR_FAILURE, "Invalid side parameter", NULL);
   }

   maxdist = (unsigned) maxrad*maxrad;

   /* -- distances >= 1 -- */             
   pt = sedr->pt;
   p = pt+2;
   for (i=1; i < (int)sedr->length && maxdist >= sedr->sqrd_dist[i]; i++) {
      d = (int)sedr->sqrd_dist[i];
      k=1;
      ptr = get_list_head(seed);
      pi = p;
      pf = pt + sedr->npts[i];
      do {  /* loop the contour */
         cp = get_list_point(ptr);
         x = cp % prev_col + maxrad;
         y = cp / prev_col + maxrad;
         p = pi;
         do { /* loop displacements with distance d */
            rw = y + *p;
            cl = x + *(p+1);
            p+=2;
            pos = cl + lut[rw];
            if (dist_data[pos] == INVALID_DIST) {
               dist_data[pos] = d;
               lbl_data[pos] = k;
               pred_data[pos] = cp;
            }

            /* 
                Four-fold unroll: # of pts at any distance is a multiple of 4
            */
            rw = y + *p;
            cl = x + *(p+1);
            p+=2;
            pos = cl + lut[rw];
            if (dist_data[pos] == INVALID_DIST) {
               dist_data[pos] = d;
               lbl_data[pos] = k;
               pred_data[pos] = cp;
            }

            rw = y + *p;
            cl = x + *(p+1);
            p+=2;
            pos = cl + lut[rw];
            if (dist_data[pos] == INVALID_DIST) {
               dist_data[pos] = d;
               lbl_data[pos] = k;
               pred_data[pos] = cp;
            }

            rw = y + *p;
            cl = x + *(p+1);
            p+=2;
            pos = cl + lut[rw];
            if (dist_data[pos] == INVALID_DIST) {
               dist_data[pos] = d;
               lbl_data[pos] = k;
               pred_data[pos] = cp;
            }
         } while (p < pf);
         k++;
         ptr = next_list_node(ptr);
     } while (not_nil(ptr));
   }


	aimg = new_ann_img(image);
   for (i=maxrad; i<r-maxrad; i++)
      for (j=maxrad; j<c-maxrad; j++) {
         RC(aimg->label,i-maxrad, j-maxrad) = RC(lbl_img, i, j);
         RC(aimg->cost, i-maxrad, j-maxrad) = RC(dist, i, j);
         RC(aimg->pred, i-maxrad, j-maxrad) = RC(pred, i, j);
      }

   /* Liberate memory */   
   imfree(&img);
   imfree_puint32(&lbl_img);
   imfree_puint32(&dist);
   imfree_puint32(&pred);

   return aimg;
}