Example #1
0
/*
 * Calls the (hopefully) desired interpolation/approximation routine.
 */
static void
put_contour(
    cntr_struct *p_cntr,	/* contour structure input */
    double xx_min, double xx_max,
    double yy_min, double yy_max, /* minimum/maximum values input */
    TBOOLEAN contr_isclosed)	/* contour line closed? (input) */
{

    if (!p_cntr)
	return;			/* Nothing to do if it is empty contour. */

    switch (interp_kind) {
    case CONTOUR_KIND_LINEAR:	/* No interpolation/approximation. */
	put_contour_nothing(p_cntr);
	break;
    case CONTOUR_KIND_CUBIC_SPL: /* Cubic spline interpolation. */
	put_contour_cubic(p_cntr, xx_min, xx_max, yy_min, yy_max,
			  chk_contour_kind(p_cntr, contr_isclosed));

	break;
    case CONTOUR_KIND_BSPLINE:	/* Bspline approximation. */
	put_contour_bspline(p_cntr,
			    chk_contour_kind(p_cntr, contr_isclosed));
	break;
    }
    free_contour(p_cntr);
}
Example #2
0
File: ridges.c Project: Booley/nbis
/*************************************************************************
**************************************************************************
#cat: validate_ridge_crossing - Takes a pair of points, a ridge start
#cat:               transition and a ridge end transition, and walks the
#cat:               ridge contour from thre ridge end points a specified
#cat:               number of steps, looking for the ridge start point.
#cat:               If found, then transitions determined not to be a valid
#cat:               ridge crossing.

   Input:
      ridge_start - index into line trajectory of ridge start transition
      ridge_end   - index into line trajectory of ridge end transition
      xlist       - x-pixel coords of line trajectory
      ylist       - y-pixel coords of line trajectory
      num         - number of coords in line trajectory
      bdata       - binary image data (0==while & 1==black)
      iw          - width (in pixels) of image
      ih          - height (in pixels) of image
      max_ridge_steps  - number of steps taken in search in both
                         scan directions
   Return Code:
      TRUE        - ridge crossing VALID
      FALSE       - ridge corssing INVALID
      Negative    - system error
**************************************************************************/
int validate_ridge_crossing(const int ridge_start, const int ridge_end,
                            const int *xlist, const int *ylist, const int num,
                            unsigned char *bdata, const int iw, const int ih,
                            const int max_ridge_steps)
{
   int ret;
   int feat_x, feat_y, edge_x, edge_y;
   int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;

   /* Assign edge pixel pair for contour trace. */
   feat_x = xlist[ridge_end];
   feat_y = ylist[ridge_end];
   edge_x = xlist[ridge_end-1];
   edge_y = ylist[ridge_end-1];

   /* Adjust pixel pair if they neighbor each other diagonally. */
   fix_edge_pixel_pair(&feat_x, &feat_y, &edge_x, &edge_y,
                       bdata, iw, ih);

   /* Trace ridge contour, starting at the ridge end transition, and */
   /* taking a specified number of step scanning for edge neighbors  */
   /* clockwise.  As we trace the ridge, we want to detect if we     */
   /* encounter the ridge start transition.  NOTE: The ridge end     */
   /* position is on the white (of a black to white transition) and  */
   /* the ridge start is on the black (of a black to white trans),   */
   /* so the edge trace needs to look for the what pixel (not the    */
   /* black one) of the ridge start transition.                      */	
   ret = trace_contour(&contour_x, &contour_y,
                       &contour_ex, &contour_ey, &ncontour,
                       max_ridge_steps,
                       xlist[ridge_start-1], ylist[ridge_start-1],
                       feat_x, feat_y, edge_x, edge_y,
                       SCAN_CLOCKWISE, bdata, iw, ih);
   /* If a system error occurred ... */
   if(ret < 0)
      /* Return error code. */
      return(ret);

   /* Otherwise, if the trace was not IGNORED, then a contour was */
   /* was generated and returned.  We aren't interested in the    */
   /* actual contour, so deallocate it.                           */
   if(ret != IGNORE)
      free_contour(contour_x, contour_y, contour_ex, contour_ey);

   /* If the trace was IGNORED, then we had some sort of initialization */
   /* problem, so treat this the same as if was actually located the    */
   /* ridge start point (in which case LOOP_FOUND is returned).         */
   /* So, If not IGNORED and ridge start not encounted in trace ...     */
   if((ret != IGNORE) &&
      (ret != LOOP_FOUND)){

      /* Now conduct contour trace scanning for edge neighbors counter- */
      /* clockwise.                                                     */
      ret = trace_contour(&contour_x, &contour_y,
                          &contour_ex, &contour_ey, &ncontour,
                          max_ridge_steps,
                          xlist[ridge_start-1], ylist[ridge_start-1],
                          feat_x, feat_y, edge_x, edge_y,
                          SCAN_COUNTER_CLOCKWISE, bdata, iw, ih);
      /* If a system error occurred ... */
      if(ret < 0)
         /* Return error code. */
         return(ret);

      /* Otherwise, if the trace was not IGNORED, then a contour was */
      /* was generated and returned.  We aren't interested in the    */
      /* actual contour, so deallocate it.                           */
      if(ret != IGNORE)
         free_contour(contour_x, contour_y, contour_ex, contour_ey);

      /* If trace not IGNORED and ridge start not encounted in 2nd trace ... */
      if((ret != IGNORE) &&
         (ret != LOOP_FOUND)){
         /* If we get here, assume we have a ridge crossing. */
         return(TRUE);
      }
      /* Otherwise, second trace returned IGNORE or ridge start found. */
   }
   /* Otherwise, first trace returned IGNORE or ridge start found. */
   
   /* If we get here, then we failed to validate a ridge crossing. */
   return(FALSE);
}
Example #3
0
/*
 * Search the data base along a contour starts at the edge pe_start until
 * a boundary edge is detected or until we close the loop back to pe_start.
 * Returns a linked list of all the points on the contour
 * Also decreases num_active by the number of points on contour.
 */
static cntr_struct *
trace_contour(
    edge_struct *pe_start, /* edge to start contour input */
    double z_level,		/* Z level of contour input */
    int *num_active,		/* number of active edges in/out */
    TBOOLEAN contr_isclosed)	/* open or closed contour line (input) */
{
    cntr_struct *p_cntr, *pc_tail;
    edge_struct *p_edge, *p_next_edge;
    poly_struct *p_poly, *PLastpoly = NULL;
    int i;

    p_edge = pe_start;		/* first edge to start contour */

    /* Generate the header of the contour - the point on pe_start. */
    if (! contr_isclosed) {
	pe_start->is_active = FALSE;
	(*num_active)--;
    }
    if (p_edge->poly[0] || p_edge->poly[1]) {	/* more than one point */

	p_cntr = pc_tail = update_cntr_pt(pe_start, z_level);	/* first point */

	do {
	    /* Find polygon to continue (Not where we came from - PLastpoly): */
	    if (p_edge->poly[0] == PLastpoly)
		p_poly = p_edge->poly[1];
	    else
		p_poly = p_edge->poly[0];
	    p_next_edge = NULL;	/* In case of error, remains NULL. */
	    for (i = 0; i < 3; i++)	/* Test the 3 edges of the polygon: */
		if (p_poly->edge[i] != p_edge)
		    if (p_poly->edge[i]->is_active)
			p_next_edge = p_poly->edge[i];
	    if (!p_next_edge) {	/* Error exit */
		pc_tail->next = NULL;
		free_contour(p_cntr);
		fprintf(stderr, "trace_contour: unexpected end of contour\n");
		return NULL;
	    }
	    p_edge = p_next_edge;
	    PLastpoly = p_poly;
	    p_edge->is_active = FALSE;
	    (*num_active)--;

	    /* Do not allocate contour points on diagonal edges */
	    if (p_edge->position != DIAGONAL) {

		pc_tail->next = update_cntr_pt(p_edge, z_level);

		/* Remove nearby points */
		if (fuzzy_equal(pc_tail, pc_tail->next)) {

		    free(pc_tail->next);
		} else
		    pc_tail = pc_tail->next;
	    }
	} while ((p_edge != pe_start) && (p_edge->position != BOUNDARY));

	pc_tail->next = NULL;

	/* For closed contour the first and last point should be equal */
	if (pe_start == p_edge) {
	    (p_cntr->X) = (pc_tail->X);
	    (p_cntr->Y) = (pc_tail->Y);
	}
    } else {			/* only one point, forget it */
	p_cntr = NULL;
    }

    return p_cntr;
}