home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_5.5 / FITLINE / FITLINE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  5.9 KB  |  209 lines

  1. /*
  2.  * fitline.c
  3.  *
  4.  * Practical Algorithms for Image Analysis
  5.  *
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* FITLINE:     program fits lines to data
  10.  *                    usage: fitline infile outimg [-c] [-L]
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <images.h>
  17. #include <tiffimage.h>
  18. #include "pcc2.h"               /* for PCC programs */
  19. extern void print_sos_lic ();
  20.  
  21. unsigned char *fcCode;          /* code storage */
  22. long nByteCode;                 /* no. bytes in code storage */
  23.  
  24. long xytoline (struct point *, long *, long *, long *);
  25. extern short eigenline (struct point *, long, double *, double *);
  26. int mbtoendpts (struct point, struct point, double, double,
  27.                 long, long, struct point *, struct point *);
  28. long usage (short);
  29. long input (int, char **, short *);
  30.  
  31. main (argc, argv)
  32.      int argc;
  33.      char *argv[];
  34. {
  35.   Image *imgO;                  /* pointer to output image structure */
  36.   unsigned char **image;        /* output image array */
  37.   long width, height;           /* image size */
  38.   struct point imgSize;         /* image size */
  39.   short coordFlag;              /* flag = 1, print fit coord.s; or 0 */
  40.   struct point *data;           /* data curve */
  41.   long nData;                   /* no. coords in data curve */
  42.   long nSegments;               /* number of segments found */
  43.   long nStructs;                /* number of line structures found */
  44.   long drawline8 ();            /* joins points in 8-connected lines */
  45.   struct edge edge;             /* lower/upper indices of segment in data */
  46.   short inLine;                 /* flag = 1 if inside line, 0 otherwise */
  47.   long nFits;                   /* number of line fits */
  48.   double m, b;                  /* slope and y-intercept of line fit */
  49.   short eigenline (), fitFlag;  /* eigenline returns flag=1 if fit made */
  50.   struct point pt1, pt2;        /* endpoints of line fit */
  51.   long iPt;                     /* index on data for line fits */
  52.   long x, y;
  53.   long i;
  54.  
  55. /* user input */
  56.   if (input (argc, argv, &coordFlag) < 0)
  57.     return (-1);
  58.  
  59. /* open input PCC file */
  60.   if (pccread (argv[1], &fcCode, &nByteCode, &width, &height) == -1)
  61.     exit (1);
  62.   if (coordFlag == 0)
  63.     printf ("image size: %dx%d, PCC length = %d\n", width, height, nByteCode);
  64.   imgSize.x = width;
  65.   imgSize.y = height;
  66.  
  67. /* allocate output image */
  68.   imgO = ImageAlloc (height, width, 8);
  69.   image = ImageGetPtr (imgO);
  70.  
  71. /* initialize image */
  72.   for (y = 0; y < height; y++)
  73.     for (x = 0; x < width; x++)
  74.       image[y][x] = 255;
  75.  
  76. /* allocate space for data coordinate array */
  77.   if ((data = (struct point *)
  78.        calloc (nByteCode * MAXPERCODE, sizeof (long))) == NULL) {
  79.     printf ("FITPOLYG: not enough memory -- sorry");
  80.     return (-1);
  81.   }
  82.  
  83. /* construct tables of feature chain decodes */
  84.   pccdecodes ();
  85.  
  86. /* perform feature chain decoding */
  87.   pcc2xy (data, &nData);
  88.  
  89.   data[nData++].x = -STOPCODE;
  90.   if ((data = (struct point *)
  91.        realloc (data, nData * sizeof (struct point))) == NULL) {
  92.     printf ("FITPOLYG: not enough memory -- sorry");
  93.     return (-2);
  94.   }
  95.  
  96. /* find x,y coordinates for each segment */
  97.   if (xytoline (data, &nData, &nSegments, &nStructs) < 0)
  98.     return (-1);
  99.  
  100. /* fit line to each segment */
  101.   for (i = 0, iPt = 0, inLine = 0, nFits = 0; i < nData; i++) {
  102.     if (data[i].x < 0) {
  103.       if (inLine == 0) {
  104.         edge.iLow = i + 1;
  105.         inLine = 1;
  106.       }
  107.       else {
  108.         --i;
  109.         edge.iHigh = i;
  110.         --iPt;
  111.         fitFlag = eigenline (data, iPt + 1, &m, &b);
  112.         nFits++;
  113.         if (fitFlag) {
  114.           mbtoendpts (data[0], data[iPt], m, b, width, height, &pt1, &pt2);
  115.           if (coordFlag)
  116.             printf ("%d: (%d,%d) (%d,%d)\n",
  117.                     nFits, pt1.x, pt1.y, pt2.x, pt2.y);
  118.           drawline8 (image, imgSize, pt1, pt2, 0);
  119.         }
  120.         iPt = 0;
  121.         inLine = 0;
  122.       }
  123.     }
  124.     else {
  125.       data[iPt].x = data[i].x;
  126.       data[iPt++].y = data[i].y;
  127.     }
  128.   }
  129.  
  130.   if (coordFlag == 0)
  131.     printf ("Number of segments fit to data = %d.\n", nFits);
  132.  
  133. /* write image output file */
  134.   ImageOut (argv[2], imgO);
  135.  
  136.   return (0);
  137. }
  138.  
  139.  
  140.  
  141. /* USAGE:       function gives instructions on usage of program
  142.  *                    usage: usage (flag)
  143.  *              When flag is 1, the long message is given, 0 gives short.
  144.  */
  145.  
  146. long
  147. usage (flag)
  148.      short flag;                /* flag =1 for long message; =0 for short message */
  149. {
  150.  
  151. /* print short usage message or long */
  152.   printf ("USAGE: fitline infile outimg [-c] [-L]\n");
  153.   if (flag == 0)
  154.     return (-1);
  155.  
  156.   printf ("\nfitline fits straight lines to pixel chain segments\n");
  157.   printf ("using the eigenvector fit method.\n");
  158.   printf ("NOTE: The fit is performed to each complete line segment;\n");
  159.   printf ("      a segment is a chain of points between features, either\n");
  160.   printf ("      endpoint features or junction features.\n");
  161.   printf ("NOTE: this fit is not appropriate to approximate curve or corner\n");
  162.   printf ("      features within segments -- use a critical point fit or\n");
  163.   printf ("      polygonalization fit for this case, instead.\n\n");
  164.   printf ("ARGUMENTS:\n");
  165.   printf ("    infile: input filename (PCC)\n");
  166.   printf ("    outimg: output image filename (TIF)\n\n");
  167.   printf ("OPTIONS:\n");
  168.   printf ("        -c: when set, print line coordinates.\n");
  169.   printf ("        -L: print Software License for this module\n");
  170.  
  171.   return (-1);
  172. }
  173.  
  174.  
  175. /* INPUT:       function reads input parameters
  176.  *                  usage: input (argc, argv, &coordFlag)
  177.  */
  178.  
  179. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  180.  
  181. long
  182. input (argc, argv, coordFlag)
  183.      int argc;
  184.      char *argv[];
  185.      short *coordFlag;          /* flag = 1 to list lines; 0 otherwise */
  186. {
  187.   long n;
  188.  
  189.   if (argc == 1)
  190.     USAGE_EXIT (1);
  191.   if (argc == 2)
  192.     USAGE_EXIT (0);
  193.  
  194.   *coordFlag = 0;
  195.  
  196.   for (n = 3; n < argc; n++) {
  197.     if (strcmp (argv[n], "-c") == 0)
  198.       *coordFlag = 1;
  199.     else if (strcmp (argv[n], "-L") == 0) {
  200.       print_sos_lic ();
  201.       exit (0);
  202.     }
  203.     else
  204.       USAGE_EXIT (0);
  205.   }
  206.  
  207.   return (0);
  208. }
  209.