void floats_to_bytes_from_file_ext(const char *inFile, const char *outFile, char *band, float mask, scale_t scaling, float scale_factor) { FILE *fp; meta_parameters *meta; float *float_data; unsigned char *byte_data; int ii, band_number; long long pixel_count; long offset; meta = meta_read(inFile); band_number = (!band || strlen(band) == 0 || strcmp(band, "???")==0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); pixel_count = meta->general->line_count * meta->general->sample_count; offset = meta->general->line_count * band_number; float_data = (float *) MALLOC(sizeof(float) * pixel_count); fp = FOPEN(inFile, "rb"); get_float_lines(fp, meta, offset, meta->general->line_count, float_data); FCLOSE(fp); byte_data = floats_to_bytes_ext(float_data, pixel_count, mask, scaling, scale_factor); for (ii=0; ii<pixel_count; ii++) float_data[ii] = (float) byte_data[ii]; meta->general->data_type = ASF_BYTE; meta_write(meta, outFile); fp = FOPEN(outFile, "wb"); put_float_lines(fp, meta, offset, meta->general->line_count, float_data); FCLOSE(fp); FREE(float_data); FREE(byte_data); meta_free(meta); }
int main(int argc,char *argv[]) { char infile1[256], infile2[256], infile3[256]; // Input file name char outfile[256]; // Output file name char tmpPath[1024]; browse_type_t mode = NOTYPE; int i,j; int sample_count; double scale; extern int currArg; strcpy(tmpPath, ""); // Parse command line if ((argc-currArg)<1) { printf("Insufficient arguments.\n"); usage(""); } while (currArg < (argc-2)) { char *key = argv[currArg++]; if (strmatches(key, "-sentinel", "--sentinel", NULL)) { CHECK_ARG(1); scale = atof(GET_ARG(1)); mode = SENTINEL_DUAL; } else if (strmatches(key, "-tmpDir", "--tmpDir", NULL)) { CHECK_ARG(1); strcpy(tmpPath, GET_ARG(1)); } else if (strmatches(key, "-log", "--log", NULL)) { CHECK_ARG(1); strcpy(logFile,GET_ARG(1)); fLog = FOPEN(logFile, "a"); logflag = TRUE; } else if (strmatches(key, "-quiet", "--quiet", "-q", NULL)) quietflag = TRUE; else { --currArg; break; } } if ((argc-currArg) < 2) { printf("Insufficient arguments.\n"); usage(argv[0]); } if (mode == NOTYPE && argc == 4) mode = PALSAR_FBD; else if (mode == NOTYPE && argc == 5) mode = PALSAR_PLR; if (!quietflag) asfSplashScreen(argc, argv); if (mode == PALSAR_FBD) { asfPrintStatus("Creating colorized browse image from PALSAR FBD data\n"); create_name(infile1,argv[1],".img"); create_name(infile2,argv[2],".img"); create_name(outfile,argv[3],".img"); meta_parameters *meta1 = meta_read(infile1); meta_parameters *meta2 = meta_read(infile2); if (meta1->general->line_count != meta2->general->line_count || meta1->general->sample_count != meta2->general->sample_count) { asfPrintError("Images must be the same size!!!\n"); exit(1); } strcpy(meta1->general->bands,"HH"); strcpy(meta2->general->bands,"HV"); int pixel_count = meta1->general->line_count*meta1->general->sample_count; float *buf1 = MALLOC(pixel_count * sizeof(float)); float *buf2 = MALLOC(pixel_count * sizeof(float)); float *buf3 = MALLOC(pixel_count * sizeof(float)); unsigned char *cbuf1, *cbuf2, *cbuf3; FILE *fp1 = FOPEN(infile1, "r"); FILE *fp2 = FOPEN(infile2, "r"); FILE *ofp = FOPEN(outfile, "w"); char ofile1[256]; char ofile2[256]; strcpy(ofile1,argv[1]); strcat(ofile1,"_DB.img"); strcpy(ofile2,argv[2]); strcat(ofile2,"_DB.img"); printf("Creating output DB files %s and %s\n",ofile1,ofile2); FILE *ofp1 = FOPEN(ofile1, "w"); FILE *ofp2 = FOPEN(ofile2, "w"); get_float_lines(fp1,meta1,0,meta1->general->line_count, buf1); get_float_lines(fp2,meta2,0,meta2->general->line_count, buf2); /* Convert data from sigma0 to dB */ sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { if (meta_is_valid_double(buf1[sample_count])) { if (buf1[sample_count] != 0) buf1[sample_count] = 10.0 * log10f(buf1[sample_count]); if (buf2[sample_count] != 0) buf2[sample_count] = 10.0 * log10f(buf2[sample_count]); } sample_count++; } } put_float_lines(ofp1, meta1, 0,meta1->general->line_count,buf1); put_float_lines(ofp2, meta2, 0,meta1->general->line_count,buf2); meta_write(meta1, ofile1); meta_write(meta2, ofile2); fclose(fp1); fclose(fp2); fclose(ofp1); fclose(ofp2); /* Scale the data to a byte range using given min/max values */ cbuf1 = my_floats_to_bytes(buf1,(long long) pixel_count, 0.0,MINMAX,-30.0,-1.0); cbuf2 = my_floats_to_bytes(buf2,(long long) pixel_count, 0.0,MINMAX,-30.0,-10.0); /* cbuf1 = my_floats_to_bytes(buf1,(long long) pixel_count, 0.0,MINMAX,-31.0,7.1); cbuf2 = my_floats_to_bytes(buf2,(long long) pixel_count, 0.0,MINMAX,-31.0,7.1); */ strcpy(ofile1,argv[1]); strcat(ofile1,"_byte.img"); strcpy(ofile2,argv[2]); strcat(ofile2,"_byte.img"); printf("Creating output byte files %s and %s\n",ofile1,ofile2); ofp1 = FOPEN(ofile1, "w"); ofp2 = FOPEN(ofile2, "w"); meta1->general->data_type=REAL32; meta2->general->data_type=REAL32; sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { buf1[sample_count] = (float) cbuf1[sample_count]; buf2[sample_count] = (float) cbuf2[sample_count]; sample_count++; } } put_float_lines(ofp1,meta1,0,meta1->general->line_count,buf1); put_float_lines(ofp2,meta2,0,meta2->general->line_count,buf2); meta_write(meta1, ofile1); meta_write(meta2, ofile2); fclose(ofp1); fclose(ofp2); /* Create the third band for the color image */ sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { if (buf2[sample_count] != 0) { /* buf3[sample_count] = (buf1[sample_count] / buf2[sample_count]); */ buf3[sample_count] = (buf1[sample_count] - buf2[sample_count]); if (buf3[sample_count] < 1) buf3[sample_count] = 1; else if (buf3[sample_count] > 255) buf3[sample_count] = 255; } else buf3[sample_count] = 0; sample_count++; } } cbuf3 = my_floats_to_bytes(buf3,(long long) pixel_count, 0.0,SIGMA ,-25.0,-10.0); sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { buf3[sample_count] = (float) cbuf3[sample_count]; sample_count++; } } /* Finally, create the 3 banded image we were looking for */ strcpy(meta1->general->bands,"HH,HV,DIV"); meta1->general->band_count=3; put_band_float_lines(ofp,meta1,0,0,meta1->general->line_count,buf1); put_band_float_lines(ofp,meta1,1,0,meta1->general->line_count,buf2); put_band_float_lines(ofp,meta1,2,0,meta1->general->line_count,buf3); meta_write(meta1,outfile); } else if (mode == PALSAR_PLR) { /* Mode 1 - Create Color Browse from 3 bands using 3sigma stretch */ asfPrintStatus("Creating colorized browse image from PALSAR PLR data\n"); create_name(infile1,argv[1],".img"); create_name(infile2,argv[2],".img"); create_name(infile3,argv[3],".img"); create_name(outfile,argv[4],".img"); meta_parameters *meta1 = meta_read(infile1); meta_parameters *meta2 = meta_read(infile2); meta_parameters *meta3 = meta_read(infile3); if (meta1->general->line_count != meta2->general->line_count || meta1->general->sample_count != meta2->general->sample_count) { asfPrintError("Images must be the same size!!!\n"); exit(1); } if (meta3->general->line_count != meta2->general->line_count || meta3->general->sample_count != meta2->general->sample_count) { asfPrintError("Images must be the same size!!!\n"); exit(1); } int pixel_count = meta1->general->line_count*meta1->general->sample_count; float *buf1 = MALLOC(pixel_count * sizeof(float)); float *buf2 = MALLOC(pixel_count * sizeof(float)); float *buf3 = MALLOC(pixel_count * sizeof(float)); float *buf4 = MALLOC(pixel_count * sizeof(float)); unsigned char *cbuf1, *cbuf2, *cbuf3, *cbuf4; FILE *fp1 = FOPEN(infile1, "r"); FILE *fp2 = FOPEN(infile2, "r"); FILE *fp3 = FOPEN(infile3, "r"); FILE *ofp = FOPEN(outfile, "w"); get_float_lines(fp1,meta1,0,meta1->general->line_count, buf1); get_float_lines(fp2,meta2,0,meta2->general->line_count, buf2); get_float_lines(fp3,meta3,0,meta3->general->line_count, buf3); /* Convert data from sigma0 to dB */ sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { if (meta_is_valid_double(buf1[sample_count])) { if (buf1[sample_count] != 0) buf1[sample_count] = 10.0 * log10f(buf1[sample_count]); if (buf2[sample_count] != 0) buf2[sample_count] = 10.0 * log10f(buf2[sample_count]); if (buf3[sample_count] != 0) buf3[sample_count] = 10.0 * log10f(buf3[sample_count]); } sample_count++; } } /* Scale the data to a byte range using 3-sigma stretch values */ cbuf1 = my_floats_to_bytes(buf1,(long long) pixel_count, 0.0,SIGMA3,-30.0,-1.0); cbuf2 = my_floats_to_bytes(buf2,(long long) pixel_count, 0.0,SIGMA3,-30.0,-10.0); cbuf3 = my_floats_to_bytes(buf3,(long long) pixel_count, 0.0,SIGMA3,-30.0,-10.0); meta1->general->data_type=REAL32; //meta2->general->data_type=ASF_BYTE; //meta3->general->data_type=ASF_BYTE; sample_count = 0; for (i=0; i<meta1->general->line_count; ++i) { for (j=0; j<meta1->general->sample_count; ++j) { buf1[sample_count] = (float) cbuf1[sample_count]; buf2[sample_count] = (float) cbuf2[sample_count]; buf3[sample_count] = (float) cbuf3[sample_count]; sample_count++; } } /* Finally, create the 3 banded image we were looking for */ strcpy(meta1->general->bands,"HH,HV,VV"); meta1->general->band_count=3; put_band_float_lines(ofp,meta1,0,0,meta1->general->line_count,buf1); put_band_float_lines(ofp,meta1,1,0,meta1->general->line_count,buf2); put_band_float_lines(ofp,meta1,2,0,meta1->general->line_count,buf3); meta_write(meta1,outfile); } else if (mode == SENTINEL_DUAL) { asfPrintStatus("Creating colorized browse image from Sentinel dual-pol " "data\n"); if (strlen(tmpPath) > 0) { create_name(infile1,argv[5],".img"); create_name(infile2,argv[6],".img"); create_name(outfile,argv[7],".tif"); } else { create_name(infile1,argv[3],".img"); create_name(infile2,argv[4],".img"); create_name(outfile,argv[5],".tif"); } // Create temporary directory char tmpDir[1024]; if (strlen(tmpPath) > 0) sprintf(tmpDir, "%s%cbrowse-", tmpPath, DIR_SEPARATOR); else strcpy(tmpDir, "browse-"); strcat(tmpDir, time_stamp_dir()); create_clean_dir(tmpDir); asfPrintStatus("Temp dir is: %s\n", tmpDir); // Calculate ratio image char tmpRatio[512], tmpRed[512], tmpGreen[512], tmpBlue[512], tmpIn[512]; char *inFiles[2]; inFiles[0] = (char *) MALLOC(sizeof(char)*255); inFiles[1] = (char *) MALLOC(sizeof(char)*255); strcpy(inFiles[0], infile1); strcpy(inFiles[1], infile2); sprintf(tmpRatio, "%s%cdiv.img", tmpDir, DIR_SEPARATOR); raster_calc(tmpRatio, "a/b", 2, inFiles); // Resample all three bands and scale to byte meta_parameters *metaIn = meta_read(tmpRatio); double scaleFactor = 1.0/(scale/metaIn->general->x_pixel_size); meta_free(metaIn); sprintf(tmpIn, "%s%cred.img", tmpDir, DIR_SEPARATOR); resample(infile1, tmpIn, scaleFactor, scaleFactor); sprintf(tmpRed, "%s%cred_byte.img", tmpDir, DIR_SEPARATOR); floats_to_bytes_from_file(tmpIn, tmpRed, NULL, -40.0, SIGMA); sprintf(tmpIn, "%s%cgreen.img", tmpDir, DIR_SEPARATOR); resample(infile2, tmpIn, scaleFactor, scaleFactor); sprintf(tmpGreen, "%s%cgreen_byte.img", tmpDir, DIR_SEPARATOR); floats_to_bytes_from_file(tmpIn, tmpGreen, NULL, -40.0, SIGMA); sprintf(tmpIn, "%s%cblue.img", tmpDir, DIR_SEPARATOR); resample(tmpRatio, tmpIn, scaleFactor, scaleFactor); sprintf(tmpBlue, "%s%cblue_byte.img", tmpDir, DIR_SEPARATOR); floats_to_bytes_from_file(tmpIn, tmpBlue, NULL, -40.0, SIGMA); // Layer stack the bands char tmpBrowse[512]; sprintf(tmpBrowse, "%s%cbrowse.img", tmpDir, DIR_SEPARATOR); FILE *fpOut = FOPEN(tmpBrowse, "w"); meta_parameters *metaOut = meta_read(tmpRed); metaOut->general->band_count = 3; metaIn = meta_read(tmpRed); int line_count = metaIn->general->line_count; int sample_count = metaIn->general->sample_count; float *buf = (float *) MALLOC(sizeof(float)*line_count*sample_count); FILE *fpIn = FOPEN(tmpBlue, "r"); get_float_lines(fpIn, metaIn, 0, line_count, buf); put_band_float_lines(fpOut, metaOut, 0, 0, line_count, buf); FCLOSE(fpIn); fpIn = FOPEN(tmpGreen, "r"); get_float_lines(fpIn, metaIn, 0, line_count, buf); put_band_float_lines(fpOut, metaOut, 1, 0, line_count, buf); FCLOSE(fpIn); fpIn = FOPEN(tmpRed, "r"); get_float_lines(fpIn, metaIn, 0, line_count, buf); put_band_float_lines(fpOut, metaOut, 2, 0, line_count, buf); FCLOSE(fpIn); FCLOSE(fpOut); FREE(buf); strcpy(metaOut->general->bands, "red,green,blue"); meta_write(metaOut, tmpBrowse); // Export to GeoTIFF char *band_names[3] = { "blue", "green", "red" }; asf_export_bands(GEOTIFF, NONE, TRUE, FALSE, FALSE, FALSE, FALSE, tmpBrowse, outfile, band_names, NULL, NULL); // Clean up asfPrintStatus("Removing temporary directory: %s\n", tmpDir); remove_dir(tmpDir); meta_free(metaIn); meta_free(metaOut); } else asfPrintError("Mode is not defined!\n"); asfPrintStatus("Done.\n"); exit(EXIT_SUCCESS); }
void deskew(const char *infile, const char *outfile) { meta_parameters *meta = meta_read(infile); int nl = meta->general->line_count; int np = meta->general->sample_count; int nb = meta->general->band_count; char **band_name = extract_band_names(meta->general->bands, nb); int band, line, samp, deskewed = meta->sar->deskewed != 0; if (!meta->sar) asfPrintError("Cannot deskew data without a sar block!\n"); char *tmp_outfile; int do_rename = FALSE; if (strcmp(infile, outfile) == 0 && nb>1) { // user wants to deskew in-place // we can't actually do that on multi-band data, too much to keep in memory // use a temporary file, then clobber input file tmp_outfile = appendToBasename(outfile, "_tmp"); do_rename = TRUE; } else { // normal case: either // 1) single-band in-place deskew // 2) not in-place deskew (single or multi) tmp_outfile = STRDUP(outfile); } // calculate the amount of shift necessary double fac = calc_shift(meta, 0, 0); // Not sure if we need this or not... //fac *= meta->general->x_pixel_size / meta->general->y_pixel_size; // the "lower" array stores the required shifts, indexed by column // (the amount of shift is row-independent) int *lower = MALLOC(np * sizeof(int)); for (samp=0; samp<np; ++samp) lower[samp] = (int) floor(fac*(double)samp); if (meta->sar->deskewed) { asfPrintStatus("Data is already deskewed.\n"); } else { asfPrintStatus("Far-range shift amount: "); if (lower[np-1] > 0) asfPrintStatus("%d pixels down.\n", lower[np-1]); else asfPrintStatus("%d pixels up.\n", -lower[np-1]); } float *ibuf = MALLOC(np * sizeof(float)); float *obuf = CALLOC(np*nl, sizeof(float)); FILE *fpi = fopenImage(infile, "rb"); for (band=0; band<nb; ++band) { if (nb>1) asfPrintStatus("Deskewing band: %s\n", band_name[band]); // apply deskewing to this band for (line=0; line<nl; ++line) { get_float_line(fpi, meta, line + nl*band, ibuf); for (samp=0; samp<np; ++samp) { int out_line = deskewed ? line : line + lower[samp]; if (out_line >= 0 && out_line < nl) obuf[out_line*np+samp] = ibuf[samp]; } asfLineMeter(line,nl); } // write out this band FILE *fpo = fopenImage(tmp_outfile, band>0 ? "ab" : "wb"); put_float_lines(fpo, meta, band*nl, nl, obuf); FCLOSE(fpo); } FCLOSE(fpi); FREE(obuf); FREE(ibuf); FREE(lower); // if we output to a temporary file, clobber the input if (do_rename) { char *tmp_outfile_img = appendExt(tmp_outfile, ".img"); char *outfile_img = appendExt(outfile, ".img"); //printf("Renaming: %s -> %s\n", tmp_outfile_img, outfile_img); rename(tmp_outfile_img, outfile_img); FREE(tmp_outfile_img); FREE(outfile_img); } FREE(tmp_outfile); // only need to update the deskewed flag in the metadata meta->sar->deskewed = 1; meta_write(meta, outfile); meta_free(meta); }
// Input: // meta_parameters *meta_sar-- SAR geometry to subset the DEM // const char *demImg -- DEM data filename // const char *demMeta -- DEM metadata filename // int pad -- number of lines to add at the top/bottom/left/right // double tolerance -- how accurate the approximation mapping needs to be, // in units of pixels // const char *output_name -- output filename (basename) // int test_mode -- adds checks for the accuracy of the mapping, and // does some unit testing // Output: // no output parameters, the output is the output_name files (.img and .meta) // Return Value: // return TRUE on success, FALSE on fail // int make_gr_dem_ext(meta_parameters *meta_sar, const char *demImg, const char *demMeta, int pad, double tolerance, const char *output_name, int test_mode) { if (test_mode) test_interp(); asfPrintStatus("Reading DEM...\n"); meta_parameters *meta_dem = meta_read(demMeta); float *demData = NULL; FloatImage *fi_dem = NULL; int dnl = meta_dem->general->line_count; int dns = meta_dem->general->sample_count; if (0) demData = read_dem(meta_dem, demImg); else fi_dem = float_image_new_from_metadata(meta_dem, demImg); if (demData) asfPrintStatus("Old method: reading entire DEM.\n"); if (fi_dem) asfPrintStatus("New method: float image\n"); if (demData && fi_dem) asfPrintError("Impossible.\n"); char *outImg = appendExt(output_name, ".img"); char *output_name_tmp, *outImgTmp; // do not do DEM smoothing if the DEM pixel size is better or close to the // SAR image's pixel size. int do_averaging = TRUE; if (meta_dem->general->y_pixel_size - 10 < meta_sar->general->y_pixel_size) do_averaging = FALSE; asfPrintStatus("Averaging: %s (DEM %f, SAR: %f)\n", do_averaging ? "YES" : "NO", meta_dem->general->y_pixel_size, meta_sar->general->y_pixel_size); if (do_averaging) { output_name_tmp = appendStr(output_name, "_unsmoothed"); outImgTmp = appendExt(output_name_tmp, ".img"); } else { output_name_tmp = STRDUP(output_name); outImgTmp = STRDUP(outImg); } // add the padding if requested meta_parameters *meta_out = meta_copy(meta_sar); meta_out->general->line_count += pad*2; meta_out->general->sample_count += pad*2; meta_out->general->start_line -= pad; meta_out->general->start_sample -= pad; // fixing up the output metadata. Note that we must keep the SAR section // intact since that specifies our geometry which is the whole point of // this exercise. strcpy(meta_out->general->basename, meta_dem->general->basename); strcpy(meta_out->general->sensor, MAGIC_UNSET_STRING); strcpy(meta_out->general->processor, MAGIC_UNSET_STRING); strcpy(meta_out->general->mode, MAGIC_UNSET_STRING); strcpy(meta_out->general->sensor_name, MAGIC_UNSET_STRING); meta_out->general->image_data_type = DEM; meta_out->general->radiometry = MAGIC_UNSET_INT; strcpy(meta_out->general->acquisition_date, meta_dem->general->acquisition_date); meta_out->general->orbit = MAGIC_UNSET_INT; meta_out->general->orbit_direction = MAGIC_UNSET_CHAR; meta_out->general->frame = MAGIC_UNSET_INT; meta_out->general->band_count = 1; strcpy(meta_out->general->bands, "DEM"); int nl = meta_out->general->line_count; int ns = meta_out->general->sample_count; // finding the right grid size int size = find_grid_size(meta_sar, meta_dem, 512, .1*tolerance); asfPrintStatus("Creating ground range image...\n"); float *buf = MALLOC(sizeof(float)*ns*size); FILE *fpOut = FOPEN(outImgTmp, "wb"); // these are for tracking the quality of the bilinear interp // not used if test_mode is false int num_out_of_tol = 0; int num_checked = 0; int num_bad = 0; double max_err = 0; double avg_err = 0; int ii, jj; for (ii=0; ii<nl; ii += size) { int line_lo = ii; int line_hi = ii + size; for (jj=0; jj<ns; jj += size) { double lines[4], samps[4]; int samp_lo = jj; int samp_hi = jj + size; get_interp_params(meta_sar, meta_dem, line_lo, line_hi, samp_lo, samp_hi, lines, samps); int iii, jjj; for (iii=0; iii<size; ++iii) { for (jjj=0; jjj<size && jj+jjj<ns; ++jjj) { int index = iii*ns + jj + jjj; assert(index < ns*size); double line_out, samp_out; xy_interp(ii+iii, jj+jjj, line_lo, line_hi, samp_lo, samp_hi, lines, samps, &line_out, &samp_out); // random checking of the quality of our interpolations if (test_mode && iii%11==0 && jjj%13==0) { double real_line, real_samp; sar_to_dem(meta_sar, meta_dem, ii+iii, jj+jjj, &real_line, &real_samp); double err = hypot(real_line - line_out, real_samp - samp_out); avg_err += err; if (err > max_err) max_err = err; if (err > tolerance) { asfPrintStatus("Out of tolerance at %d,%d: (%f,%f) vs (%f,%f) -> %f\n", ii+iii, jj+jjj, line_out, samp_out, real_line, real_samp, err); ++num_out_of_tol; } if (err > .5) { asfPrintStatus("Error is larger than 1 pixel!\n"); ++num_bad; } ++num_checked; } if (demData) buf[index] = interp_demData(demData, dnl, dns, line_out, samp_out); else if (fi_dem) buf[index] = interp_dem(fi_dem, line_out, samp_out); else asfPrintError("Oops.\n"); } } } put_float_lines(fpOut, meta_out, ii, size, buf); asfPrintStatus("Completed %.1f%% \r", 100.*ii/(double)nl); } asfPrintStatus("Completed 100%% \n"); if (test_mode) { asfPrintStatus("Tolerance was %f\n", tolerance); asfPrintStatus("%d/%d checked pixels had error exceeding tolerance. (%.1f%%)\n", num_out_of_tol, num_checked, 100.*num_out_of_tol/(double)num_checked); asfPrintStatus("%d/%d checked pixels had error larger than half a pixel. (%.1f%%)\n", num_bad, num_checked, 100.*num_bad/(double)num_checked); asfPrintStatus("Maximum error: %f pixels\n", max_err); avg_err /= (double)num_checked; asfPrintStatus("Average error: %f pixels\n", avg_err); } FCLOSE(fpOut); meta_write(meta_out, outImgTmp); meta_free(meta_out); meta_free(meta_dem); FREE(buf); FREE(demData); if (fi_dem) float_image_free(fi_dem); // now apply 3x3 filter if (do_averaging) { asfPrintStatus("Smoothing with 3x3 kernel ...\n"); smooth(outImgTmp, outImg, 3, EDGE_TRUNCATE); } FREE(outImg); FREE(outImgTmp); FREE(output_name_tmp); return FALSE; }
int main(int argc, char **argv) { FILE *fp; meta_parameters *metaSrc, *metaTrg; envi_header *envi; extern int currArg; // Pre-initialized to 1 radiometry_t radiometry=r_AMP; filter_type_t filter_type; char srcImage[255], trgImage[255], *inFile, outFile[255], filter_str[25]; int startX_src, startY_src, startX_trg, startY_trg, lines, samples, size; int subset=FALSE, filter=FALSE, geotiff=FALSE, line_count, sample_count; double lat_UL, lon_UL, lat_LR, lon_LR, yLine, xSample; float mean, scale; register float *img, *filtered_img=NULL; register int x, y, l; /* parse command line */ logflag=quietflag=FALSE; while (currArg < (argc-2)) { char *key = argv[currArg++]; if (strmatch(key,"-startX")) { CHECK_ARG(1); startX_src = atoi(GET_ARG(1)); subset = TRUE; } else if (strmatch(key,"-startY")) { CHECK_ARG(1); startY_src = atoi(GET_ARG(1)); subset = TRUE; } else if (strmatch(key,"-lines")) { CHECK_ARG(1); lines = atoi(GET_ARG(1)); subset = TRUE; } else if (strmatch(key,"-samples")) { CHECK_ARG(1); samples = atoi(GET_ARG(1)); subset = TRUE; } else if (strmatch(key,"-filter")) { CHECK_ARG(2); strcpy(filter_str, GET_ARG(2)); size = atoi(GET_ARG(1)); filter = TRUE; } else if (strmatch(key,"-geotiff")) { geotiff = TRUE; } else { printf( "\n**Invalid option: %s\n", argv[currArg-1]); usage(argv[0]); } } if ((argc-currArg)<2) {printf("Insufficient arguments.\n"); usage(argv[0]);} strcpy (srcImage, argv[currArg]); strcpy (trgImage, argv[currArg+1]); asfSplashScreen(argc, argv); // Ingesting CEOS files into ASF internal format asfPrintStatus("Ingesting source image: %s ...\n", srcImage); asf_import(radiometry, FALSE, FALSE, FALSE, "CEOS", "", "geocoded_image", NULL, NULL, -99.0, -99.0, NULL, NULL, NULL, TRUE, NULL, srcImage, "", srcImage); metaSrc = meta_read(srcImage); asfPrintStatus("Ingesting target image: %s ...\n", trgImage); asf_import(radiometry, FALSE, FALSE, FALSE, "CEOS", "", "geocoded_image", NULL, NULL, -99.0, -99.0, NULL, NULL, NULL, TRUE, NULL, trgImage, "", trgImage); metaTrg = meta_read(trgImage); // Check subset values for source image line_count = metaSrc->general->line_count; sample_count = metaSrc->general->sample_count; if (subset) { if (startX_src < 0 || startX_src > sample_count) startX_src = 0; if (startY_src < 0 || startY_src > line_count) startY_src = 0; if (lines < 0 || (lines-startY_src) > line_count) lines = line_count - startY_src; if (samples < 0 || (samples-startX_src) > sample_count) samples = sample_count - startX_src; } else { startX_src = startY_src = 0; lines = line_count; samples = sample_count; } // Assign filter if (filter) { if (strcmp(uc(filter_str), "AVERAGE") == 0) filter_type = AVERAGE; else if (strcmp(uc(filter_str), "SOBEL") == 0) filter_type = SOBEL; else if (strcmp(uc(filter_str), "FROST") == 0) filter_type = FROST; else if (strcmp(uc(filter_str), "LEE") == 0) filter_type = LEE; else if (strcmp(uc(filter_str), "GAMMA_MAP") == 0) filter_type = GAMMA_MAP; else { asfPrintWarning("Unsupported filter type '%s'- ignoring the filter" " settings\n", filter_str); filter = FALSE; } if (size%2 == 0 && filter_type != AVERAGE) { size--; asfPrintWarning("Filter kernel must have an odd number of lines and" "samples!\n"); } } // Allocate some memory for the subsets line_count = metaTrg->general->line_count; sample_count = metaTrg->general->sample_count; img = (float *) MALLOC(sizeof(float)*lines*samples); if (filter) filtered_img = (float *) MALLOC(sizeof(float)*lines*samples); // Determine geographic location of subset meta_get_latLon(metaSrc, startY_src, startX_src, 0.0, &lat_UL, &lon_UL); meta_get_latLon(metaSrc, startY_src+lines, startX_src+samples, 0.0, &lat_LR, &lon_LR); meta_get_lineSamp(metaTrg, lat_UL, lon_UL, 0.0, &yLine, &xSample); startX_trg = (int) (xSample + 0.5); startY_trg = (int) (yLine + 0.5); // READ IN SUBSETS // Read target image subset first to determine average brightness asfPrintStatus("\nGenerating subset for target image ...\n"); asfPrintStatus("start line: %d, start sample: %d, lines: %d, samples: %d\n", startY_trg, startX_trg, lines, samples); inFile = appendExt(trgImage, ".img"); sprintf(outFile, "%s_sub.img", trgImage); fp = FOPEN(inFile, "rb"); read_subset(fp, metaTrg, startX_trg, startY_trg, samples, lines, 0.0, &mean, img); FCLOSE(fp); // Compute scale factor mean *= -1; scale = 1.0 / (lines * samples); // Subtract this average off of target image for (y=0; y<lines; y++) { l = samples * y; for (x=0; x<samples; x++) img[l+x] = (img[l+x] + mean) * scale; } if (filter) { asfPrintStatus("\nFiltering target image subset with %s (%dx%d) ...\n", uc(filter_str), size, size); filter_image(img, filtered_img, filter_type, size, lines, samples); } // Update metadata and write target subset to file metaTrg->general->line_count = lines; metaTrg->general->sample_count = samples; metaTrg->general->start_line = startY_trg; metaTrg->general->start_sample = startX_trg; meta_write(metaTrg, outFile); envi = meta2envi(metaTrg); write_envi_header(outFile, outFile, metaTrg, envi); fp = FOPEN(outFile, "wb"); if (filter) put_float_lines(fp, metaTrg, 0, lines, filtered_img); else put_float_lines(fp, metaTrg, 0, lines, img); FCLOSE(fp); // Read source image subset applying for brightness asfPrintStatus("\nGenerating subset for source image ...\n"); asfPrintStatus("start line: %d, start sample: %d, lines: %d, samples: %d\n", startY_src, startX_src, lines, samples); inFile = appendExt(srcImage, ".img"); sprintf(outFile, "%s_sub.img", srcImage); fp = FOPEN(inFile, "rb"); read_subset(fp, metaSrc, startX_src, startY_src, samples, lines, mean, NULL, img); FCLOSE(fp); if (filter) { asfPrintStatus("\nFiltering source image subset with %s (%dx%d) ...\n", uc(filter_str), size, size); filter_image(img, filtered_img, filter_type, size, lines, samples); } // Update metadata and write source subset to file metaSrc->general->line_count = lines; metaSrc->general->sample_count = samples; metaSrc->general->start_line = startY_src; metaSrc->general->start_sample = startX_src; meta_write(metaSrc, outFile); envi = meta2envi(metaSrc); write_envi_header(outFile, outFile, metaSrc, envi); fp = FOPEN(outFile, "wb"); if (filter) put_float_lines(fp, metaSrc, 0, lines, filtered_img); else put_float_lines(fp, metaSrc, 0, lines, img); FCLOSE(fp); // Clean up FREE(img); meta_free(metaSrc); meta_free(metaTrg); // Exporting subsets to GeoTIFF if (geotiff) { output_format_t output_format=GEOTIFF; scale_t sample_mapping=SIGMA; asfPrintStatus("\nExporting source image subset to GeoTIFF ...\n"); sprintf(outFile, "%s_sub", srcImage); asf_export(output_format, sample_mapping, outFile, outFile); asfPrintStatus("\nExporting target image subset to GeoTIFF ...\n"); sprintf(outFile, "%s_sub", trgImage); asf_export(output_format, sample_mapping, outFile, outFile); } return (0); }
int asf_igram_coh(int lookLine, int lookSample, int stepLine, int stepSample, char *masterFile, char *slaveFile, char *outBase, float *average) { char ampFile[255], phaseFile[255]; //, igramFile[512]; char cohFile[512], ml_ampFile[255], ml_phaseFile[255]; //, ml_igramFile[512]; FILE *fpMaster, *fpSlave, *fpAmp, *fpPhase, *fpCoh, *fpAmp_ml, *fpPhase_ml; int line, sample_count, line_count, count; float bin_high, bin_low, max=0.0, sum_a, sum_b, ampScale; double hist_sum=0.0, percent, percent_sum; long long hist_val[HIST_SIZE], hist_cnt=0; meta_parameters *inMeta,*outMeta, *ml_outMeta; complexFloat *master, *slave, *sum_igram, *sum_ml_igram; float *amp, *phase, *sum_cpx_a, *sum_cpx_b, *coh, *pCoh; float *ml_amp, *ml_phase; // FIXME: Processing flow with two-banded interferogram needed - backed out // for now create_name(ampFile, outBase,"_igram_amp.img"); create_name(phaseFile, outBase,"_igram_phase.img"); create_name(ml_ampFile, outBase,"_igram_ml_amp.img"); create_name(ml_phaseFile, outBase,"_igram_ml_phase.img"); //create_name(igramFile, outBase,"_igram.img"); //create_name(ml_igramFile, outBase, "_igram_ml.img"); //sprintf(cohFile, "coherence.img"); create_name(cohFile, outBase, "_coh.img"); // Read input meta file inMeta = meta_read(masterFile); line_count = inMeta->general->line_count; sample_count = inMeta->general->sample_count; ampScale = 1.0/(stepLine*stepSample); // Generate metadata for single-look images outMeta = meta_read(masterFile); outMeta->general->data_type = REAL32; // Write metadata for interferometric amplitude outMeta->general->image_data_type = AMPLITUDE_IMAGE; meta_write(outMeta, ampFile); // Write metadata for interferometric phase outMeta->general->image_data_type = PHASE_IMAGE; meta_write(outMeta, phaseFile); /* // Write metadata for interferogram outMeta->general->image_data_type = INTERFEROGRAM; outMeta->general->band_count = 2; strcpy(outMeta->general->bands, "IGRAM-AMP,IGRAM-PHASE"); meta_write(outMeta, igramFile); */ // Generate metadata for multilooked images ml_outMeta = meta_read(masterFile); ml_outMeta->general->data_type = REAL32; ml_outMeta->general->line_count = line_count/stepLine; ml_outMeta->general->sample_count = sample_count/stepSample; ml_outMeta->general->x_pixel_size *= stepSample; ml_outMeta->general->y_pixel_size *= stepLine; ml_outMeta->sar->multilook = 1; ml_outMeta->sar->line_increment *= stepLine; ml_outMeta->sar->sample_increment *= stepSample; // FIXME: This is the wrong increment but create_dem_grid does not know any // better at the moment. //ml_outMeta->sar->line_increment = 1; //ml_outMeta->sar->sample_increment = 1; // Write metadata for multilooked interferometric amplitude ml_outMeta->general->image_data_type = AMPLITUDE_IMAGE; meta_write(ml_outMeta, ml_ampFile); // Write metadata for multilooked interferometric phase ml_outMeta->general->image_data_type = PHASE_IMAGE; meta_write(ml_outMeta, ml_phaseFile); // Write metadata for coherence image ml_outMeta->general->image_data_type = COHERENCE_IMAGE; meta_write(ml_outMeta, cohFile); /* // Write metadata for multilooked interferogram ml_outMeta->general->image_data_type = INTERFEROGRAM; strcpy(ml_outMeta->general->bands, "IGRAM-AMP,IGRAM-PHASE"); ml_outMeta->general->band_count = 2; meta_write(ml_outMeta, ml_igramFile); */ // Allocate memory master = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count*lookLine); slave = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count*lookLine); amp = (float *) MALLOC(sizeof(float)*sample_count*lookLine); phase = (float *) MALLOC(sizeof(float)*sample_count*lookLine); ml_amp = (float *) MALLOC(sizeof(float)*sample_count/stepSample); ml_phase = (float *) MALLOC(sizeof(float)*sample_count/stepSample); coh = (float *) MALLOC(sizeof(float)*sample_count/stepSample); sum_cpx_a = (float *) MALLOC(sizeof(float)*sample_count); sum_cpx_b = (float *) MALLOC(sizeof(float)*sample_count); sum_igram = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count); sum_ml_igram = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count); // Open files fpMaster = FOPEN(masterFile,"rb"); fpSlave = FOPEN(slaveFile,"rb"); fpAmp = FOPEN(ampFile,"wb"); fpPhase = FOPEN(phaseFile,"wb"); fpAmp_ml = FOPEN(ml_ampFile,"wb"); fpPhase_ml = FOPEN(ml_phaseFile,"wb"); //FILE *fpIgram = FOPEN(igramFile, "wb"); //FILE *fpIgram_ml = FOPEN(ml_igramFile, "wb"); fpCoh = FOPEN(cohFile,"wb"); // Initialize histogram for (count=0; count<HIST_SIZE; count++) hist_val[count] = 0; asfPrintStatus(" Calculating interferogram and coherence ...\n\n"); for (line=0; line<line_count; line+=stepLine) { register int offset, row, column, limitLine; double igram_real, igram_imag; int inCol; limitLine=MIN(lookLine, line_count-line); printf("Percent completed %3.0f\r",(float)line/line_count*100.0); pCoh = coh; // Read in the next lines of data get_complexFloat_lines(fpMaster, inMeta, line, limitLine, master); get_complexFloat_lines(fpSlave, inMeta, line, limitLine, slave); // Add the remaining rows into sum vectors offset = sample_count; for (column=0; column<sample_count; column++) { offset = column; sum_cpx_a[column] = 0.0; sum_cpx_b[column] = 0.0; sum_igram[column].real = 0.0; sum_igram[column].imag = 0.0; sum_ml_igram[column].real = 0.0; sum_ml_igram[column].imag = 0.0; igram_real = 0.0; igram_imag = 0.0; for (row=0; row<limitLine; row++) { // Complex multiplication for interferogram generation igram_real = master[offset].real*slave[offset].real + master[offset].imag*slave[offset].imag; igram_imag = master[offset].imag*slave[offset].real - master[offset].real*slave[offset].imag; amp[offset] = sqrt(igram_real*igram_real + igram_imag*igram_imag); if (FLOAT_EQUIVALENT(igram_real, 0.0) || FLOAT_EQUIVALENT(igram_imag, 0.0)) phase[offset]=0.0; else phase[offset] = atan2(igram_imag, igram_real); sum_cpx_a[column] += AMP(master[offset])*AMP(master[offset]); sum_cpx_b[column] += AMP(slave[offset])*AMP(slave[offset]); sum_igram[column].real += igram_real; sum_igram[column].imag += igram_imag; if (line % stepLine == 0 && row < stepLine) { sum_ml_igram[column].real += igram_real; sum_ml_igram[column].imag += igram_imag; } offset += sample_count; } ml_amp[column] = sqrt(sum_ml_igram[column].real*sum_ml_igram[column].real + sum_ml_igram[column].imag*sum_ml_igram[column].imag)*ampScale; if (FLOAT_EQUIVALENT(sum_ml_igram[column].real, 0.0) || FLOAT_EQUIVALENT(sum_ml_igram[column].imag, 0.0)) ml_phase[column] = 0.0; else ml_phase[column] = atan2(sum_ml_igram[column].imag, sum_ml_igram[column].real); } // Write single-look and multilooked amplitude and phase put_float_lines(fpAmp, outMeta, line, stepLine, amp); put_float_lines(fpPhase, outMeta, line, stepLine, phase); put_float_line(fpAmp_ml, ml_outMeta, line/stepLine, ml_amp); put_float_line(fpPhase_ml, ml_outMeta, line/stepLine, ml_phase); //put_band_float_lines(fpIgram, outMeta, 0, line, stepLine, amp); //put_band_float_lines(fpIgram, outMeta, 1, line, stepLine, phase); //put_band_float_line(fpIgram_ml, ml_outMeta, 0, line/stepLine, ml_amp); //put_band_float_line(fpIgram_ml, ml_outMeta, 1, line/stepLine, ml_phase); // Calculate the coherence by adding from sum vectors for (inCol=0; inCol<sample_count; inCol+=stepSample) { register int limitSample = MIN(lookSample,sample_count-inCol); sum_a = 0.0; sum_b = 0.0; igram_real = 0.0; igram_imag = 0.0; // Step over multilook area and sum output columns for (column=0; column<limitSample; column++) { igram_real += sum_igram[inCol+column].real; igram_imag += sum_igram[inCol+column].imag; sum_a += sum_cpx_a[inCol+column]; sum_b += sum_cpx_b[inCol+column]; } if (FLOAT_EQUIVALENT((sum_a*sum_b), 0.0)) *pCoh = 0.0; else { *pCoh = (float) sqrt(igram_real*igram_real + igram_imag*igram_imag) / sqrt(sum_a * sum_b); if (*pCoh>1.0001) { printf(" coh = %f -- setting to 1.0\n",*pCoh); printf(" You shouldn't have seen this!\n"); printf(" Exiting.\n"); exit(EXIT_FAILURE); *pCoh=1.0; } } pCoh++; } // Write out values for coherence put_float_line(fpCoh, ml_outMeta, line/stepLine, coh); // Keep filling coherence histogram for (count=0; count<sample_count/stepSample; count++) { register int tmp; tmp = (int) (coh[count]*HIST_SIZE); /* Figure out which bin this value is in */ /* This shouldn't happen */ if(tmp >= HIST_SIZE) tmp = HIST_SIZE-1; if(tmp < 0) tmp = 0; hist_val[tmp]++; // Increment that bin for the histogram hist_sum += coh[count]; // Add up the values for the sum hist_cnt++; // Keep track of the total number of values if (coh[count]>max) max = coh[count]; // Calculate maximum coherence } } // End for line printf("Percent completed %3.0f\n",(float)line/line_count*100.0); // Sum and print the statistics percent_sum = 0.0; printf(" Coherence : Occurrences : Percent\n"); printf(" ---------------------------------------\n"); for (count=0; count<HIST_SIZE; count++) { bin_low = (float)(count)/(float)HIST_SIZE; bin_high = (float)(count+1)/(float)HIST_SIZE; percent = (double)hist_val[count]/(double)hist_cnt; percent_sum += (float)100*percent; printf(" %.2f -> %.2f : %.8lld %2.3f \n", bin_low,bin_high, (long long) hist_val[count],100*percent); } *average = (float)hist_sum/(float)hist_cnt; printf(" ---------------------------------------\n"); printf(" Maximum Coherence: %.3f\n", max); printf(" Average Coherence: %.3f (%.1f / %lld) %f\n", *average,hist_sum, hist_cnt, percent_sum); // Free and exit FREE(master); FREE(slave); FREE(amp); FREE(phase); FREE(ml_amp); FREE(ml_phase); FREE(coh); FCLOSE(fpMaster); FCLOSE(fpSlave); FCLOSE(fpAmp); FCLOSE(fpPhase); FCLOSE(fpAmp_ml); FCLOSE(fpPhase_ml); //FCLOSE(fpIgram); //FCLOSE(fpIgram_ml); FCLOSE(fpCoh); meta_free(inMeta); meta_free(outMeta); meta_free(ml_outMeta); return(0); }
int geoid_adjust(const char *input_filename, const char *output_filename) { char *input_img = appendExt(input_filename, ".img"); char *input_meta = appendExt(input_filename, ".meta"); char *output_img = appendExt(output_filename, ".img"); char *output_meta = appendExt(output_filename, ".meta"); if (!fileExists(input_img)) asfPrintError("File not found: %s\n", input_img); if (!fileExists(input_meta)) asfPrintError("File not found: %s\n", input_meta); meta_parameters *meta = meta_read(input_meta); int nl = meta->general->line_count; int ns = meta->general->sample_count; int ii, jj; FILE *fpIn = FOPEN(input_img, "rb"); FILE *fpOut = FOPEN(output_img, "wb"); float *buf; // Two ways we can do this: // 1) call meta_get_latLon at every point // 2) call meta_get_latLon at certain points and interpolate between // We will use the first when we have a lat/lon image, and the second for // everything else. int latlon_image = meta->projection && meta->projection->type == LAT_LONG_PSEUDO_PROJECTION; double avg = 0.0; int num=0; asfPrintStatus("Performing geoid correction.\n"); asfPrintStatus(" Input file: %s\n", input_filename); asfPrintStatus(" Output file: %s\n", output_filename); if (latlon_image) { asfPrintStatus("Lat/Lon image, not using mapping interpolation.\n"); buf = MALLOC(sizeof(float)*ns); for (ii=0; ii<nl; ++ii) { get_float_line(fpIn, meta, ii, buf); for (jj=0; jj<ns; ++jj) { double lat, lon; meta_get_latLon(meta, ii, jj, 0, &lat, &lon); if (buf[jj] > -900 && buf[jj] != meta->general->no_data) { float ht = get_geoid_height(lat,lon); buf[jj] += ht; avg += ht; ++num; } } put_float_line(fpOut, meta, ii, buf); asfLineMeter(ii,nl); } } else { asfPrintStatus("Not a Lat/Lon image, using mapping interpolation.\n"); double tol = .0001; int size = find_grid_size(meta, 512, .1*tol); int test_mode = 1; buf = MALLOC(sizeof(float)*ns*size); // these are for tracking the quality of the bilinear interp // not used if test_mode is false int num_out_of_tol = 0; int num_checked = 0; int num_bad = 0; double max_err = 0; double avg_err = 0; for (ii=0; ii<nl; ii += size) { int line_lo = ii; int line_hi = ii + size; if (ii+size >= nl) size = nl-ii; get_float_lines(fpIn, meta, ii, size, buf); for (jj=0; jj<ns; jj += size) { double lats[4], lons[4]; int samp_lo = jj; int samp_hi = jj + size; get_interp_params(meta, line_lo, line_hi, samp_lo, samp_hi, lats, lons); int iii, jjj; for (iii=0; iii<size; ++iii) { for (jjj=0; jjj<size && jj+jjj<ns; ++jjj) { int kkk = iii*ns + jj + jjj; assert(kkk < ns*size); double lat, lon; xy_interp(ii+iii, jj+jjj, line_lo, line_hi, samp_lo, samp_hi, lats, lons, &lat, &lon); // random checking of the quality of our interpolations if (test_mode && iii%11==0 && jjj%13==0) { double real_lat, real_lon; img_to_latlon(meta, ii+iii, jj+jjj, &real_lat, &real_lon); double err = hypot(real_lat - lat, real_lon - lon); avg_err += err; if (err > max_err) max_err = err; if (err > .1*tol) { asfPrintStatus("Out of tolerance at %d,%d: (%f,%f) vs (%f,%f) -> %f\n", ii+iii, jj+jjj, lat, lon, real_lat, real_lon, err); ++num_out_of_tol; } if (err > tol) { asfPrintStatus("Error is larger than %f!\n", .01*tol); ++num_bad; } ++num_checked; } if (buf[kkk] > -900 && buf[kkk] != meta->general->no_data) { float ht = get_geoid_height(lat,lon); buf[kkk] += ht; avg += ht; ++num; } } } } put_float_lines(fpOut, meta, ii, size, buf); asfPrintStatus("Completed %.1f%% \r", 100.*ii/(double)nl); } asfPrintStatus("Completed 100%% \n"); } avg /= (double)(num); asfPrintStatus("Average correction: %f\n", avg); meta_write(meta, output_meta); meta_free(meta); FCLOSE(fpIn); FCLOSE(fpOut); FREE(buf); FREE(input_img); FREE(input_meta); FREE(output_img); FREE(output_meta); // success return 0; }