home *** CD-ROM | disk | FTP | other *** search
- /*
- * dpp.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * D(raw)P(oint)P(attern)
- *
- * generate and draw random point, square or disk pattern
- *
- */
-
- #include "dpp.h"
-
- #define ON 1
- #define OFF 0
- #define NEW_SEED ON
- #define SQR(a) ( (a)*(a) )
-
- /* globals */
- extern char *optarg;
- extern int optind, opterr;
- extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
-
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s outimg [-p t][-c f][-s x y] [-L]\n", progname);
- printf ("\n%s generates and draws a random, ordered or clustered point pattern\n\n", progname);
- printf ("ARGUMENTS:\n");
- printf (" outimg: output image filename (TIF format)\n\n");
- printf ("OPTIONS:\n");
- printf (" -p t: select pattern type: R(andom), O(rdered), C(lustered)\n");
- printf (" t = R: random (default)\n");
- printf (" t = O: ordered\n");
- printf (" t = C: clustered\n");
- printf (" -c f: desired fractional coverage, 0<=f<=100\n");
- printf (" -s x y: output image size (default 512x512)\n");
- printf (" -L: print Software License for this module\n");
- exit (1);
- }
-
- /*
- * function to draw points
- */
- void
- draw_points (int *x, int *y, long n, struct Image *imgOut, int value)
- {
- int ip;
-
- for (ip = 0; ip < n; ip++) {
- setpixel (*(x + ip), *(y + ip), imgOut, value);
- }
- }
-
- /*
- * function to generate a single random point coordinate
- */
- Sp
- random_point (int nx, int ny)
- {
- Sp pt;
-
- pt.x = (short) ((float) rand () * (float) nx / (float) RAND_MAX);
- pt.y = (short) ((float) rand () * (float) ny / (float) RAND_MAX);
- return (pt);
- }
-
- /*
- * function to generate random point coordinates
- */
- void
- generate_random_points (int *xc, int *yc, long npix, int nx, int ny)
- {
- int seed = 1;
- int ip;
- Sp pt;
-
- if (NEW_SEED == ON) {
- printf ("...select new seed(enter 1 to reinitialize):");
- scanf ("%d", &seed);
- }
-
- srand (seed); /* must be called only once per series */
- for (ip = 0; ip < npix; ip++) {
- #ifdef DEBUG
- if (ip % 100 == 0)
- printf (" ip = %d\n", ip);
- #endif
- pt = random_point (nx, ny);
- *(xc + ip) = (int) pt.x;
- *(yc + ip) = (int) pt.y;
- }
- }
-
- /*
- * function to generate ordered point coordinates
- */
- void
- generate_ordered_points (int *xc, int *yc, long npix, int nx, int ny, float coverage)
- {
- int sepx;
- int sepy;
- int ix;
- int iy;
- int xnpts;
- int ynpts;
- int i;
-
- if (!npix)
- return;
- xnpts = (int) ((float) nx * (float) sqrt ((double) coverage));
- ynpts = (int) ((float) ny * (float) sqrt ((double) coverage));
- sepx = (nx / xnpts) + 1;
- sepy = (ny / ynpts) + 1;
- i = 0;
- for (ix = 0; ix < nx; ix += sepx) {
- for (iy = 0; iy < ny; iy += sepy) {
- if (i >= npix)
- break;
- *(xc + i) = ix;
- *(yc + i) = iy;
- i++;
- }
- }
- }
-
- /*
- * function to generate clustered point coordinates
- */
- void
- generate_clustered_points (int *xc, int *yc, long npix, int nx, int ny, long nxny)
- {
- char buf[256];
- long Nc;
- int kc;
- int ip;
- int seed = 1;
- Sp cur_seed_pt;
- Sp new_pt;
- int xsd, ysd;
- int ppc;
- double sigma;
- double fxc, fyc;
- double fac, rsq;
-
-
- for (;;) {
- printf ("How many clusters? ");
- readlin (buf);
- if (!(Nc = atol (buf)))
- printf ("Sorry, invalid input, try again\n");
- else
- break;
- }
-
- for (;;) {
- printf ("Select SIGMA to set cluster width (width proportional to NX/SIGMA): ");
- readlin (buf);
- if (!(sigma = (float) atof (buf)))
- printf ("Sorry, invalid input, try again\n");
- else
- break;
- }
-
-
- if (NEW_SEED == ON) {
- printf ("...select new seed(enter 1 to reinitialize):");
- readlin (buf);
- sscanf (buf, "%d", &seed);
- }
- srand (seed);
-
- ppc = npix / Nc;
- ip = 0;
- for (kc = 0; kc < Nc; kc++) {
-
-
- cur_seed_pt = random_point (nx, ny);
-
- /*
- * ** restrict seed coordinate to interior of available AOI
- * ** (to reduce chance of generating a cluster overlapping edge of AOI)
- */
- xsd = (int) ((nx / 2) + (2.0 * cur_seed_pt.x / nx - 1.0) * (nx / 8));
- ysd = (int) ((ny / 2) + (2.0 * cur_seed_pt.y / ny - 1.0) * (ny / 8));
- printf ("\ncluster: %d - seed point: %3d, %3d\n", kc, xsd, ysd);
-
- do {
- new_pt = random_point (nx, ny);
- fxc = (double) (2.0 * new_pt.x / nx - 1.0);
- fyc = (double) (2.0 * new_pt.y / ny - 1.0);
-
- if ((rsq = SQR (fxc) + SQR (fyc)) < 1.0) {
- fac = sqrt (-2.0 * log (rsq) / rsq);
- *(xc + ip) = (int) (xsd + fac * fxc * (double) nx / (2 * sigma));
- *(yc + ip) = (int) (ysd + fac * fyc * (double) ny / (2 * sigma));
- //printf("\n%3d - (%3d, %3d)\n", ip, *(xc+ip), *(yc+ip));
- ip++;
- }
- } while (ip < ppc * (kc + 1));
- }
-
- }
-
- void
- main (int argc, char **argv)
- {
-
- int i_arg;
- char type = 'R'; /* type of pattern drawn */
- int *xc, *yc;
- float coverage;
- long nxny;
- long npix;
- int nx = HEIGHT;
- int ny = WIDTH;
- struct Image *imgOut;
-
- /*
- * cmd line options
- */
- static char *optstring = "p:c:s:L";
-
- nxny = nx * ny;
- coverage = (float) (5.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) {
- switch (i_arg) {
- case 'c':
- coverage = (float) atof (optarg);
- break;
- case 'p':
- type = optarg[0];
- break;
- case 's':
- if (!sscanf (argv[optind - 1], "%d", &nx) || !sscanf (argv[optind], "%d", &ny)) {
- printf ("Error getting values for image size\n");
- printf ("Will use defaults\n");
- nx = WIDTH;
- ny = HEIGHT;
- }
- else
- optind += 1;
- nxny = nx * ny;
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- printf ("...unknown command line option encountered\n");
- exit (1);
- break;
- }
- }
-
- npix = (long) (coverage * nxny / 100.0);
- printf ("Image size for %s = %d x %d pixels\n", argv[1], nx, ny);
- printf ("Coverage = %f percent of area, # pixels to be drawn = %ld\n", coverage, npix);
- printf ("pattern = %c\n", type);
-
- /*
- * initialize graphics
- */
- imgOut = ImageAlloc ((long) ny, (long) nx, BPS);
-
- /* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
- tiffInput = 0;
-
- if ((xc = (int *) calloc ((size_t) npix, sizeof (int))) == NULL) {
- printf ("\n...mem alloc for xc failed\n");
- exit (1);
- }
- if ((yc = (int *) calloc ((size_t) npix, sizeof (int))) == NULL) {
- printf ("\n...mem alloc for yc failed\n");
- exit (1);
- }
-
- switch (type) {
- case 'R': /* Random point pattern */
- case 'r':
- generate_random_points (xc, yc, npix, nx, ny);
- draw_points (xc, yc, npix, imgOut, WHITE);
- break;
- case 'O': /* Ordered point pattern */
- case 'o':
- generate_ordered_points (xc, yc, npix, nx, ny, coverage / (float) 100.0);
- draw_points (xc, yc, npix, imgOut, WHITE);
- break;
- case 'C': /* Clustered point pattern */
- case 'c':
- generate_clustered_points (xc, yc, npix, nx, ny, nxny);
- draw_points (xc, yc, npix, imgOut, WHITE);
- break;
- default:
- printf ("...unknown pattern type: %c\n", type);
- exit (1);
- break;
- }
-
-
- /*
- * free memory
- */
- free (xc);
- free (yc);
-
- printf ("\n...writing output file %s\n", argv[1]);
- ImageOut (argv[1], imgOut);
-
- }
-