home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_4.6 / xph / xph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  7.8 KB  |  302 lines

  1. /* 
  2.  * xph.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * XP(oly_)H(ull) 
  11.  *
  12.  * constructs convex hull of polygonal shape
  13.  * 
  14.  */
  15.  
  16. #include "xph.h"
  17.  
  18. /* globals */
  19. int loop_switch = 1;            /* enable/disable loop over poly approx */
  20. int hull_switch = 1;            /* enable/disable evaluation of hull eval */
  21. int n_ap_max = NA_MAX;
  22. extern char *optarg;
  23. extern int optind, opterr;
  24.  
  25.  
  26. /*
  27.  * usage of routine
  28.  */
  29. void
  30. usage (char *progname)
  31. {
  32.   progname = last_bs (progname);
  33.   printf ("USAGE: %s outimg [-r filename] [-L]\n", progname);
  34.   printf ("\n%s constructs convex hull of polygonal shape\n\n", progname);
  35.   printf ("ARGUMENTS:\n");
  36.   printf ("       outimg: output image filename (TIF)\n\n");
  37.   printf ("OPTIONS:\n");
  38.   printf ("  -r filename: input data file containing delta_phik and delta_lk,\n");
  39.   printf ("               generated by xcp.\n");
  40.   printf ("               if filename not specified, will use internal data for test\n");
  41.   printf ("           -L: print Software License for this module\n");
  42.  
  43.   exit (1);
  44. }
  45.  
  46. #define BUFSZ 1024
  47.  
  48. int
  49. readDeltas (char *filename, float **d_phi, float **d_l)
  50. {
  51.   FILE *stream;
  52.   int n_lines;
  53.   int i = 0, line_no = 0;
  54.   char *sptr, inBuf[BUFSZ], buf[256], *strptr;
  55.   float phi, l;
  56.  
  57.   strcpy (buf, filename);
  58.   if (((strptr = strstr (buf, FILE_EXT)) && (strptr != (buf + strlen (buf) - strlen (FILE_EXT)))) || !strptr)
  59.     strcat (buf, FILE_EXT);
  60.   if ((stream = fopen (buf, "r")) != NULL) {
  61.     /* get # points to read */
  62.     for (;;) {
  63.       if (fgets (inBuf, BUFSZ, stream) == (char *) NULL) {
  64.         printf ("Premature EOF encountered while reading filter file %s\n", filename);
  65.         exit (1);
  66.       }
  67.       line_no++;
  68.       /*
  69.        * Throw away comments
  70.        */
  71.       if (inBuf[0] == '#')
  72.         continue;
  73.       else {
  74.         if (sscanf (inBuf, "%d\n", &n_lines) != 1) {
  75.           printf ("error reading n_lines\n");
  76.           exit (1);
  77.         }
  78.         if ((*d_phi = (float *) calloc (n_lines, sizeof (float))) == NULL) {
  79.           printf ("\n...mem allocation for d_phi failed\n");
  80.           exit (1);
  81.         }
  82.         if ((*d_l = (float *) calloc (n_lines, sizeof (float))) == NULL) {
  83.           printf ("\n...mem allocation for d_l failed\n");
  84.           exit (1);
  85.         }
  86.         break;
  87.       }
  88.     }
  89.     /* Now read the values in */
  90.     while (i < n_lines) {
  91.       if (fgets (inBuf, BUFSZ, stream) == (char *) NULL) {
  92.         printf ("Premature EOF encountered while reading filter file %s\n", filename);
  93.         exit (1);
  94.       }
  95.       line_no++;
  96.       /*
  97.        * Throw away comments
  98.        */
  99.       if (inBuf[0] == '#')
  100.         continue;
  101.       sptr = inBuf;
  102.       if (sscanf (sptr, "%f %f\n", &phi, &l) != 2) {
  103.         printf ("Can't read delta_phi, delta_l values on line %d of file %s\n", line_no, filename);
  104.         exit (1);
  105.       }
  106.       *(*d_phi + i) = (float) phi;
  107.       *(*d_l + i) = (float) l;
  108.       i++;
  109.  
  110.     }
  111.     fclose (stream);
  112.     return (1);
  113.   }
  114.   else {
  115.     printf ("Can not open input file: %s\n", filename);
  116.     exit (1);
  117.   }
  118. }
  119.  
  120. int
  121. main (int argc, char *argv[])
  122. {
  123.  
  124. /* example: character 4, encoded following Zahn */
  125. #if defined(WIN32)
  126. #pragma warning( disable : 4244 )
  127. #endif
  128.   static float delta_phik[N_VERTEX] =
  129.   {-1, -1, -1, 1, -1, 1, 1, 1,
  130.    -1, -2, -1, 1, 1, -1, 1, -1,
  131.    1, -1, -1, -1, -1, -1, 1, -1,
  132.    1, 1, 1, -1, -1, -1, -1, 1,
  133.    -1, -1, -1, -1, 2, 1, 1, 1,
  134.    -1, 1, -1, 1, -1, -1};
  135.   static float delta_lk[N_VERTEX] =
  136.   {20, 10 * SQ2, 40, 40 * SQ2, 40,
  137.    20 * SQ2, 40, 10 * SQ2, 40, 10 * SQ2,
  138.    30 * SQ2, 40, 30 * SQ2, 20, 20 * SQ2,
  139.    40, 20 * SQ2, 20, 10 * SQ2, 40,
  140.    30 * SQ2, 20, 20 * SQ2, 20, 20 * SQ2,
  141.    20, 10 * SQ2, 120, 10 * SQ2, 20,
  142.    90 * SQ2, 20, 20 * SQ2, 20, 10 * SQ2,
  143.    20, 40 * SQ2, 10 * SQ2, 40, 30 * SQ2,
  144.    40, 20 * SQ2, 20, 20 * SQ2, 20,
  145.    50 * SQ2};
  146. #if defined(WIN32)
  147. #pragma warning( default : 4244 )
  148. #endif
  149.  
  150.   double tot_phi, tol, av_dirn;
  151.  
  152.   int i_arg;
  153.   int i;
  154.   int edge_outk;
  155.   long nv;
  156.   int hull_area;
  157.   float *d_phi, *d_l;
  158.  
  159.   float *moments;
  160.   struct Bdy bd, *bdp = &bd;
  161.   struct spoint *hullctr;
  162.   struct spoint cursor, *pc = &cursor;
  163.   struct spoint *v, *v_ap;
  164.   struct spoint *pvc;
  165.  
  166.   unsigned int pixel_count;
  167.  
  168.   Image *ip;
  169.  
  170. /* 
  171.  * cmd line options:
  172.  */
  173.   static char *optstring = "r:L";
  174.  
  175.   d_phi = delta_phik;
  176.   d_l = delta_lk;
  177. /*
  178.  * parse command line
  179.  */
  180.   optind = 2;
  181.   opterr = ON;                  /* give error messages */
  182.  
  183.  
  184.   if (argc < 2)
  185.     usage (argv[0]);
  186.  
  187.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  188.     switch (i_arg) {
  189.     case 'r':
  190.       readDeltas (optarg, &d_phi, &d_l);
  191.       break;
  192.     case 'L':
  193.       print_sos_lic ();
  194.       exit (0);
  195.     default:
  196.       break;
  197.     }
  198.   }
  199. /*
  200.  * initialize graphics
  201.  */
  202.   ip = ImageAlloc ((long) WIDTH, (long) HEIGHT, BPS);
  203.  
  204. /*
  205.  * initialize parameters required by reconstruct_poly()
  206.  */
  207.   tot_phi = -8.0;
  208.   edge_outk = 0;
  209.   pc->x = X_ORG;
  210.   pc->y = Y_ORG;
  211.  
  212. /* 
  213.  * reconstruct polygon
  214.  * NOTE:
  215.  *   nv represents the number of (distinct) curv pts, but the arrays
  216.  *   xv and yv contain n_vert+1 pts (first vertex = last vertex)
  217.  */
  218.   nv = (long) N_VERTEX;
  219.   if ((v = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
  220.       exitmess ("\n...mem allocation for v failed\n", 1);
  221.  
  222.   if ((v_ap = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
  223.       exitmess ("\n...mem allocation for v_ap failed\n", 1);
  224.  
  225.  
  226.  
  227.   pixel_count = reconstruct_poly (d_phi, d_l, nv,
  228.                                   v, pc, edge_outk, tot_phi, ip, WHITE);
  229.  
  230.   printf ("\n...polygon area (pixel count): %u\n", pixel_count);
  231.  
  232.   printf ("\n...writing output file %s\n", argv[1]);
  233.   tol = 0.0;                    /* tolerance for polygon fitting */
  234.   av_dirn = 0.0;
  235.   printf ("\n...calling poly_hull:\n");
  236.   printf ("      ptr to Bdy: %p\n", bdp);
  237.   printf ("  ptr to Bdy->vn: %p\n", &(bdp->vn));
  238.  
  239.   /* in poly_hull.c */
  240.   fill_bdy_structure (bdp, v, nv, tot_phi);
  241.   hullctr = poly_hull (bdp, v_ap, av_dirn, &hull_area, ip, GRAY);
  242.   printf ("\tlocation of convex hull center:");
  243.   printf (" (%3d,%3d)\n", hullctr->x, hullctr->y);
  244.  
  245.   if ((int) bdp->an < (int) bdp->vn)
  246.     v_ap = (struct spoint *) realloc (v_ap, ((bdp->an) + 1) * sizeof (struct spoint));
  247.  
  248. #ifdef DEBUG
  249.   printf ("\n...XPOLY_HULL:\n");
  250.   printf ("     sizeof(Bdy): %d\n", sizeof (struct Bdy));
  251.   printf ("      ptr to Bdy: %p\n", bdp);
  252.   printf ("   ptr to Bdy->v: %p\n", bdp->v);
  253.   printf ("  ptr to Bdy->ap: %p\n", bdp->ap);
  254.   printf (" ptr to Bdy->hpp: %p\n", bdp->hpp);
  255.   printf ("  bdp->vn = %ld, bdp->an = %ld, bdp->hn = %d\n",
  256.           bdp->vn, bdp->an, bdp->hn);
  257.   for (i = 0; i <= (int) bdp->vn; i++) {
  258.     printf ("\n  (bdp->v)->x = %d", (bdp->v + i)->x);
  259.     printf ("  (bdp->v)->y = %d", (bdp->v + i)->y);
  260.   }
  261.  
  262.   printf ("\n...polygon approximation found %d vertices:\n", bdp->an);
  263.   for (i = 0; i <= (int) bdp->an; i++) {
  264.     printf ("\n  v_ap->x = %d", (v_ap + i)->x);
  265.     printf ("  v_ap->y = %d", (v_ap + i)->y);
  266.   }
  267. #endif
  268.  
  269. /*
  270.  * compute low-order moments
  271.  */
  272.   if (EVAL_MOM == ON) {
  273.     if ((moments = (float *) calloc (N_MOM, sizeof (float))) == NULL)
  274.         exitmess ("\n...mem alloc for moments failed\n", 1);
  275.  
  276.     pvc = poly_moments (bdp->an, v_ap, moments, ip, GRAY);
  277.  
  278.     printf ("\n...centroid pos: (%3d, %3d)\n", pvc->x, pvc->y);
  279.     printf ("...area: %f\n", *(moments + 1));
  280.   }
  281.  
  282. /*
  283.  * deallocate memory
  284.  */
  285.   printf ("\n...free memory allocated within struct Bdy\n");
  286.   printf (" free Bdy->hpp: %p\n", bdp->hpp);
  287.   free (bdp->hpp);              /* allocated in poly_approx.c */
  288.   printf ("  free Bdy->ap: %p\n", bdp->ap);
  289.   free (bdp->ap);               /* allocated in poly_approx.c */
  290.   printf ("   free Bdy->v: %p\n", bdp->v);
  291.   free (bdp->v);                /* allocated in poly_edge.c */
  292.  
  293.   printf ("\n...free allocated memory\n");
  294.   free (v);
  295.   free (v_ap);
  296.   if (EVAL_MOM == ON)
  297.     free (moments);
  298.   printf ("\n...writing output file %s\n", argv[1]);
  299.   ImageOut (argv[1], ip);
  300.   return (0);
  301. }
  302.