/************************************************************************* ************************************************************************** #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); }
/************************************************************************* ************************************************************************** #cat: search_in_direction - Takes a specified maximum number of steps in a #cat: specified direction looking for the first occurence of #cat: a pixel with specified value. (Once found, adjustments #cat: are potentially made to make sure the resulting pixel #cat: and its associated edge pixel are 4-connected.) Input: pix - value of pixel to be searched for strt_x - x-pixel coord to start search strt_y - y-pixel coord to start search delta_x - increment in x for each step delta_y - increment in y for each step maxsteps - maximum number of steps to conduct search bdata - binary image data (0==while & 1==black) iw - width (in pixels) of image ih - height (in pixels) of image Output: ox - x coord of located pixel oy - y coord of located pixel oex - x coord of associated edge pixel oey - y coord of associated edge pixel Return Code: TRUE - pixel of specified value found FALSE - pixel of specified value NOT found **************************************************************************/ int search_in_direction(int *ox, int *oy, int *oex, int *oey, const int pix, const int strt_x, const int strt_y, const double delta_x, const double delta_y, const int maxsteps, unsigned char *bdata, const int iw, const int ih) { int i, x, y, px, py; double fx, fy; /* Set previous point to starting point. */ px = strt_x; py = strt_y; /* Set floating point accumulators to starting point. */ fx = (double)strt_x; fy = (double)strt_y; /* Foreach step up to the specified maximum ... */ for(i = 0; i < maxsteps; i++){ /* Increment accumulators. */ fx += delta_x; fy += delta_y; /* Round to get next step. */ x = sround(fx); y = sround(fy); /* If we stepped outside the image boundaries ... */ if((x < 0) || (x >= iw) || (y < 0) || (y >= ih)){ /* Return FALSE (we did not find what we were looking for). */ *ox = -1; *oy = -1; *oex = -1; *oey = -1; return(FALSE); } /* Otherwise, test to see if we found our pixel with value 'pix'. */ if(*(bdata+(y*iw)+x) == pix){ /* The previous and current pixels form a feature, edge pixel */ /* pair, which we would like to use for edge following. The */ /* previous pixel may be a diagonal neighbor however to the */ /* current pixel, in which case the pair could not be used by */ /* the contour tracing (which requires the edge pixel in the */ /* pair neighbor to the N,S,E or W. */ /* This routine adjusts the pair so that the results may be */ /* used by the contour tracing. */ fix_edge_pixel_pair(&x, &y, &px, &py, bdata, iw, ih); /* Return TRUE (we found what we were looking for). */ *ox = x; *oy = y; *oex = px; *oey = py; return(TRUE); } /* Otherwise, still haven't found pixel with desired value, */ /* so set current point to previous and take another step. */ px = x; py = y; } /* Return FALSE (we did not find what we were looking for). */ *ox = -1; *oy = -1; *oex = -1; *oey = -1; return(FALSE); }