2
#include <grass/raster.h>
3
#include <grass/glocale.h>
4
#include <grass/imagery.h>
5
#include <grass/gmath.h>
12
void extract_init(struct SigSet *S)
24
/* allocate scratch memory */
25
lambda = G_alloc_vector(nbands);
26
tmp_mat = G_alloc_matrix(nbands, nbands);
29
/* invert matrix and compute constant for each subclass */
32
for (m = 0; m < S->nclasses; m++) {
33
C = &(S->ClassSig[m]);
35
/* for each subclass */
36
for (i = 0; i < C->nsubclasses; i++) {
37
SubS = &(C->SubSig[i]);
39
/* Test for symetric matrix */
40
for (b1 = 0; b1 < nbands; b1++)
41
for (b2 = 0; b2 < nbands; b2++) {
42
if (SubS->R[b1][b2] != SubS->R[b2][b1])
43
G_warning(_("Nonsymetric covariance for class %d subclass %d"),
46
SubS->Rinv[b1][b2] = SubS->R[b1][b2];
47
tmp_mat[b1][b2] = SubS->R[b1][b2];
51
/* Test for positive definite matrix */
52
G_math_eigen(tmp_mat, lambda, nbands);
53
for (b1 = 0; b1 < nbands; b1++) {
54
if (lambda[b1] <= 0.0)
55
G_warning(_("Nonpositive eigenvalues for class %d subclass %d"),
59
/* Precomputes the cnst */
60
SubS->cnst = (-nbands / 2.0) * log(2 * PI);
61
for (b1 = 0; b1 < nbands; b1++) {
62
SubS->cnst += -0.5 * log(lambda[b1]);
65
/* Precomputes the inverse of tex->R */
66
invert(SubS->Rinv, nbands);
69
G_free_vector(lambda);
70
G_free_matrix(tmp_mat);
74
void extract(DCELL *** img, /* multispectral image, img[band][i][j] */
75
struct Region *region, /* region to extract */
76
LIKELIHOOD *** ll, /* log likelihood, ll[i][j][class] */
77
struct SigSet *S /* class signatures */
80
int i, j; /* column and row indexes */
81
int m; /* class index */
82
int k; /* subclass index */
83
int b1, b2; /* spectral index */
84
int no_data; /* no data flag */
85
int max_nsubclasses; /* maximum number of subclasses */
86
int nbands; /* number of spectral bands */
87
double *subll; /* log likelihood of subclasses */
89
double maxlike = 0.0L;
96
/* determine the maximum number of subclasses */
98
for (m = 0; m < S->nclasses; m++)
99
if (S->ClassSig[m].nsubclasses > max_nsubclasses)
100
max_nsubclasses = S->ClassSig[m].nsubclasses;
102
/* allocate memory */
103
diff = (double *)G_malloc(nbands * sizeof(double));
104
subll = (double *)G_malloc(max_nsubclasses * sizeof(double));
106
/* Compute log likelihood at each pixel and for every class. */
109
for (i = region->ymin; i < region->ymax; i++)
110
for (j = region->xmin; j < region->xmax; j++) {
112
/* Check for no data condition */
114
for (b1 = 0; (b1 < nbands) && no_data; b1++)
115
no_data = no_data && (Rast_is_d_null_value(&img[b1][i][j]));
118
for (m = 0; m < S->nclasses; m++)
123
for (m = 0; m < S->nclasses; m++) {
124
C = &(S->ClassSig[m]);
126
/* compute log likelihood for each subclass */
127
for (k = 0; k < C->nsubclasses; k++) {
128
SubS = &(C->SubSig[k]);
129
subll[k] = SubS->cnst;
130
for (b1 = 0; b1 < nbands; b1++) {
131
diff[b1] = img[b1][i][j] - SubS->means[b1];
133
0.5 * diff[b1] * diff[b1] *
136
for (b1 = 0; b1 < nbands; b1++)
137
for (b2 = b1 + 1; b2 < nbands; b2++)
139
diff[b1] * diff[b2] * SubS->Rinv[b1][b2];
142
/* shortcut for one subclass */
143
if (C->nsubclasses == 1) {
144
ll[i][j][m] = subll[0];
146
/* compute mixture likelihood */
148
/* find the most likely subclass */
149
for (k = 0; k < C->nsubclasses; k++) {
152
if (subll[k] > maxlike)
156
/* Sum weighted subclass likelihoods */
158
for (k = 0; k < C->nsubclasses; k++)
160
exp(subll[k] - maxlike) * C->SubSig[k].pi;
162
ll[i][j][m] = log(subsum) + maxlike;
167
G_free((char *)diff);
168
G_free((char *)subll);