home *** CD-ROM | disk | FTP | other *** search
- /*
- * sall.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * SALL
- *
- * construct segm adj list;
- * version employing memory saving segment structure; see also: lsall.c
- *
- * ms, 11/90;
- */
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
-
- #include "lldef.h"
- #include "xsgll.h"
-
-
- #define OFF 0
- #define ORDER_DIJ -1 /* construct dij-ordered lists */
- #define ORDER_PJI 1 /* construct pji-ordered lists */
- #define ORDER ORDER_PJI
-
- #define MIN_SAL_SIZE 3
-
- #undef DEBUG
- #undef SHOW_SEG
- #undef SHOW_PARMS
-
- /*
- * compare list entries (segments):
- * key: inverse overlap parameter, pji
- *
- */
- int
- cmpSegmpji (oldSegm, newSegm)
- struct Segmtype *oldSegm, *newSegm;
- {
-
- return (SIGN (oldSegm->pji - newSegm->pji));
- }
-
-
- /*
- * scan list, comparing inverse overlap pji of newSegm <j> with that
- * of those segments already in current segm adj list (SAL);
- * a list is desired in which all segments following the reference
- * segment (stored at the top) are entered in the order of decreasing pji;
- * employs matching function, here cmpSegmpji
- * (see also: llsearch() in llist.c )
- */
- Boolean
- cmppji (newSegm, sall)
- struct Segmtype *newSegm;
- struct linklist *sall;
- {
- Boolean MatchStatus = False;
-
- /* scan bwd from tail until newpji > existpji */
- lltail (sall);
- do {
- if (((*sall->match) (sall->clp->item, newSegm)) > 0)
- MatchStatus = True;
-
- } while ((MatchStatus != True) && (llprevious (sall) == True));
-
-
- return (MatchStatus);
- }
-
-
-
- /*
- * display segment
- */
- void
- show_segment (index, segm, rSegm)
- int index;
- struct Segm *segm;
- struct Segmtype *rSegm;
- {
-
- printf ("\n...segment <%d>, as initialized:\n", index);
-
- printf (" ptO.x = %d, ptO.y = %d\n",
- segm->ptO.x, segm->ptO.y);
- printf (" ptF.x = %d, ptF.y = %d\n",
- segm->ptF.x, segm->ptF.y);
- printf (" slope = %f\n", segm->slope);
- printf (" line_ind = %d\n", segm->line_ind);
-
- printf (" dij = %f, pij = %f, pji = %f\n",
- rSegm->dij, rSegm->pij, rSegm->pji);
- printf (" segm_ind = %d\n", rSegm->segm_ind);
- printf (" sgl_level = %d\n", rSegm->sgl_level);
- printf (" SalStatus = %d\n", rSegm->SalStat);
-
- }
-
-
- /*
- * initialize new segment entry (link) in list
- * note:
- * the index of a segment read from the input data file is not necessarily
- * identical to the array index associated with this segment; the segment
- * index entered into the list is currently just the array index; this
- * facilitates subsequent access of segment data (e.g. coordinates), but
- * can introduce an index offset between the two segment structures;
- */
- struct Segmtype *
- init_node (list, index, Segm)
- struct linklist *list;
- int index;
- struct Segmtype *Segm;
- {
- struct Segmtype *Segmptr;
-
-
- Segm->segm_ind = index;
- Segm->dij = (float) 0.0;
- Segm->pij = (float) 999.0; /* self overlap */
- Segm->pji = (float) 999.0; /* self overlap */
- Segm->sgl_level = 0;
- Segm->SalStat = Active;
-
- return (Segmptr = Segm);
- }
-
-
-
- /*
- * construct segment adjacency list
- * to obtain an ordered list, the present version employs insertion sorting
- */
- int
- construct_sall (sall, segm, n_segm, angl_thresh, ovlp_thresh, d_max)
- struct linklist sall[];
- struct Segm *segm;
- int n_segm;
- double angl_thresh;
- double ovlp_thresh;
- double d_max;
- {
-
- struct linklist *clist; /* ptr to current list */
- struct Segmtype refSegm, *rSegm = &refSegm; /* lin. segm. list entry */
- struct Segmtype curSegm, *cSegm = &curSegm; /* lin. segm. list entry */
- struct spoint ptO1, ptF1, ptO2, ptF2; /*segm orig. and fin points */
- int n_sall;
-
- double dij, dji, pij, pji;
- float slpi, slpj, slp_thresh;
- int i, j;
- int order_sal = ORDER; /* when set, order SAL with */
- /* respect to dij or pji */
-
-
- slp_thresh = (float) tan (angl_thresh * (PI / 180.0));
-
-
- /*
- * consider every pair ( i!=j ) of segments
- */
- printf ("\n...constructing segment adj lists:\n");
- printf ("...processing segment:\n");
- n_sall = 0;
- for (i = 0; i < n_segm; i++) {
- printf (" %3d ", i);
- if ((i + 1) % 12 == 0)
- printf ("\n");
-
- /* initialize new SAL<i> with the reference segment <i> */
- clist = &sall[i];
-
- /* rSegm = init_node(clist, (inSegm+i)->segm_ind, &refSegm); */
- rSegm = init_node (clist, i, &refSegm);
- lltail (clist);
- lladd ((char *) rSegm, clist);
-
-
- ptO1.x = (segm + i)->ptO.x;
- ptO1.y = (segm + i)->ptO.y;
- ptF1.x = (segm + i)->ptF.x;
- ptF1.y = (segm + i)->ptF.y;
- slpi = (segm + i)->slope;
-
- #ifdef SHOW_SEG
- show_segment (i, segm + i, rSegm);
- #endif
-
- for (j = 0; j < n_segm; j++) {
- if (j != i) {
- slpj = (segm + j)->slope;
- /*if (slpi * slpj == -1.0) {
- * printf ("\n...segments m%d, m%d perpendicular:", i, j);
- * printf (" pair skipped\n");
- * }
- * else */ if (fabs ((slpi - slpj) / (1.0 + slpi * slpj)) < slp_thresh) {
-
- ptO2.x = (segm + j)->ptO.x;
- ptO2.y = (segm + j)->ptO.y;
- ptF2.x = (segm + j)->ptF.x;
- ptF2.y = (segm + j)->ptF.y;
-
- prlpar (ptO1, ptF1, ptO2, ptF2, &dij, &dji, &pij, &pji);
-
- #ifdef SHOW_PARMS
- printf ("\n...returned from prlpar():\n");
- printf (" overlap(%d,%d)=%.2lf\n", i, j, pij);
- printf (" overlap(%d,%d)=%.2lf\n", j, i, pji);
- printf (" perp.dist(%d,%d)=%.2lf\n", i, j, dij);
- #endif
-
- switch (SIGN (dij)) {
- case -1:
- if (fabs (dij) < d_max) {
- if (pij > (double) ovlp_thresh) {
-
- cSegm = init_node (clist, j, &curSegm);
- cSegm->segm_ind = j;
- cSegm->dij = (float) dij;
- cSegm->pij = (float) pij;
- cSegm->pji = (float) pji;
-
- if (order_sal == ORDER_PJI) {
- llsetmatch (cmpSegmpji, clist);
- while (cmppji (cSegm, clist) != True);
- lladd ((char *) cSegm, clist);
- }
- else {
- llhead (clist);
- if (order_sal == ORDER_DIJ) {
- llsetmatch (cmpSegmdist, clist);
- while (cmpdij (cSegm, SIGN (dij), clist) != True);
- }
- lladdprev ((char *) cSegm, clist);
- }
- }
- }
- break;
- case 1:
- if (dij < d_max) {
- if (pij > (double) ovlp_thresh) {
- cSegm = init_node (clist, j, &curSegm);
- cSegm->segm_ind = j;
- cSegm->dij = (float) dij;
- cSegm->pij = (float) pij;
- cSegm->pji = (float) pji;
-
- if (order_sal == ORDER_PJI) {
- llsetmatch (cmpSegmpji, clist);
- while (cmppji (cSegm, clist) != True);
- lladd ((char *) cSegm, clist);
- }
- else {
- lltail (clist);
- if (order_sal == ORDER_DIJ) {
- llsetmatch (cmpSegmdist, clist);
- while (cmpdij (cSegm, SIGN (dij), clist) != True);
- }
- lladd ((char *) cSegm, clist);
- }
- }
- }
- break;
- case 0:
- #ifdef DEBUG
- printf ("\n...overlap p(%d,%d) = %.2lf ignored\n",
- i, j, pij);
- #endif
- break;
- default:
- printf ("\n...unknown SIGN(dij)!\n");
- break;
- }
- }
- }
- }
-
- if (clist->listlength >= MIN_SAL_SIZE)
- n_sall++;
- #ifdef DEBUG
- show_segm_list (clist, i);
- #endif
- }
-
- return (n_sall);
- }
-