/* * Does pass 2, or find one complete contour out of the triangulation * data base: * * Returns a pointer to the contour (as linked list), contr_isclosed * tells if the contour is a closed line or not, and num_active is * updated. */ static cntr_struct * gen_one_contour( edge_struct *p_edges, /* list of edges input */ double z_level, /* Z level of contour input */ TBOOLEAN *contr_isclosed, /* open or closed contour, in/out */ int *num_active) /* number of active edges in/out */ { edge_struct *pe_temp; if (! *contr_isclosed) { /* Look for something to start with on boundary: */ pe_temp = p_edges; while (pe_temp) { if (pe_temp->is_active && (pe_temp->position == BOUNDARY)) break; pe_temp = pe_temp->next; } if (!pe_temp) *contr_isclosed = TRUE; /* No more contours on boundary. */ else { return trace_contour(pe_temp, z_level, num_active, *contr_isclosed); } } if (*contr_isclosed) { /* Look for something to start with inside: */ pe_temp = p_edges; while (pe_temp) { if (pe_temp->is_active && (pe_temp->position != BOUNDARY)) break; pe_temp = pe_temp->next; } if (!pe_temp) { *num_active = 0; fprintf(stderr, "gen_one_contour: no contour found\n"); return NULL; } else { *contr_isclosed = TRUE; return trace_contour(pe_temp, z_level, num_active, *contr_isclosed); } } return NULL; /* We should never be here, but lint... */ }
/************************************************************************* ************************************************************************** #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); }