7
#include <grass/glocale.h>
9
#include "local_proto.h"
11
#define PN Region.perimeter_npoints
12
#define P Region.perimeter
15
#define SIG Sigs.sig[SN-1]
17
#define MEAN(b) (Band_sum[b]/np)
18
#define STD_DEV(b) ((float) sqrt ((double) VAR(b,b) / np))
19
#define VAR(b1,b2) (Band_product[b1][b2] - Band_sum[b1]*Band_sum[b2]/np)
23
static int *Range_max, *Range_min;
24
static float *Band_sum; /* for means, variances */
25
static float **Band_product;
26
static int **Band_histo;
27
static int np; /* number of points in sample */
28
static int usable_signature = 0;
29
static int dont_save(void);
30
static int yes_save(void);
31
static int done(void);
34
/**********************************************************************/
36
/************************** ###### ************************************/
38
/**********************************************************************/
39
int init_sig_routines(size_t nbands)
43
if ((Range_min = (int *)G_calloc(nbands, sizeof(int))) == NULL ||
44
(Range_max = (int *)G_calloc(nbands, sizeof(int))) == NULL ||
45
(Band_min = (int *)G_calloc(nbands, sizeof(int))) == NULL ||
46
(Band_max = (int *)G_calloc(nbands, sizeof(int))) == NULL ||
47
(Band_sum = (float *)G_calloc(nbands, sizeof(float))) == NULL ||
48
(Band_product = (float **)G_calloc(nbands, sizeof(float *))) == NULL
49
|| (Band_histo = (int **)G_calloc(nbands, sizeof(int *))) == NULL)
50
G_fatal_error(_("Unable to allocate space for signature statistics."));
51
for (i = 0; i < nbands; i++) {
52
if ((Band_product[i] =
53
(float *)G_calloc(nbands, sizeof(float))) == NULL ||
54
(Band_histo[i] = (int *)G_calloc(MAX_CATS, sizeof(int))) == NULL)
55
G_fatal_error(_("Unable to allocate space for signature statistics."));
62
/**********************************************************************/
64
/************************** ###### ************************************/
66
/**********************************************************************/
67
int prepare_signature(int nbands)
76
void (*prev_sigalarm) ();
78
Menu_msg("Preparing signature...");
82
G_warning(_("prepare_signature: outline has odd number of points."));
86
for (b = 0; b < nbands; b++) {
88
for (b2 = 0; b2 < nbands; b2++)
89
Band_product[b][b2] = 0.0;
90
for (b2 = 0; b2 < MAX_CATS; b2++)
91
Band_histo[b][b2] = 0;
96
prev_sigalarm = signal(SIGALRM, sigalarm);
98
for (i = 1; i < PN; i += 2) {
99
if (signalflag.interrupt)
102
if (signalflag.alarm) {
104
signalflag.alarm = 0;
105
sprintf(msg, "Preparing signature... %.0f%% complete",
106
(float)i / PN * 100.0);
112
if (y != P[i - 1].y) {
113
G_warning(_("prepare_signature: scan line %d has odd number of points."),
117
readbands(nbands, y);
123
G_warning(_("signature: perimeter points out of order."));
127
for (x = x0; x <= x1; x++) {
128
np++; /* count interior points */
129
for (b = 0; b < nbands; b++) {
131
if (n < 0 || n > MAX_CATS - 1) {
132
G_warning(_("prepare_signature: data error."));
135
Band_sum[b] += n; /* sum for means */
136
Band_histo[b][n]++; /* histogram */
138
Band_min[b] = Band_max[b] = n;
140
Band_min[b] = n; /* absolute min, max */
144
for (b2 = 0; b2 <= b; b2++) /* products for variance */
145
Band_product[b][b2] += n * Bandbuf[b2][x];
150
signal(SIGALRM, prev_sigalarm);
153
return (usable_signature = !signalflag.interrupt);
156
/**********************************************************************/
158
/************************** ###### ************************************/
160
/**********************************************************************/
163
extern int Display_color;
164
extern char *Display_color_name;
172
int show_signature(int nbands, double default_nstd)
177
char std_str[50], color_str[50];
180
static Objects objects[] = {
181
INFO("Signature Menu:", &use),
182
MENU("", input_std, &use),
183
MENU("", input_color, &use),
184
MENU(" Display matches ", display_signature, &use),
185
MENU(" Done ", done, &use),
188
objects[1].label = std_str;
189
objects[2].label = color_str;
191
Menu_msg("Drawing histograms...");
192
histograms(nbands, Band_sum, Band_product, Band_histo, np,
193
Band_min, Band_max, Nstd, BEFORE_STD);
195
for (b = 0; b < nbands; b++) {
196
dist = Nstd * STD_DEV(b);
198
Range_min[b] = mean - dist + 0.5;
199
Range_max[b] = mean + dist + 0.5;
203
while (selection != DONE) {
204
sprintf(std_str, " Set std dev's (%5.2f) ", Nstd);
205
sprintf(color_str, " Set color (%s) ", Display_color_name);
206
selection = Input_pointer(objects);
208
case INP_STD: /* Input Number of Std. Deviations */
209
/* set min/max for each band - Nstd standard deviations from mean
210
not exceed actual min and max */
211
for (b = 0; b < nbands; b++) {
212
dist = Nstd * STD_DEV(b);
214
Range_min[b] = mean - dist + 0.5;
215
Range_max[b] = mean + dist + 0.5;
217
Menu_msg("Drawing histograms...");
218
histograms(nbands, Band_sum, Band_product, Band_histo, np,
219
Range_min, Range_max, Nstd, AFTER_STD);
221
/* remove the mask file, if it exists */
225
case INP_COLOR: /* Input Color for Display */
227
case DISPLAY: /* Display the matching cells */
230
case DONE: /* done here, go back to command menu */
234
G_warning(_("Unknown Menu selection in show_signature()."));
239
/* remove the created mask file */
245
static int done(void)
250
/**********************************************************************/
252
/************************** ###### ************************************/
254
/**********************************************************************/
255
int display_signature(void)
259
struct Cell_head cellhd;
263
int row, nrows, ncols;
264
struct Colors mask_colors;
267
Menu_msg("Finding cells that match the signature...");
269
nbands = Refer.nfiles;
271
/* build new mask based on current signature and Nstd */
272
G_set_window(&VIEW_MAP1->cell.head);
275
if ((fd = G_open_cell_new(MASK)) < 0)
276
G_fatal_error(_("Unable to open the cell map MASK."));
277
if ((buffer = G_allocate_cell_buf()) == NULL)
278
G_fatal_error(_("Unable to allocate the cell buffer in display_signature()."));
279
nrows = G_window_rows();
280
ncols = G_window_cols();
282
for (row = 0; row < nrows; row++) {
283
readbands(nbands, row);
284
for (col = 0; col < ncols; col++) {
285
buffer[col] = (CELL) 0;
286
for (n = 0; n < nbands; n++) {
287
if (Bandbuf[n][col] < Range_min[n] ||
288
Bandbuf[n][col] > Range_max[n])
289
goto past; /* if not in range jump out past the assignment */
291
buffer[col] = (CELL) 1;
294
G_put_raster_row(fd, buffer, CELL_TYPE);
299
} /* end of if first_display */
301
/* generate and write the color table for the mask */
302
G_init_colors(&mask_colors);
303
G_set_color((CELL) 1, Color_table[Display_color].red,
304
Color_table[Display_color].grn,
305
Color_table[Display_color].blue, &mask_colors);
306
G_write_colors(MASK, G_mapset(), &mask_colors);
308
/* display new mask */
309
if (G_get_cellhd(MASK, G_mapset(), &cellhd) != 0)
310
G_fatal_error(_("Did not find input cell map MASK."));
311
G_adjust_window_to_box(&cellhd, &VIEW_MASK1->cell.head, VIEW_MASK1->nrows,
313
draw_cell(VIEW_MASK1, OVER_LAY);
319
/**********************************************************************/
321
/************************** ###### ************************************/
323
/**********************************************************************/
324
/* for menu to know if we have a signature */
325
int have_signature(void)
327
return (usable_signature);
330
/**********************************************************************/
332
/************************** ###### ************************************/
334
/**********************************************************************/
335
/* routine to save the signature into the signature structure */
338
int save_signature(void)
340
static Objects objects[] = {
341
INFO("Do you want to save this Signature?", &use2),
342
MENU(" Yes ", yes_save, &use2),
343
MENU(" No ", dont_save, &use2),
347
Input_pointer(objects);
353
static int yes_save(void)
358
/* get a new signature */
359
I_new_signature(&Sigs);
361
/* get signature name */
363
Menu_msg("Input signature description on keyboard...");
364
Curses_prompt_gets("Signature Description? ", tempstr);
365
strcpy(SIG.desc, tempstr);
368
/* save the signature in a Sig structure */
371
for (b = 0; b < Sigs.nbands; b++) {
372
SIG.mean[b] = MEAN(b);
373
for (b2 = 0; b2 <= b; b2++)
374
SIG.var[b][b2] = VAR(b, b2) / (np - 1);
382
static int dont_save(void)
388
/**********************************************************************/
390
/************************** ###### ************************************/
392
/**********************************************************************/
393
/* routine to write out the signature structure */
394
int write_signatures(void)
396
Menu_msg("Saving Signature File...");
397
I_write_signatures(outsig_fd, &Sigs);