home *** CD-ROM | disk | FTP | other *** search
- /*
- * spp.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * S(can) P(oint) P(attern)
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include "spp.h"
-
- #undef DEBUG
- #undef SHOW_PP
- #undef DEBUG_SORT
-
- #define ON 1
- #define OFF 0
-
-
- /* globals */
- unsigned char **image; /* input/output image */
- int NMAX = 4000; /* max no point objects in image */
-
- int offset_of_y = OFFSETOF (struct Pix, y);
- int offset_of_x = OFFSETOF (struct Pix, x);
-
- extern char *optarg;
- extern int optind, opterr;
-
- int POINT_OBJ = ON; /* default: assume pattern of point-objs */
- int SORT = OFF;
- int WRITE_FILE = OFF;
-
-
- /*
- * comparison function for qsort():
- * sort array of tuples in order of increassing y-values (not tested)
- */
- int
- compare (t1, t2)
- const void *t1, *t2;
- {
- int i1, i2;
-
- i1 = *(int *) ((struct Pix *) t1 + offset_of_y);
- i2 = *(int *) ((struct Pix *) t2 + offset_of_y);
- return ((int) SIGN (i1 - i2));
- }
-
-
-
- void
- fail_alloc (char *str, int code)
- {
- printf ("\n...memory alloc for %s failed\n", str);
- exit (code);
- }
-
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s inimg [-d] [-w file] [-L]\n", progname);
- printf ("\n%s scans a point pattern in a given image\n", progname);
- printf ("and generates data for later Vornoi analysis.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -d : default mode: scan pattern of point-like objects\n");
- printf (" marked in max_index-1 (254);\n");
- printf (" data are generated in order of increasing y-coordinates.\n");
- printf (" -w file: write file (.vin) to disk\n");
- printf (" -L : print Software License for this module\n");
- exit (1);
- }
-
-
-
- void
- main (int argc, char *argv[])
- {
- int i;
- int nrows, ncols;
-
- struct Pix *Cxy;
- long n_pts;
- int status;
- int xmin, ymin, xmax, ymax;
- int jmin, imin, jmax, imax;
- int left_x, right_x;
-
- char *buf;
- int i_arg;
- FILE *file;
- Image *imgIO; /* structure for I/O images */
- char in_filename[256];
-
-
- /*
- * cmd line options
- */
- static char *optstring = "dw:L";
-
-
- in_filename[0] = '\0';
-
- /*
- * parse command line
- */
- optind = 2;
- opterr = ON; /* give error messages */
-
- if (argc < 2)
- usage (argv[0]);
-
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- printf ("\n");
- switch (i_arg) {
- case 'd':
- printf ("...option %c: default mode\n", i_arg);
- POINT_OBJ = ON;
- break;
- case 'w':
- printf ("...option %c: write file %s to disk\n",
- i_arg, buf = optarg);
-
- if ((file = fopen (buf, "w")) == NULL) {
- puts ("\n...could not open output file");
- exit (1);
- }
- WRITE_FILE = ON;
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- printf ("...unknown condition encountered\n");
- exit (1);
- break;
- }
- }
- strcpy (in_filename, argv[1]);
-
- /*
- * get the image
- */
- imgIO = ImageIn (in_filename);
- if (imgIO->bps == 8 && imgIO->spp == 3) {
- printf ("Got RGB image!!!\n");
- fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
- exit (1);
- }
- image = imgIO->img;
- nrows = imgIO->height;
- ncols = imgIO->width;
-
- jmin = imin = 0;
- jmax = ncols;
- imax = nrows;
-
- left_x = jmin;
- right_x = jmax - 1;
- ncols = jmax - jmin;
- nrows = imax - imin;
-
- #ifdef DEBUG
- printf ("\n...ncols = %d, nrows = %d\n", ncols, nrows);
- #endif
-
-
- /*
- * zero outer border of image
- */
- zero_border (imgIO, 1);
-
-
- /*
- * memory allocation
- */
- if ((Cxy = (struct Pix *) calloc (NMAX, sizeof (struct Pix))) == NULL)
- fail_alloc ("Cxy", 1);
-
- /*
- * extract coordinates of objects in point pattern
- * -->note: data are extracted in order of increasing y!!
- */
- printf ("\n...extracting point object coordinates:");
- n_pts = 0;
- if ((status = x_pp (Cxy, &n_pts, left_x, imin, right_x, imax)) == 0) {
- printf ("\n...no objects exceeds NMAX = %d\n", NMAX);
- exit (1);
- }
- else
- printf ("\n...found %ld points\n", n_pts);
-
- /* realloc */
-
- #ifdef SHOW_PP
- printf ("\n...point coordinates:\n");
- for (i = 0; i < n_pts; i++) {
- printf ("... x[%d] = %4d, y[%d] = %4d\n",
- i, (Cxy + i)->x, i, (Cxy + i)->y);
- }
- #endif
-
-
- if (SORT == OFF) {
- printf ("\n...find extrema in (unsorted) data...\n");
-
- xmin = xmax = (Cxy + 0)->x;
- ymin = ymax = (Cxy + 0)->y;
- for (i = 1; i < n_pts; i++) {
- if ((Cxy + i)->x < xmin)
- xmin = (Cxy + i)->x;
- if ((Cxy + i)->x > xmax)
- xmax = (Cxy + i)->x;
-
- if ((Cxy + i)->y < ymin)
- ymin = (Cxy + i)->y;
- if ((Cxy + i)->y > ymax)
- ymax = (Cxy + i)->y;
- }
- printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
- printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
- }
-
- /*
- * sort Cxy if required for later use
- */
- else if (SORT == ON) {
- printf ("\n...sort data and find extrema...\n");
-
- qsort (Cxy, n_pts, sizeof (struct Pix), compare);
-
- xmin = xmax = (Cxy + 0)->x;
- for (i = 1; i < n_pts; i++) {
- if ((Cxy + i)->x < xmin)
- xmin = (Cxy + i)->x;
- if ((Cxy + i)->x > xmax)
- xmax = (Cxy + i)->x;
- }
- ymin = (Cxy + 0)->y;
- ymax = (Cxy + n_pts - 1)->y;
-
- #ifdef DEBUG_SORT
- printf ("\n...data after sorting:\n");
- for (i = 0; i < n_pts; i++) {
- printf ("... x[%d] = %4d, y[%d] = %4d\n",
- i, (Cxy + i)->x, i, (Cxy + i)->y);
- }
- printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
- printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
- #endif
- }
-
- /*
- * write data file of format ( .vin) for use by Voronoi routines
- */
- if (WRITE_FILE == ON) {
- write_vin_file (file, (int) n_pts, xmin, ymin, xmax, ymax, Cxy);
- fclose (file);
- }
-
- if (POINT_OBJ == ON)
- free (Cxy);
- }
-