/***** Principal Component Transformation of Satellite Data *****/ /* Center for Space Research WRW 402 University of Texas Austin, TX 78712-1085 (512) 471-6824 */ #include #include #include #include #include #include static CELL round_c (double x) { CELL n; if (x >= 0.0) n = x + .5; else { n = -x + .5; n = -n; } return n; } int main (int argc, char *argv[]) { /* Global variable & function declarations */ int i,j,k; /* Loop control variables */ long rows,cols; /* Number of rows & columns */ long row,col; double sum; /* sum of all entries in a band */ long bands; /* Number of image bands */ long NN; /* Total number of data points */ double *mu; /* Mean vector for image bands */ double **covar; /* Covariance Matrix */ double *eigval; double **eigmat; char **inp_names; char **out_names, temp[600]; int infd, PASSES, pass; int *inp_file_descr; int scale, scale_max, scale_min; double min, max; char tempbuf[500], *mapset; CELL *rowbuf1, *rowbuf2; double *d_buf; /* a cell buf only double in order not to loose precision */ struct GModule *module; struct Option *opt1, *opt2, *opt3 ; module = G_define_module(); module->keywords = _("imagery"); module->description = "Principal components analysis (pca) " "program for image processing."; /* Define the different options */ opt1 = G_define_option() ; opt1->key = "input"; opt1->type = TYPE_STRING; opt1->required = YES; opt1->multiple = YES; opt1->gisprompt = "old,cell,raster" ; opt1->description= "input layer name" ; opt2 = G_define_option() ; opt2->key = "output"; opt2->type = TYPE_STRING; opt2->required = YES; opt2->gisprompt = "new,cell,raster" ; opt2->description= "output layer name"; opt3 = G_define_option() ; opt3->key = "rescale"; opt3->type = TYPE_INTEGER; opt3->key_desc = "min,max"; opt3->required = NO; opt3->answer = "0,255"; opt3->description= "Rescaling range output (For no rescaling use 0,0)"; /***** Start of main *****/ G_gisinit(argv[0]); if (G_parser(argc, argv) < 0) exit(-1); rows = G_window_rows(); cols = G_window_cols(); NN = rows * cols; rowbuf1 = G_allocate_cell_buf(); rowbuf2 = G_allocate_cell_buf(); scale = 1; scale_min = 0; scale_max =255; /* default values */ if(opt3->answer) { sscanf(opt3->answers[0], "%d", &scale_min); sscanf(opt3->answers[1], "%d", &scale_max); if(scale_min==scale_max) { if(scale_min==0) scale = 0; else { fprintf(stderr, "Scale range length should be >0; Using default values: 0,255\n\n"); scale_min = 0; scale_max = 255; } } if(scale_maxanswers[bands] != NULL; bands++); covar = (double **) G_calloc(bands, sizeof(double *)); mu = (double *) G_malloc(bands * sizeof(double )); inp_file_descr = (int *) G_malloc(bands * sizeof(int )); eigmat = (double **) G_calloc(bands, sizeof(double *)); eigval = (double *) G_calloc(bands, sizeof(double)); inp_names = (char **) G_calloc(bands, sizeof(char *)); out_names = (char **) G_calloc(bands, sizeof(char *)); d_buf = (double *) G_malloc(cols * sizeof(double)); for(i=0;ianswers[i], "")) == NULL) { sprintf(tempbuf, "Unable to find cell map <%s>", opt1->answers[i]); G_fatal_error(tempbuf); } if ((inp_file_descr[i] =G_open_cell_old(opt1->answers[i], mapset)) < 0) { sprintf(tempbuf,"Error opening %s\n",opt1->answers[i]); G_fatal_error(tempbuf); } inp_names[i] = G_fully_qualified_name(opt1->answers[i], mapset); sprintf(tempbuf, "%s.%d", opt2->answer, i+1); out_names[i] = G_fully_qualified_name(tempbuf, G_mapset()); /* G_close_cell (infd) */; } /* check output file */ /*****************************/ /*if (strlen(opt2->answer) >=13) G_fatal_error("The output cell map name can not be longer than 12 characters."); */ /* for(i=0;ianswer, (i+1)); if((scale)&&(pass==PASSES)) { fprintf(stdout, "%s: Rescaling the data to %d,%d range ... ", name, scale_min, scale_max); fflush(stdout); old_range = max - min; new_range = (double) (scale_max - scale_min); } if(pass==1) { fprintf(stdout,"%s: ", name); fflush(stdout); if ((infd=G_open_cell_new(name)) < 0) { sprintf(tempbuf,"Error opening %s\n",G_fully_qualified_name(name, mapset)); G_fatal_error(tempbuf); } } for(row=0 ; rowmax) max=d_buf[col]; } else if(scale) { /* scaling the cell */ if(min==max) rowbuf1[col] = 1; else /* first mapping data to 0,(new_range-1) and then adding new_min */ rowbuf1[col] = round_c((new_range*(d_buf[col]-min)/old_range) + scale_min); } } /* writing the cell */ } /* for col=0 to cols */ } /* for j = 0 to bands */ if(pass==PASSES) G_put_raster_row( infd, rowbuf1, CELL_TYPE); } /* for row = 0 to rows */ G_percent(row,rows,2); if(pass==PASSES) { G_close_cell(infd); /* make grey scale color table */ sprintf(command, "r.colors %s color=grey", name); system(command); /* write a color table */ } } /* for pass = 1 to PASSES */ } /* for i=0 to bands-1 */ fprintf(stdout, "Eigen vectors:\n"); for(i=0;i