GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <string.h> 00002 #include <stdlib.h> 00003 #include <grass/imagery.h> 00004 #include <grass/gis.h> 00005 00006 static int gettag(FILE *, char *); 00007 static int get_nbands(FILE *, struct SigSet *); 00008 static int get_title(FILE *, struct SigSet *); 00009 static int get_class(FILE *, struct SigSet *); 00010 static int get_classnum(FILE *, struct ClassSig *); 00011 static int get_classtype(FILE *, struct ClassSig *); 00012 static int get_classtitle(FILE *, struct ClassSig *); 00013 static int get_subclass(FILE *, struct SigSet *, struct ClassSig *); 00014 static int get_subclass_pi(FILE *, struct SubSig *); 00015 static int get_subclass_means(FILE *, struct SubSig *, int); 00016 static int get_subclass_covar(FILE *, struct SubSig *, int); 00017 00018 static double **alloc_matrix(int rows, int cols) 00019 { 00020 double **m; 00021 int i; 00022 00023 m = (double **)G_calloc(rows, sizeof(double *)); 00024 m[0] = (double *)G_calloc(rows * cols, sizeof(double)); 00025 for (i = 1; i < rows; i++) 00026 m[i] = m[i - 1] + cols; 00027 00028 return m; 00029 } 00030 00031 int I_SigSetNClasses(struct SigSet *S) 00032 { 00033 int i, count; 00034 00035 for (i = 0, count = 0; i < S->nclasses; i++) 00036 if (S->ClassSig[i].used) 00037 count++; 00038 00039 return count; 00040 } 00041 00042 00043 struct ClassData *I_AllocClassData(struct SigSet *S, 00044 struct ClassSig *C, int npixels) 00045 { 00046 struct ClassData *Data; 00047 00048 Data = &(C->ClassData); 00049 Data->npixels = npixels; 00050 Data->count = 0; 00051 Data->x = alloc_matrix(npixels, S->nbands); 00052 Data->p = alloc_matrix(npixels, C->nsubclasses); 00053 return Data; 00054 } 00055 00056 int I_InitSigSet(struct SigSet *S) 00057 { 00058 S->nbands = 0; 00059 S->nclasses = 0; 00060 S->ClassSig = NULL; 00061 S->title = NULL; 00062 00063 return 0; 00064 } 00065 00066 int I_SigSetNBands(struct SigSet *S, int nbands) 00067 { 00068 S->nbands = nbands; 00069 00070 return 0; 00071 } 00072 00073 struct ClassSig *I_NewClassSig(struct SigSet *S) 00074 { 00075 struct ClassSig *Sp; 00076 00077 if (S->nclasses == 0) 00078 S->ClassSig = (struct ClassSig *)G_malloc(sizeof(struct ClassSig)); 00079 else 00080 S->ClassSig = (struct ClassSig *)G_realloc((char *)S->ClassSig, 00081 sizeof(struct ClassSig) * 00082 (S->nclasses + 1)); 00083 00084 Sp = &S->ClassSig[S->nclasses++]; 00085 Sp->classnum = 0; 00086 Sp->nsubclasses = 0; 00087 Sp->used = 1; 00088 Sp->type = SIGNATURE_TYPE_MIXED; 00089 Sp->title = NULL; 00090 return Sp; 00091 } 00092 00093 struct SubSig *I_NewSubSig(struct SigSet *S, struct ClassSig *C) 00094 { 00095 struct SubSig *Sp; 00096 int i; 00097 00098 if (C->nsubclasses == 0) 00099 C->SubSig = (struct SubSig *)G_malloc(sizeof(struct SubSig)); 00100 else 00101 C->SubSig = (struct SubSig *)G_realloc((char *)C->SubSig, 00102 sizeof(struct SubSig) * 00103 (C->nsubclasses + 1)); 00104 00105 Sp = &C->SubSig[C->nsubclasses++]; 00106 Sp->used = 1; 00107 Sp->R = (double **)G_calloc(S->nbands, sizeof(double *)); 00108 Sp->R[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double)); 00109 for (i = 1; i < S->nbands; i++) 00110 Sp->R[i] = Sp->R[i - 1] + S->nbands; 00111 Sp->Rinv = (double **)G_calloc(S->nbands, sizeof(double *)); 00112 Sp->Rinv[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double)); 00113 for (i = 1; i < S->nbands; i++) 00114 Sp->Rinv[i] = Sp->Rinv[i - 1] + S->nbands; 00115 Sp->means = (double *)G_calloc(S->nbands, sizeof(double)); 00116 Sp->N = 0; 00117 Sp->pi = 0; 00118 Sp->cnst = 0; 00119 return Sp; 00120 } 00121 00122 #define eq(a,b) strcmp(a,b)==0 00123 00124 int I_ReadSigSet(FILE * fd, struct SigSet *S) 00125 { 00126 char tag[256]; 00127 00128 I_InitSigSet(S); 00129 00130 while (gettag(fd, tag)) { 00131 if (eq(tag, "title:")) 00132 get_title(fd, S); 00133 if (eq(tag, "nbands:")) 00134 get_nbands(fd, S); 00135 if (eq(tag, "class:")) 00136 get_class(fd, S); 00137 } 00138 return 1; /* for now assume success */ 00139 } 00140 00141 static int gettag(FILE * fd, char *tag) 00142 { 00143 if (fscanf(fd, "%s", tag) != 1) 00144 return 0; 00145 G_strip(tag); 00146 return 1; 00147 } 00148 00149 static int get_nbands(FILE * fd, struct SigSet *S) 00150 { 00151 fscanf(fd, "%d", &S->nbands); 00152 00153 return 0; 00154 } 00155 00156 static int get_title(FILE * fd, struct SigSet *S) 00157 { 00158 char title[1024]; 00159 00160 *title = 0; 00161 fscanf(fd, "%[^\n]", title); 00162 I_SetSigTitle(S, title); 00163 00164 return 0; 00165 } 00166 00167 static int get_class(FILE * fd, struct SigSet *S) 00168 { 00169 char tag[1024]; 00170 struct ClassSig *C; 00171 00172 C = I_NewClassSig(S); 00173 while (gettag(fd, tag)) { 00174 if (eq(tag, "endclass:")) 00175 break; 00176 if (eq(tag, "classnum:")) 00177 get_classnum(fd, C); 00178 if (eq(tag, "classtype:")) 00179 get_classtype(fd, C); 00180 if (eq(tag, "classtitle:")) 00181 get_classtitle(fd, C); 00182 if (eq(tag, "subclass:")) 00183 get_subclass(fd, S, C); 00184 } 00185 00186 return 0; 00187 } 00188 00189 static int get_classnum(FILE * fd, struct ClassSig *C) 00190 { 00191 fscanf(fd, "%ld", &C->classnum); 00192 00193 return 0; 00194 } 00195 00196 static int get_classtype(FILE * fd, struct ClassSig *C) 00197 { 00198 fscanf(fd, "%d", &C->type); 00199 00200 return 0; 00201 } 00202 00203 static int get_classtitle(FILE * fd, struct ClassSig *C) 00204 { 00205 char title[1024]; 00206 00207 *title = 0; 00208 fscanf(fd, "%[^\n]", title); 00209 I_SetClassTitle(C, title); 00210 00211 return 0; 00212 } 00213 00214 static int get_subclass(FILE * fd, struct SigSet *S, struct ClassSig *C) 00215 { 00216 struct SubSig *Sp; 00217 char tag[1024]; 00218 00219 Sp = I_NewSubSig(S, C); 00220 00221 while (gettag(fd, tag)) { 00222 if (eq(tag, "endsubclass:")) 00223 break; 00224 if (eq(tag, "pi:")) 00225 get_subclass_pi(fd, Sp); 00226 if (eq(tag, "means:")) 00227 get_subclass_means(fd, Sp, S->nbands); 00228 if (eq(tag, "covar:")) 00229 get_subclass_covar(fd, Sp, S->nbands); 00230 } 00231 00232 return 0; 00233 } 00234 00235 static int get_subclass_pi(FILE * fd, struct SubSig *Sp) 00236 { 00237 fscanf(fd, "%lf", &Sp->pi); 00238 00239 return 0; 00240 } 00241 00242 static int get_subclass_means(FILE * fd, struct SubSig *Sp, int nbands) 00243 { 00244 int i; 00245 00246 for (i = 0; i < nbands; i++) 00247 fscanf(fd, "%lf", &Sp->means[i]); 00248 00249 return 0; 00250 } 00251 00252 static int get_subclass_covar(FILE * fd, struct SubSig *Sp, int nbands) 00253 { 00254 int i, j; 00255 00256 for (i = 0; i < nbands; i++) 00257 for (j = 0; j < nbands; j++) 00258 fscanf(fd, "%lf", &Sp->R[i][j]); 00259 00260 return 0; 00261 } 00262 00263 int I_SetSigTitle(struct SigSet *S, const char *title) 00264 { 00265 if (title == NULL) 00266 title = ""; 00267 if (S->title) 00268 free(S->title); 00269 S->title = G_store(title); 00270 00271 return 0; 00272 } 00273 00274 const char *I_GetSigTitle(const struct SigSet *S) 00275 { 00276 if (S->title) 00277 return S->title; 00278 else 00279 return ""; 00280 } 00281 00282 int I_SetClassTitle(struct ClassSig *C, const char *title) 00283 { 00284 if (title == NULL) 00285 title = ""; 00286 if (C->title) 00287 free(C->title); 00288 C->title = G_store(title); 00289 00290 return 0; 00291 } 00292 00293 const char *I_GetClassTitle(const struct ClassSig *C) 00294 { 00295 if (C->title) 00296 return C->title; 00297 else 00298 return ""; 00299 } 00300 00301 int I_WriteSigSet(FILE * fd, const struct SigSet *S) 00302 { 00303 const struct ClassSig *Cp; 00304 const struct SubSig *Sp; 00305 int i, j, b1, b2; 00306 00307 fprintf(fd, "title: %s\n", I_GetSigTitle(S)); 00308 fprintf(fd, "nbands: %d\n", S->nbands); 00309 for (i = 0; i < S->nclasses; i++) { 00310 Cp = &S->ClassSig[i]; 00311 if (!Cp->used) 00312 continue; 00313 if (Cp->nsubclasses <= 0) 00314 continue; 00315 fprintf(fd, "class:\n"); 00316 fprintf(fd, " classnum: %ld\n", Cp->classnum); 00317 fprintf(fd, " classtitle: %s\n", I_GetClassTitle(Cp)); 00318 fprintf(fd, " classtype: %d\n", Cp->type); 00319 00320 for (j = 0; j < Cp->nsubclasses; j++) { 00321 Sp = &Cp->SubSig[j]; 00322 fprintf(fd, " subclass:\n"); 00323 fprintf(fd, " pi: %g\n", Sp->pi); 00324 fprintf(fd, " means:"); 00325 for (b1 = 0; b1 < S->nbands; b1++) 00326 fprintf(fd, " %g", Sp->means[b1]); 00327 fprintf(fd, "\n"); 00328 fprintf(fd, " covar:\n"); 00329 for (b1 = 0; b1 < S->nbands; b1++) { 00330 fprintf(fd, " "); 00331 for (b2 = 0; b2 < S->nbands; b2++) 00332 fprintf(fd, " %g", Sp->R[b1][b2]); 00333 fprintf(fd, "\n"); 00334 } 00335 fprintf(fd, " endsubclass:\n"); 00336 } 00337 fprintf(fd, "endclass:\n"); 00338 } 00339 00340 return 0; 00341 }