home *** CD-ROM | disk | FTP | other *** search
- /*
- * xph.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * XP(oly_)H(ull)
- *
- * constructs convex hull of polygonal shape
- *
- */
-
- #include "xph.h"
-
- /* globals */
- int loop_switch = 1; /* enable/disable loop over poly approx */
- int hull_switch = 1; /* enable/disable evaluation of hull eval */
- int n_ap_max = NA_MAX;
- extern char *optarg;
- extern int optind, opterr;
-
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s outimg [-r filename] [-L]\n", progname);
- printf ("\n%s constructs convex hull of polygonal shape\n\n", progname);
- printf ("ARGUMENTS:\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -r filename: input data file containing delta_phik and delta_lk,\n");
- printf (" generated by xcp.\n");
- printf (" if filename not specified, will use internal data for test\n");
- printf (" -L: print Software License for this module\n");
-
- exit (1);
- }
-
- #define BUFSZ 1024
-
- int
- readDeltas (char *filename, float **d_phi, float **d_l)
- {
- FILE *stream;
- int n_lines;
- int i = 0, line_no = 0;
- char *sptr, inBuf[BUFSZ], buf[256], *strptr;
- float phi, l;
-
- strcpy (buf, filename);
- if (((strptr = strstr (buf, FILE_EXT)) && (strptr != (buf + strlen (buf) - strlen (FILE_EXT)))) || !strptr)
- strcat (buf, FILE_EXT);
- if ((stream = fopen (buf, "r")) != NULL) {
- /* get # points to read */
- for (;;) {
- if (fgets (inBuf, BUFSZ, stream) == (char *) NULL) {
- printf ("Premature EOF encountered while reading filter file %s\n", filename);
- exit (1);
- }
- line_no++;
- /*
- * Throw away comments
- */
- if (inBuf[0] == '#')
- continue;
- else {
- if (sscanf (inBuf, "%d\n", &n_lines) != 1) {
- printf ("error reading n_lines\n");
- exit (1);
- }
- if ((*d_phi = (float *) calloc (n_lines, sizeof (float))) == NULL) {
- printf ("\n...mem allocation for d_phi failed\n");
- exit (1);
- }
- if ((*d_l = (float *) calloc (n_lines, sizeof (float))) == NULL) {
- printf ("\n...mem allocation for d_l failed\n");
- exit (1);
- }
- break;
- }
- }
- /* Now read the values in */
- while (i < n_lines) {
- if (fgets (inBuf, BUFSZ, stream) == (char *) NULL) {
- printf ("Premature EOF encountered while reading filter file %s\n", filename);
- exit (1);
- }
- line_no++;
- /*
- * Throw away comments
- */
- if (inBuf[0] == '#')
- continue;
- sptr = inBuf;
- if (sscanf (sptr, "%f %f\n", &phi, &l) != 2) {
- printf ("Can't read delta_phi, delta_l values on line %d of file %s\n", line_no, filename);
- exit (1);
- }
- *(*d_phi + i) = (float) phi;
- *(*d_l + i) = (float) l;
- i++;
-
- }
- fclose (stream);
- return (1);
- }
- else {
- printf ("Can not open input file: %s\n", filename);
- exit (1);
- }
- }
-
- int
- main (int argc, char *argv[])
- {
-
- /* example: character 4, encoded following Zahn */
- #if defined(WIN32)
- #pragma warning( disable : 4244 )
- #endif
- static float delta_phik[N_VERTEX] =
- {-1, -1, -1, 1, -1, 1, 1, 1,
- -1, -2, -1, 1, 1, -1, 1, -1,
- 1, -1, -1, -1, -1, -1, 1, -1,
- 1, 1, 1, -1, -1, -1, -1, 1,
- -1, -1, -1, -1, 2, 1, 1, 1,
- -1, 1, -1, 1, -1, -1};
- static float delta_lk[N_VERTEX] =
- {20, 10 * SQ2, 40, 40 * SQ2, 40,
- 20 * SQ2, 40, 10 * SQ2, 40, 10 * SQ2,
- 30 * SQ2, 40, 30 * SQ2, 20, 20 * SQ2,
- 40, 20 * SQ2, 20, 10 * SQ2, 40,
- 30 * SQ2, 20, 20 * SQ2, 20, 20 * SQ2,
- 20, 10 * SQ2, 120, 10 * SQ2, 20,
- 90 * SQ2, 20, 20 * SQ2, 20, 10 * SQ2,
- 20, 40 * SQ2, 10 * SQ2, 40, 30 * SQ2,
- 40, 20 * SQ2, 20, 20 * SQ2, 20,
- 50 * SQ2};
- #if defined(WIN32)
- #pragma warning( default : 4244 )
- #endif
-
- double tot_phi, tol, av_dirn;
-
- int i_arg;
- int i;
- int edge_outk;
- long nv;
- int hull_area;
- float *d_phi, *d_l;
-
- float *moments;
- struct Bdy bd, *bdp = &bd;
- struct spoint *hullctr;
- struct spoint cursor, *pc = &cursor;
- struct spoint *v, *v_ap;
- struct spoint *pvc;
-
- unsigned int pixel_count;
-
- Image *ip;
-
- /*
- * cmd line options:
- */
- static char *optstring = "r:L";
-
- d_phi = delta_phik;
- d_l = delta_lk;
- /*
- * parse command line
- */
- optind = 2;
- opterr = ON; /* give error messages */
-
-
- if (argc < 2)
- usage (argv[0]);
-
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- switch (i_arg) {
- case 'r':
- readDeltas (optarg, &d_phi, &d_l);
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- break;
- }
- }
- /*
- * initialize graphics
- */
- ip = ImageAlloc ((long) WIDTH, (long) HEIGHT, BPS);
-
- /*
- * initialize parameters required by reconstruct_poly()
- */
- tot_phi = -8.0;
- edge_outk = 0;
- pc->x = X_ORG;
- pc->y = Y_ORG;
-
- /*
- * reconstruct polygon
- * NOTE:
- * nv represents the number of (distinct) curv pts, but the arrays
- * xv and yv contain n_vert+1 pts (first vertex = last vertex)
- */
- nv = (long) N_VERTEX;
- if ((v = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
- exitmess ("\n...mem allocation for v failed\n", 1);
-
- if ((v_ap = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
- exitmess ("\n...mem allocation for v_ap failed\n", 1);
-
-
-
- pixel_count = reconstruct_poly (d_phi, d_l, nv,
- v, pc, edge_outk, tot_phi, ip, WHITE);
-
- printf ("\n...polygon area (pixel count): %u\n", pixel_count);
-
- printf ("\n...writing output file %s\n", argv[1]);
- tol = 0.0; /* tolerance for polygon fitting */
- av_dirn = 0.0;
- printf ("\n...calling poly_hull:\n");
- printf (" ptr to Bdy: %p\n", bdp);
- printf (" ptr to Bdy->vn: %p\n", &(bdp->vn));
-
- /* in poly_hull.c */
- fill_bdy_structure (bdp, v, nv, tot_phi);
- hullctr = poly_hull (bdp, v_ap, av_dirn, &hull_area, ip, GRAY);
- printf ("\tlocation of convex hull center:");
- printf (" (%3d,%3d)\n", hullctr->x, hullctr->y);
-
- if ((int) bdp->an < (int) bdp->vn)
- v_ap = (struct spoint *) realloc (v_ap, ((bdp->an) + 1) * sizeof (struct spoint));
-
- #ifdef DEBUG
- printf ("\n...XPOLY_HULL:\n");
- printf (" sizeof(Bdy): %d\n", sizeof (struct Bdy));
- printf (" ptr to Bdy: %p\n", bdp);
- printf (" ptr to Bdy->v: %p\n", bdp->v);
- printf (" ptr to Bdy->ap: %p\n", bdp->ap);
- printf (" ptr to Bdy->hpp: %p\n", bdp->hpp);
- printf (" bdp->vn = %ld, bdp->an = %ld, bdp->hn = %d\n",
- bdp->vn, bdp->an, bdp->hn);
- for (i = 0; i <= (int) bdp->vn; i++) {
- printf ("\n (bdp->v)->x = %d", (bdp->v + i)->x);
- printf (" (bdp->v)->y = %d", (bdp->v + i)->y);
- }
-
- printf ("\n...polygon approximation found %d vertices:\n", bdp->an);
- for (i = 0; i <= (int) bdp->an; i++) {
- printf ("\n v_ap->x = %d", (v_ap + i)->x);
- printf (" v_ap->y = %d", (v_ap + i)->y);
- }
- #endif
-
- /*
- * compute low-order moments
- */
- if (EVAL_MOM == ON) {
- if ((moments = (float *) calloc (N_MOM, sizeof (float))) == NULL)
- exitmess ("\n...mem alloc for moments failed\n", 1);
-
- pvc = poly_moments (bdp->an, v_ap, moments, ip, GRAY);
-
- printf ("\n...centroid pos: (%3d, %3d)\n", pvc->x, pvc->y);
- printf ("...area: %f\n", *(moments + 1));
- }
-
- /*
- * deallocate memory
- */
- printf ("\n...free memory allocated within struct Bdy\n");
- printf (" free Bdy->hpp: %p\n", bdp->hpp);
- free (bdp->hpp); /* allocated in poly_approx.c */
- printf (" free Bdy->ap: %p\n", bdp->ap);
- free (bdp->ap); /* allocated in poly_approx.c */
- printf (" free Bdy->v: %p\n", bdp->v);
- free (bdp->v); /* allocated in poly_edge.c */
-
- printf ("\n...free allocated memory\n");
- free (v);
- free (v_ap);
- if (EVAL_MOM == ON)
- free (moments);
- printf ("\n...writing output file %s\n", argv[1]);
- ImageOut (argv[1], ip);
- return (0);
- }
-