~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to imagery/i.class/signature.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <string.h>
2
 
#include <unistd.h>
3
 
#include <math.h>
4
 
#include <stdio.h>
5
 
#include <signal.h>
6
 
#include <grass/gis.h>
7
 
#include <grass/glocale.h>
8
 
#include "globals.h"
9
 
#include "local_proto.h"
10
 
 
11
 
#define PN Region.perimeter_npoints
12
 
#define P  Region.perimeter
13
 
 
14
 
#define SN  Sigs.nsigs
15
 
#define SIG Sigs.sig[SN-1]
16
 
 
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)
20
 
 
21
 
static int *Band_min;
22
 
static int *Band_max;
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);
32
 
 
33
 
 
34
 
/**********************************************************************/
35
 
 
36
 
/************************** ###### ************************************/
37
 
 
38
 
/**********************************************************************/
39
 
int init_sig_routines(size_t nbands)
40
 
{
41
 
    int i;
42
 
 
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."));
56
 
    }
57
 
 
58
 
    return 0;
59
 
}
60
 
 
61
 
 
62
 
/**********************************************************************/
63
 
 
64
 
/************************** ###### ************************************/
65
 
 
66
 
/**********************************************************************/
67
 
int prepare_signature(int nbands)
68
 
{
69
 
    char msg[100];
70
 
    int b, b2;
71
 
    int n;
72
 
    int i;
73
 
    int x0, x1;
74
 
    int x;
75
 
    int y;
76
 
    void (*prev_sigalarm) ();
77
 
 
78
 
    Menu_msg("Preparing signature...");
79
 
 
80
 
    usable_signature = 0;
81
 
    if (PN % 2) {
82
 
        G_warning(_("prepare_signature: outline has odd number of points."));
83
 
        return (0);
84
 
    }
85
 
 
86
 
    for (b = 0; b < nbands; b++) {
87
 
        Band_sum[b] = 0.0;
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;
92
 
    }
93
 
    np = 0;
94
 
 
95
 
    signalflag.alarm = 0;
96
 
    prev_sigalarm = signal(SIGALRM, sigalarm);
97
 
    alarm(10);
98
 
    for (i = 1; i < PN; i += 2) {
99
 
        if (signalflag.interrupt)
100
 
            break;
101
 
 
102
 
        if (signalflag.alarm) {
103
 
            alarm(0);
104
 
            signalflag.alarm = 0;
105
 
            sprintf(msg, "Preparing signature... %.0f%% complete",
106
 
                    (float)i / PN * 100.0);
107
 
            Menu_msg(msg);
108
 
            alarm(10);
109
 
        }
110
 
 
111
 
        y = P[i].y;
112
 
        if (y != P[i - 1].y) {
113
 
            G_warning(_("prepare_signature: scan line %d has odd number of points."),
114
 
                      (i + 1) / 2);
115
 
            return (0);
116
 
        }
117
 
        readbands(nbands, y);
118
 
 
119
 
        x0 = P[i - 1].x - 1;
120
 
        x1 = P[i].x - 1;
121
 
 
122
 
        if (x0 > x1) {
123
 
            G_warning(_("signature: perimeter points out of order."));
124
 
            return (0);
125
 
        }
126
 
 
127
 
        for (x = x0; x <= x1; x++) {
128
 
            np++;               /* count interior points */
129
 
            for (b = 0; b < nbands; b++) {
130
 
                n = Bandbuf[b][x];
131
 
                if (n < 0 || n > MAX_CATS - 1) {
132
 
                    G_warning(_("prepare_signature: data error."));
133
 
                    return (0);
134
 
                }
135
 
                Band_sum[b] += n;       /* sum for means */
136
 
                Band_histo[b][n]++;     /* histogram */
137
 
                if (np == 1)
138
 
                    Band_min[b] = Band_max[b] = n;
139
 
                if (Band_min[b] > n)
140
 
                    Band_min[b] = n;    /* absolute min, max */
141
 
                if (Band_max[b] < n)
142
 
                    Band_max[b] = n;
143
 
 
144
 
                for (b2 = 0; b2 <= b; b2++)     /* products for variance */
145
 
                    Band_product[b][b2] += n * Bandbuf[b2][x];
146
 
            }
147
 
        }
148
 
    }
149
 
    alarm(0);
150
 
    signal(SIGALRM, prev_sigalarm);
151
 
    Menu_msg("");
152
 
 
153
 
    return (usable_signature = !signalflag.interrupt);
154
 
}
155
 
 
156
 
/**********************************************************************/
157
 
 
158
 
/************************** ###### ************************************/
159
 
 
160
 
/**********************************************************************/
161
 
 
162
 
int first_display;
163
 
extern int Display_color;
164
 
extern char *Display_color_name;
165
 
extern float Nstd;
166
 
 
167
 
#define INP_STD 1
168
 
#define INP_COLOR 2
169
 
#define DISPLAY 3
170
 
#define DONE 4
171
 
 
172
 
int show_signature(int nbands, double default_nstd)
173
 
{
174
 
    int b;
175
 
    int selection = 0;
176
 
    static int use = 1;
177
 
    char std_str[50], color_str[50];
178
 
    float dist, mean;
179
 
 
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),
186
 
        {0}
187
 
    };
188
 
    objects[1].label = std_str;
189
 
    objects[2].label = color_str;
190
 
 
191
 
    Menu_msg("Drawing histograms...");
192
 
    histograms(nbands, Band_sum, Band_product, Band_histo, np,
193
 
               Band_min, Band_max, Nstd, BEFORE_STD);
194
 
    Nstd = 1.5;
195
 
    for (b = 0; b < nbands; b++) {
196
 
        dist = Nstd * STD_DEV(b);
197
 
        mean = MEAN(b);
198
 
        Range_min[b] = mean - dist + 0.5;
199
 
        Range_max[b] = mean + dist + 0.5;
200
 
    }
201
 
    first_display = 1;
202
 
 
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);
207
 
        switch (selection) {
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);
213
 
                mean = MEAN(b);
214
 
                Range_min[b] = mean - dist + 0.5;
215
 
                Range_max[b] = mean + dist + 0.5;
216
 
            }
217
 
            Menu_msg("Drawing histograms...");
218
 
            histograms(nbands, Band_sum, Band_product, Band_histo, np,
219
 
                       Range_min, Range_max, Nstd, AFTER_STD);
220
 
 
221
 
            /* remove the mask file, if it exists */
222
 
            first_display = 1;
223
 
            remove_mask();
224
 
            break;
225
 
        case INP_COLOR: /* Input Color for Display */
226
 
            break;
227
 
        case DISPLAY:           /* Display the matching cells */
228
 
            first_display = 0;
229
 
            break;
230
 
        case DONE:              /* done here, go back to command menu */
231
 
            Menu_msg("");
232
 
            break;
233
 
        default:
234
 
            G_warning(_("Unknown Menu selection in show_signature()."));
235
 
        }
236
 
 
237
 
    }
238
 
 
239
 
    /* remove the created mask file */
240
 
    remove_mask();
241
 
 
242
 
    return 0;
243
 
}
244
 
 
245
 
static int done(void)
246
 
{
247
 
    return (DONE);
248
 
}
249
 
 
250
 
/**********************************************************************/
251
 
 
252
 
/************************** ###### ************************************/
253
 
 
254
 
/**********************************************************************/
255
 
int display_signature(void)
256
 
{
257
 
    int fd;
258
 
    CELL *buffer;
259
 
    struct Cell_head cellhd;
260
 
    register int n;
261
 
    register int col;
262
 
    register int nbands;
263
 
    int row, nrows, ncols;
264
 
    struct Colors mask_colors;
265
 
 
266
 
    if (first_display) {
267
 
        Menu_msg("Finding cells that match the signature...");
268
 
 
269
 
        nbands = Refer.nfiles;
270
 
 
271
 
        /* build new mask based on current signature and Nstd */
272
 
        G_set_window(&VIEW_MAP1->cell.head);
273
 
        open_band_files();
274
 
 
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();
281
 
 
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 */
290
 
                }
291
 
                buffer[col] = (CELL) 1;
292
 
              past:;
293
 
            }
294
 
            G_put_raster_row(fd, buffer, CELL_TYPE);
295
 
        }
296
 
 
297
 
        G_close_cell(fd);
298
 
        close_band_files();
299
 
    }                           /* end of if first_display */
300
 
 
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);
307
 
 
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,
312
 
                           VIEW_MASK1->ncols);
313
 
    draw_cell(VIEW_MASK1, OVER_LAY);
314
 
 
315
 
    return (DISPLAY);
316
 
}
317
 
 
318
 
 
319
 
/**********************************************************************/
320
 
 
321
 
/************************** ###### ************************************/
322
 
 
323
 
/**********************************************************************/
324
 
/* for menu to know if we have a signature */
325
 
int have_signature(void)
326
 
{
327
 
    return (usable_signature);
328
 
}
329
 
 
330
 
/**********************************************************************/
331
 
 
332
 
/************************** ###### ************************************/
333
 
 
334
 
/**********************************************************************/
335
 
/* routine to save the signature into the signature structure */
336
 
static int use2 = 1;
337
 
 
338
 
int save_signature(void)
339
 
{
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),
344
 
        {0}
345
 
    };
346
 
 
347
 
    Input_pointer(objects);
348
 
    Menu_msg("");
349
 
 
350
 
    return 0;
351
 
}
352
 
 
353
 
static int yes_save(void)
354
 
{
355
 
    int b, b2;
356
 
    char tempstr[100];
357
 
 
358
 
    /* get a new signature */
359
 
    I_new_signature(&Sigs);
360
 
 
361
 
    /* get signature name */
362
 
    tempstr[0] = '\0';
363
 
    Menu_msg("Input signature description on keyboard...");
364
 
    Curses_prompt_gets("Signature Description? ", tempstr);
365
 
    strcpy(SIG.desc, tempstr);
366
 
    use_mouse_msg();
367
 
 
368
 
    /* save the signature in a Sig structure */
369
 
    SIG.npoints = np;
370
 
    SIG.status = 1;
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);
375
 
    }
376
 
    Menu_msg("");
377
 
 
378
 
    return (1);
379
 
}
380
 
 
381
 
 
382
 
static int dont_save(void)
383
 
{
384
 
    return (1);
385
 
}
386
 
 
387
 
 
388
 
/**********************************************************************/
389
 
 
390
 
/************************** ###### ************************************/
391
 
 
392
 
/**********************************************************************/
393
 
/* routine to write out the signature structure */
394
 
int write_signatures(void)
395
 
{
396
 
    Menu_msg("Saving Signature File...");
397
 
    I_write_signatures(outsig_fd, &Sigs);
398
 
    fclose(outsig_fd);
399
 
    G_sleep(1);
400
 
    Menu_msg("Done.");
401
 
 
402
 
    return 0;
403
 
}