Beispiel #1
0
void calc_minmax_polsarpro(const char *inFile, double *min, double *max)
{
  int ii,jj;
  
  *min = 999999;
  *max = -999999;
  
  char *enviName = (char *) MALLOC(sizeof(char)*(strlen(inFile) + 10));
  sprintf(enviName, "%s.hdr", inFile);
  envi_header *envi = read_envi(enviName);
  meta_parameters *meta = envi2meta(envi);
  float *data = MALLOC(sizeof(float) * meta->general->sample_count);
  
  FILE *fp = FOPEN(inFile, "rb");
  asfPrintStatus("\nCalculating min and max ...\n");
  for (ii=0; ii<meta->general->line_count; ++ii) {
    asfPercentMeter(((double)ii/(double)meta->general->line_count));
    get_float_line(fp, meta, ii, data);
    
    for (jj=0; jj<meta->general->sample_count; ++jj) {
      ieee_big32(data[jj]);
      if (data[jj] < *min) *min = data[jj];
      if (data[jj] > *max) *max = data[jj];
    }
  }
  asfPercentMeter(1.0);
  FCLOSE(fp);
  FREE(data);
  meta_free(meta);
  FREE(envi);
  FREE(enviName);
}
Beispiel #2
0
/* Calculate minimum, maximum, mean and standard deviation for a floating point
   image. A mask value can be defined that is excluded from this calculation.
   If no mask value is supposed to be used, pass the mask value as NAN. */
void calc_stats(float *data, long long pixel_count, double mask, double *min,
        double *max, double *mean, double *stdDev)
{
    long long ii, pix;

    /* Initialize values */
    *min = 99999;
    *max = -99999;
    *mean = 0.0;
    *stdDev = 0.0;
    pix = 0;

    asfPrintStatus("\nFinding min, max, and mean...\n");
    for (ii=0; ii<pixel_count; ii++) {
        asfPercentMeter(((double)ii/(double)pixel_count));
        if (!ISNAN(mask)) {
            if (data[ii] < *min && !FLOAT_EQUIVALENT(data[ii], mask))
                *min = data[ii];
            if (data[ii] > *max && !FLOAT_EQUIVALENT(data[ii], mask))
                *max = data[ii];
            if (!FLOAT_EQUIVALENT(data[ii], mask)) {
                *mean += data[ii];
                pix++;
            }
        }
        else {
            if (data[ii] < *min) *min = data[ii];
            if (data[ii] > *max) *max = data[ii];
            *mean += data[ii];
            ++pix;
        }
    }
    asfPercentMeter(1.0);
    *mean /= pix;

    asfPrintStatus("\nCalculating standard deviation...\n");
    for (ii=0; ii<pixel_count; ii++) {
        asfPercentMeter(((double)ii/(double)pixel_count));
        if (!ISNAN(mask)) {
            if (!FLOAT_EQUIVALENT(data[ii], mask))
                *stdDev += (data[ii] - *mean) * (data[ii] - *mean);
        }
        else
            *stdDev += (data[ii] - *mean) * (data[ii] - *mean);
    }
    *stdDev = sqrt(*stdDev/(pix - 1));
    asfPercentMeter(1.0);

    return;
}
Beispiel #3
0
int get_terrasar_thumbnail_data(int thumb_size_x, int thumb_size_y,
                              meta_parameters *meta, void *read_client_info,
                              void *dest_void, int data_type)
{
  ReadTerrasarClientInfo *info = (ReadTerrasarClientInfo*) read_client_info;
  
  int ii, jj;
  int ns = meta->general->sample_count;
  int sf = meta->general->line_count / thumb_size_y;
  
  if (info->multilook)
    sf *= meta->sar->look_count;
  
  float *dest = (float*)dest_void;

  // Read in the image
  short int *shorts = MALLOC(sizeof(short int)*ns*2);
  for (ii=0; ii<thumb_size_y; ii++) {
    int line = ii*sf;
    long long offset = (long long) (info->header + line*info->width);
    FSEEK(info->fp, offset, SEEK_SET);
    FREAD(shorts, sizeof(short int), ns*2, info->fp);
    for (jj=0; jj<thumb_size_x; jj++)
      dest[jj + ii*thumb_size_x] = hypot(shorts[jj*sf*2], shorts[jj*sf*2+1]);
    asfPercentMeter((float)ii/(thumb_size_y - 1));
  }
  free(shorts);
  
  return TRUE;
}
Beispiel #4
0
int get_uavsar_thumbnail_data(int thumb_size_x, int thumb_size_y,
                              meta_parameters *meta, void *read_client_info,
                              void *dest_void, int data_type)
{
    ReadUavsarClientInfo *info = (ReadUavsarClientInfo*) read_client_info;

    int i, j;

    int sf = meta->general->line_count / thumb_size_y;
    int ns = meta->general->sample_count;

    // temporary storage
    float *buf = MALLOC(sizeof(float)*ns);

    if (meta->general->data_type == ASF_BYTE) {
        unsigned char *dest = (unsigned char*)dest_void;
        if (data_type == GREYSCALE_BYTE) {
            for (i=0; i<thumb_size_y; ++i) {
                get_uavsar_line(info, meta, i*sf, buf);
                for (j=0; j<thumb_size_x; ++j)
                    dest[i*thumb_size_x+j] = (unsigned char)(buf[j*sf]);
                asfPercentMeter((float)i/(thumb_size_y-1));
            }
        }
        else {
            assert(FALSE);
        }
    } else {
        float *dest = (float*)dest_void;
        if (data_type == GREYSCALE_FLOAT) {
            for (i=0; i<thumb_size_y; ++i) {
                get_uavsar_line(info, meta, i*sf, buf);
                for (j=0; j<thumb_size_x; ++j)
                    dest[i*thumb_size_x+j] = buf[j*sf];
                asfPercentMeter((float)i/(thumb_size_y-1));
            }
        } else {
            assert(FALSE);
        }
    }

    free(buf);
    return TRUE;
}
Beispiel #5
0
int get_asf_thumbnail_data(int thumb_size_x, int thumb_size_y,
                           meta_parameters *meta, void *read_client_info,
                           void *dest_void, int data_type)
{
    ReadAsfClientInfo *info = (ReadAsfClientInfo*) read_client_info;

    int sf = meta->general->line_count / thumb_size_y;
    //assert(sf==meta->general->sample_count / thumb_size_x);
    int i,j;

    int nl = meta->general->line_count;
    int ns = meta->general->sample_count;

    // temporary storage
    float *buf = MALLOC(sizeof(float)*ns);

    if (meta->general->data_type == ASF_BYTE) {
        // BYTE case -- data file contains bytes.
        unsigned char *dest = (unsigned char*)dest_void;
        if (data_type == GREYSCALE_BYTE) {
            // data file contains byte data, and we are just pulling out
            // one band to display.
            int off = nl*info->band_gs;
            for (i=0; i<thumb_size_y; ++i) {
                get_asf_line(info, meta, i*sf + off, buf);
                for (j=0; j<thumb_size_x; ++j)
                    dest[i*thumb_size_x+j] = (unsigned char)(buf[j*sf]);
                asfPercentMeter((float)i/(thumb_size_y-1));
            }
        }
        else {
            // rgb case -- we have to read up to 3 bands from the file,
            // and put them together
            assert(data_type == RGB_BYTE);
            int off, k;

            // first set dest buffer to all zeros.  This way, any bands that
            // aren't set up will just come out black
            memset(dest, 0, 3*thumb_size_x*thumb_size_y);

            // "tot" is to help with the PercentMeter -- the total number
            // of lines that we will need to read.  "l" is the counter
            int tot = (info->band_r>=0) + (info->band_g>=0) + (info->band_b>=0);
            tot *= thumb_size_y;
            int l=0;

            // to do each of the bands, we read the data into a float array,
            // then cast (back) to byte into the interleaved "dest" array
            // (interleaved in the sense that we only populate every 3rd item
            // each time through)

            // red band
            if (info->band_r >= 0) {
                off = nl*info->band_r;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x; // starting point in dest array
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = (unsigned char)(buf[j*sf]);
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            // green band
            if (info->band_g >= 0) {
                off = nl*info->band_g;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x+1;
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = (unsigned char)(buf[j*sf]);
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            // blue band
            if (info->band_b >= 0) {
                off = nl*info->band_b;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x+2;
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = (unsigned char)(buf[j*sf]);
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            //assert(l==tot);
            if (l!=tot) printf("These are supposed to be equal: %d %d\n",
                l, tot);
        }
    } else {
        // this is the normal case -- regular old floating point data,
        // we just read with get_float_line and populate directly into
        // a floating point array
        float *dest = (float*)dest_void;
        if (data_type == GREYSCALE_FLOAT) {
            int off = nl*info->band_gs;
            for (i=0; i<thumb_size_y; ++i) {
                get_asf_line(info, meta, i*sf + off, buf);
                for (j=0; j<thumb_size_x; ++j)
                    dest[i*thumb_size_x+j] = buf[j*sf];
                asfPercentMeter((float)i/(thumb_size_y-1));
            }
        } else if (data_type == RGB_FLOAT) {
            int off, k;

            // first set dest buffer to all zeros.  This way, any bands that
            // aren't set up will just come out black.
            memset(dest, 0, 3*sizeof(float)*thumb_size_x*thumb_size_y);

            // "tot" is to help with the PercentMeter -- the total number
            // of lines that we will need to read.  "l" is the counter
            int tot = (info->band_r>=0) + (info->band_g>=0) + (info->band_b>=0);
            tot *= thumb_size_y;
            int l=0;

            // to do each of the bands, we read the data into a float array,
            // then cast (back) to byte into the interleaved "dest" array
            // (interleaved in the sense that we only populate every 3rd item
            // each time through)

            // red band
            if (info->band_r >= 0) {
                off = nl*info->band_r;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x; // starting point in dest array
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = buf[j*sf];
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            // green band
            if (info->band_g >= 0) {
                off = nl*info->band_g;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x+1;
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = buf[j*sf];
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            // blue band
            if (info->band_b >= 0) {
                off = nl*info->band_b;
                for (i=0; i<thumb_size_y; ++i) {
                    k=3*i*thumb_size_x+2;
                    get_asf_line(info, meta, i*sf + off, buf);
                    for (j=0; j<thumb_size_x; ++j, k += 3)
                        dest[k] = buf[j*sf];
                    asfPercentMeter((float)(l++)/(tot-1));
                }
            }

            //assert(l==tot);
            if (l!=tot) printf("These are supposed to be equal: %d %d\n",
                l, tot);
        } else {
            assert(FALSE);
        }
    }

    free(buf);
    return TRUE;
}
Beispiel #6
0
/* Create histogram of the data and get the summation of the
 * square of (sample-mean) to use in calculation of rmse & stdev */
stat_parameters calc_hist(stat_parameters stats, char *sar_name, int band, meta_parameters *meta,
                          double sum_of_samples, long samples_counted, int mask_flag)
{
  FILE   *fp;
  long   start_line, start_sample, window_height, window_width;
  long   percent_complete, line, sample, ii, band_offset;
  double diff_squared_sum=0.0;
  float  *data_line;

  start_line = stats.upper_left_line;
  start_sample = stats.upper_left_samp;
  window_height = stats.lower_right_line - start_line;
  window_width = stats.lower_right_samp - start_sample;

  data_line = (float *)MALLOC(sizeof(float)*meta->general->sample_count);
  fp = FOPEN(sar_name, "r");

  /* Initialize the histogram array */
  for (ii=0; ii<256; ii++) stats.histogram[ii] = 0;

  if (meta->general->data_type != ASF_BYTE) {
    /* Set slope and offset, to map pixels to [0..255].
     * byte = slope * in + offset
     * 0    = slope * min + offset
     * 255  = slope * max + offset
     * Therefore: */
    stats.slope = 255.0 / (stats.max-stats.min);
    stats.offset = -stats.slope * stats.min;
  }

  /* Get histogram of the data.  If its byte data just slap it into the
   * histogram; otherwise use slope & offset to scale the data */
  stats.mean = sum_of_samples / (double)samples_counted;
  percent_complete=0;
  band_offset = band * meta->general->line_count;
  for (line=start_line+band_offset; line<start_line+window_height+band_offset; line++) {
    if (!quietflag) asfPercentMeter((float)(line-start_line-band_offset)/(float)(window_height-start_line));
    get_float_line(fp, meta, line, data_line);
    for (sample=start_sample; sample<start_sample+window_width; sample++) {
      int bin = (meta->general->data_type == ASF_BYTE)
        ? (int)data_line[sample]
        : (int)(stats.slope*data_line[sample]+stats.offset);
      if (bin < 0) bin = 0;
      else if (bin > 255) bin = 255;
      if ( mask_flag && FLOAT_EQUIVALENT(data_line[sample],stats.mask) )
        continue;
      stats.histogram[bin]++;
      diff_squared_sum += SQR(data_line[sample] - stats.mean);
    }
  }
  if (!quietflag) asfPercentMeter(1.0);

  FREE(data_line);
  FCLOSE(fp);

/* Populate stats structure */
  stats.rmse =
    sqrt( fabs( diff_squared_sum / (double)samples_counted ) );
  stats.std_deviation =
    sqrt( fabs( diff_squared_sum / (double)(samples_counted-1) ) );

  return stats;
}
Beispiel #7
0
int main(int argc, char **argv)
{
  double min, max;             /* Minimum & maximum sample values       */
  double sum_of_samples=0.0;   /* Sum of all samples accounted for      */
  double sum_of_squared_samples=0.0; /* Sum of all squared samples accounted for*/
  double trim_fraction;        /* Fraction used to trim the histogram   */
  int ii;                      /* Loop index                            */
  long samples_counted=0;      /* Number of all samples accounted for   */
  float *data_line;           /* Buffer for a line of samples          */
  long line, sample;            /* Line and sample indices               */
  long num_lines, num_samples;  /* Number of lines and samples           */
  int percent_complete=0;      /* Percent of data sweep completed       */
  int overmeta_flag=FALSE;     /* If TRUE write over current .meta file */
  int overstat_flag=FALSE;     /* If TRUE write over current .stat file */
  int nometa_flag=FALSE;       /* If TRUE do not write .meta file       */
  int nostat_flag=FALSE;       /* If TRUE do not write .stat file       */
  int mask_flag=FALSE;         /* TRUE if user specifies a mask value   */
  int trim_flag=FALSE;         /* If TRUE trim histogram                */
  double mask=NAN;             /* Value to ignore while caculating stats*/
  char meta_name[261];         /* Meta file name                        */
  meta_parameters *meta;       /* SAR meta data structure               */
  char sar_name[256];          /* SAR file name WITH extention          */
  FILE *sar_file;              /* SAR data file pointer to take stats on*/
  stat_parameters *stats;      /* Statistics structure                  */
  char stat_name[261];         /* Stats file name                       */
  extern int currArg;          /* Pre-initialized to 1                  */

  /* We initialize these to a magic number for checking. */
  long start_line = -1;         /* Window starting line.                 */
  long start_sample = -1;       /* Window starting sample.               */
  long window_height = -1;      /* Window height in lines.               */
  long window_width = -1;       /* Window width in samples.              */

/* parse command line */
  handle_license_and_version_args(argc, argv, "stats");
  logflag=quietflag=FALSE;
  while (currArg < (argc-1)) {
    char *key = argv[currArg++];
    if (strmatch(key,"-quiet")) {
      quietflag=TRUE;
    }
    else if (strmatch(key,"-log")) {
      CHECK_ARG(1);
      strcpy(logFile,GET_ARG(1));
      fLog = FOPEN(logFile, "a");
      logflag=TRUE;
    }
    else if (strmatch(key,"-mask")) {
      CHECK_ARG(1);
      mask = atof(GET_ARG(1));
      mask_flag=TRUE;
    }
    else if (strmatch(key,"-overmeta")) {
      overmeta_flag=TRUE;
    }
    else if (strmatch(key,"-overstat")) {
      overstat_flag=TRUE;
    }
    else if (strmatch(key,"-nometa")) {
      nometa_flag=TRUE;
    }
    else if (strmatch(key,"-nostat")) {
      nostat_flag=TRUE;
    }
    else if (strmatch(key,"-startline")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      start_line = atol(GET_ARG(1));
      if ( start_line < 0 ) {
        printf("error: -startline argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-startsample")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      start_sample = atol(GET_ARG(1));
      if ( start_sample < 0 ) {
        printf("error: -startsample argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-width")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      window_width = atol(GET_ARG(1));
      if ( window_width < 0 ) {
        printf("error: -width argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-height")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      window_height = atol(GET_ARG(1));
      if ( window_height < 0 ) {
        printf("error: -height argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-trim")) {
      CHECK_ARG(1);
      trim_flag=TRUE; /* Implied.  */
      trim_fraction = atof(GET_ARG(1));
    }
    else {printf( "\n**Invalid option:  %s\n",argv[currArg-1]); usage(argv[0]);}
  }

  if ((argc-currArg)<1) {printf("Insufficient arguments.\n"); usage(argv[0]);}
  strcpy (sar_name, argv[currArg]);
  char *ext = findExt(sar_name);
  if (ext == NULL || strcmp("IMG", uc(ext)) != 0) {
    strcpy(sar_name, appendExt(sar_name, ".img"));
  }
  create_name(meta_name, sar_name, ".meta");
  create_name(stat_name, sar_name, ".stat");

  printf("\nProgram: stats\n\n");
  if (logflag) {
    fprintf(fLog, "\nProgram: stats\n\n");
  }
  printf("\nCalculating statistics for %s\n\n", sar_name);
  if (logflag) {
    fprintf(fLog,"\nCalculating statistics for %s\n\n", sar_name);
  }
  meta = meta_read(meta_name);
  num_lines = meta->general->line_count;
  num_samples = meta->general->sample_count;

  if ( start_line == -1 ) start_line = 0;
  if ( start_line > num_lines ) {
    printf("error: -startline argument is larger than index of last line in image\n");
    exit(EXIT_FAILURE);
  }
  if ( start_sample == -1 ) start_sample = 0;
  if ( start_sample > num_samples ) {
    printf("error: -startsample argument is larger than index of last sample in image\n");
    exit(EXIT_FAILURE);
  }
  if ( window_height == -1 ) window_height = num_lines;
  if ( start_line + window_height > num_lines ) {
    printf("warning: window specified with -startline, -height options doesn't fit in image\n");
  }
  if ( window_width == -1 ) window_width = num_samples;
  if ( start_sample + window_width > num_samples ) {
    printf("warning: window specified with -startsample, -width options doesn't fit in image\n");
  }

/* Make sure we don't over write any files that we don't want to */
  if (meta->stats && !overmeta_flag && !nometa_flag) {
    printf(" ** The meta file already has a populated statistics structure.\n"
           " ** If you want to run this program and replace that structure,\n"
           " ** then use the -overmeta option to do so. If you want to run\n"
           " ** this program, but don't want to replace the structure, use\n"
           " ** the -nometa option.\n");
    if (logflag) {
      fprintf(fLog,
      " ** The meta file already has a populated statistics structure.\n"
      " ** If you want to run this program and replace that structure,\n"
      " ** then use the -overmeta option to do so. If you want to run\n"
      " ** this program, but don't want to replace the structure, use\n"
      " ** the -nometa option.\n");
    }
    exit(EXIT_FAILURE);
  }
  if (fileExists(stat_name) && !overstat_flag && !nostat_flag) {
    printf(" ** The file, %s, already exists. If you want to\n"
           " ** overwrite it, then use the -overstat option to do so.\n"
           " ** If you want to run the progam but don't want to write\n"
           " ** over the current file, then use the -nostat option.\n",
           stat_name);
    if (logflag) {
      fprintf(fLog,
      " ** The file, %s, already exists. If you want to\n"
      " ** overwrite it, then use the -overstat option to do so.\n"
      " ** If you want to run the progam but don't want to write\n"
      " ** over the current file, then use the -nostat option.\n",
      stat_name);
    }
    exit(EXIT_FAILURE);
  }

/* Let user know the window in which the stats will be taken */
  if ((start_line!=0) || (start_sample!=0)
      || (window_height!=num_lines) || (window_width!=num_samples)) {
        if (!quietflag) {
      printf("Taking statistics on a window with upper left corner (%ld,%ld)\n"
      "  and lower right corner (%ld,%ld)\n",
      start_sample, start_line,
      window_width+start_sample, window_height+start_line);
    }
    if (logflag && !quietflag) {
      fprintf(fLog,
        "Taking statistics on a window with upper left corner (%ld,%ld)\n"
      "  and lower right corner (%ld,%ld)\n",
      start_sample, start_line,
      window_width+start_sample, window_height+start_line);
    }

  }

/* Allocate line buffer */
  data_line = (float *)MALLOC(sizeof(float)*num_samples);
  if (meta->stats) FREE(meta->stats);
  if (meta->general->band_count <= 0) {
    printf(" ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n");
    if (logflag) {
      fprintf(fLog, " ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n");
    }
    meta->general->band_count = 1;
  }
  meta->stats = meta_statistics_init(meta->general->band_count);
  if (!meta->stats) {
    printf(" ** Cannot allocate memory for statistics data structures.\n");
    if (logflag) {
      fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n");
    }
    exit(EXIT_FAILURE);
  }
  stats = (stat_parameters *)MALLOC(sizeof(stat_parameters) * meta->stats->band_count);
  if (!stats) {
    printf(" ** Cannot allocate memory for statistics data structures.\n");
    if (logflag) {
      fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n");
    }
    exit(EXIT_FAILURE);
  }

  int  band;
  long band_offset;
  for (band = 0; band < meta->stats->band_count; band++) {
    /* Find min, max, and mean values */
    if (!quietflag) printf("\n");
    if (logflag && !quietflag) fprintf(fLog,"\n");
    min = 100000000;
    max = -100000000;
    sum_of_samples=0.0;
    sum_of_squared_samples=0.0;
    percent_complete=0;
    band_offset = band * meta->general->line_count;
    sar_file = FOPEN(sar_name, "r");
    for (line=start_line+band_offset; line<start_line+window_height+band_offset; line++) {
      if (!quietflag) asfPercentMeter((float)(line-start_line-band_offset)/(float)(window_height-start_line));
      get_float_line(sar_file, meta, line, data_line);
      for (sample=start_sample; sample<start_sample+window_width; sample++) {
        if ( mask_flag && FLOAT_EQUIVALENT(data_line[sample],mask) )
          continue;
        if (data_line[sample] < min) min=data_line[sample];
        if (data_line[sample] > max) max=data_line[sample];
        sum_of_samples += data_line[sample];
        sum_of_squared_samples += SQR(data_line[sample]);
        samples_counted++;
      }
    }
    if (!quietflag) asfPercentMeter(1.0);
//    if (!quietflag) printf("\rFirst data sweep: 100%% complete.\n");
    FCLOSE(sar_file);

    stats[band].min = min;
    stats[band].max = max;
    stats[band].upper_left_line = start_line;
    stats[band].upper_left_samp = start_sample;
    stats[band].lower_right_line = start_line + window_height;
    stats[band].lower_right_samp = start_sample + window_width;
    stats[band].mask = mask;

    stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples,
                      samples_counted, mask_flag);


  /* Remove outliers and trim the histogram by resetting the minimum and
    and maximum */
    if (trim_flag) {
      register int sum=0, num_pixels, minDex=0, maxDex=255;
      double overshoot, width;

      num_pixels = (int)(samples_counted*trim_fraction);
      minDex = 0;
      while (sum < num_pixels)
        sum += stats[band].histogram[minDex++];
      if (minDex-1>=0)
        overshoot = (double)(num_pixels-sum)/stats[band].histogram[minDex-1];
      else
        overshoot = 0;
      stats[band].min = (minDex-overshoot-stats[band].offset)/stats[band].slope;

      sum=0;
      while (sum < num_pixels)
        sum += stats[band].histogram[maxDex--];
      if (maxDex+1<256)
        overshoot = (double)(num_pixels-sum)/stats[band].histogram[maxDex+1];
      else
        overshoot = 0;
      stats[band].max = (maxDex+1+overshoot-stats[band].offset)/stats[band].slope;

      /* Widening the range for better visual effect */
      width = (stats[band].max-stats[band].min)*(1/(1.0-2*trim_fraction)-1);
      stats[band].min -= width/2;
      stats[band].max += width/2;

      /* Couple useful corrections borrowed from SARview */
      if ((stats[band].max-stats[band].min) < 0.01*(max-min)) {
        stats[band].max = max;
        stats[band].min = min;
      }
      if (min == 0.0)
        stats[band].min=0.0;
      if (stats[band].min == stats[band].max)
        stats[band].max = stats[band].min + MICRON;

      stats[band].slope = 255.0/(stats[band].max-stats[band].min);
      stats[band].offset = -stats[band].slope*stats[band].min;

      stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples,
                        samples_counted, mask_flag);
    }
  }
  if(data_line)FREE(data_line);

  /* Populate meta->stats structure */
  char **band_names = NULL;
  if (meta_is_valid_string(meta->general->bands) &&
      strlen(meta->general->bands)               &&
      meta->general->band_count > 0)
  {
    band_names = extract_band_names(meta->general->bands, meta->general->band_count);
  }
  else {
    if (meta->general->band_count <= 0) meta->general->band_count = 1;
    band_names = (char **) MALLOC (meta->general->band_count * sizeof(char *));
    int i;
    for (i=0; i<meta->general->band_count; i++) {
      band_names[i] = (char *) MALLOC (64 * sizeof(char));
      sprintf(band_names[i], "%02d", i);
    }
  }
  int band_no;
  for (band_no = 0; band_no < meta->stats->band_count; band_no++) {
    strcpy(meta->stats->band_stats[band_no].band_id, band_names[band_no]);
    meta->stats->band_stats[band_no].min = stats[band_no].min;
    meta->stats->band_stats[band_no].max = stats[band_no].max;
    meta->stats->band_stats[band_no].mean = stats[band_no].mean;
    meta->stats->band_stats[band_no].rmse = stats[band_no].rmse;
    meta->stats->band_stats[band_no].std_deviation = stats[band_no].std_deviation;
    meta->stats->band_stats[band_no].mask = stats[band_no].mask;
  }
  if (band_names) {
    int i;
    for (i=0; i<meta->general->band_count; i++) {
      if (band_names[i]) FREE (band_names[i]);
    }
    FREE(band_names);
  }

/* Print findings to the screen (and log file if applicable)*/
  if (!quietflag) {
    printf("\n");
    printf("Statistics found:\n");
    if (mask_flag)
      { printf("Used mask %-16.11g\n",mask); }
    printf("Number of bands: %d\n", meta->stats->band_count);
    for (band=0; band<meta->stats->band_count; band++) {
      printf("\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id);
      printf("Minimum = %-16.11g\n",stats[band].min);
      printf("Maximum = %-16.11g\n",stats[band].max);
      printf("Mean = %-16.11g\n",stats[band].mean);
      printf("Root mean squared error = %-16.11g\n",
            stats[band].rmse);
      printf("Standard deviation = %-16.11g\n",
            stats[band].std_deviation);
      printf("\n");
      printf("Data fit to [0..255] using equation:  byte = %g * sample + %g\n",
            stats[band].slope, stats[band].offset);
                  if (trim_flag)
                    printf("Trimming fraction = %.3g\n", trim_fraction);
      printf("\n");
      printf("Histogram:\n");
      for (ii=0; ii<256; ii++) {
        if (ii%8 == 0) {
          printf("%s%3i-%3i:",
            (ii==0) ? "" : "\n",
            ii, ii+7);
        }
        printf(" %8i", stats[band].histogram[ii]);
      }
      printf("\n");
    }
  }
  if (logflag && !quietflag) {
    fprintf(fLog,"Statistics found:\n");
    if (mask_flag)
      { fprintf(fLog,"Used mask %-16.11g\n",mask); }
    fprintf(fLog,"Number of bands: %d\n", meta->stats->band_count);
    for (band=0; band<meta->stats->band_count; band++) {
      fprintf(fLog,"\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id);
      fprintf(fLog,"Minimum = %-16.11g\n",stats[band].min);
      fprintf(fLog,"Maximum = %-16.11g\n",stats[band].max);
      fprintf(fLog,"Mean = %-16.11g\n",stats[band].mean);
      fprintf(fLog,"Root mean squared error = %-16.11g\n",
             stats[band].rmse);
      fprintf(fLog,"Standard deviation = %-16.11g\n",
             stats[band].std_deviation);
      fprintf(fLog,"\n");
      fprintf(fLog,"Data fit to [0..255] using equation:  byte = %g * sample + %g\n",
             stats[band].slope, stats[band].offset);
      if (trim_flag)
        fprintf(fLog,"Trimming fraction = %.3g\n", trim_fraction);
      fprintf(fLog,"\n");
      fprintf(fLog,"Histogram:\n");
      for (ii=0; ii<256; ii++) {
        if (ii%8 == 0) {
          fprintf(fLog,"%s%3i-%3i:",
                 (ii==0) ? "" : "\n",
                 ii, ii+7);
        }
        fprintf(fLog," %8i", stats[band].histogram[ii]);
      }
      fprintf(fLog,"\n");
    }
  }

/* Write out .meta and .stat files */
  if (!nometa_flag) meta_write(meta, meta_name);
  if (!nostat_flag) stat_write(stats, stat_name, meta->stats->band_count);

/* Free the metadata structure */
  meta_free(meta);

/* Report */
  if (!quietflag) {
    printf("\n");
    printf("Statistics taken on image file %s.\n",sar_name);
    if (!nometa_flag)
      printf("Statistics written to the stats block in %s.\n",
        meta_name);
    if (!nostat_flag)
      printf("Statistics plus histogram written to %s.\n",
        stat_name);
    printf("\n");
  }
  if (logflag && !quietflag) {
    fprintf(fLog,"\n");
    fprintf(fLog,"Statistics taken on image file '%s'\n",sar_name);
    if (!nometa_flag)
      fprintf(fLog,"Statistics written to the stats block in %s\n",
        meta_name);
    if (!nostat_flag)
      fprintf(fLog,"Statistics plus histogram written to %s\n",
        stat_name);
    fprintf(fLog,"\n");
  }

  if (fLog) FCLOSE(fLog);
  return 0;
}
Beispiel #8
0
// if png_flag is true, outputs a PNG.  if false, outputs a jpeg
static void patchToRGBImage(char *outname, int png_flag)
{
  update_status("Generating %s", outname);
  if (!quietflag)
    printf("   Outputting Debugging image '%s'...\n",outname);

  // input name is just the output name with ".img"
  char *polar_name = MALLOC((strlen(outname)+20)*sizeof(char));
  sprintf(polar_name, "%s_polar.img", outname);

  // will multilook, as well as conver to polar, generates a 2-band
  // file (amplitude is band 1, phase is band 2)
  c2p(outname,polar_name,FALSE,TRUE);

  // prepare for RGB conversion
  int i,j;
  meta_parameters *meta = meta_read(polar_name);
  int nl = meta->general->line_count;
  int ns = meta->general->sample_count;
  float *amp = MALLOC(sizeof(float)*ns);
  float *phase = MALLOC(sizeof(float)*ns);
  unsigned char *red = MALLOC(sizeof(unsigned char)*ns);
  unsigned char *grn = MALLOC(sizeof(unsigned char)*ns);
  unsigned char *blu = MALLOC(sizeof(unsigned char)*ns);
  FILE *fp = fopenImage(polar_name, "rb");
  const double TWOPI=2.*PI;
  const double PIOVER3=PI/3.;
  int n=0;

  // first/second passes are stats gathering
  asfPrintStatus("Gathering stats...\n");
  double avg=0, stddev=0;
  for (i=0; i<nl; i+=3) {
    get_float_line(fp,meta,i,amp);
    for (j=0; j<ns; j+=3) {
      avg += amp[j];
      ++n;
    }
    asfPercentMeter((float)i/((float)nl*2.));
  }
  avg /= (double)n;
  for (i=0; i<nl; i+=3) {
    get_float_line(fp,meta,i,amp);
    for (j=0; j<ns; j+=3) {
      stddev += (amp[j]-avg)*(amp[j]-avg);
    }
    asfPercentMeter((float)(i+nl)/((float)nl*2.));
  }
  asfPercentMeter(1);
  stddev = sqrt(stddev/(double)n);
  double min = avg - 2*stddev;
  double max = avg + 2*stddev;

  // open up PNG/JPEG output file
  FILE *ofp=NULL;
  struct jpeg_compress_struct cinfo;
  png_structp png_ptr;
  png_infop png_info_ptr;
  char *jpgname = NULL;
  char *pngname = NULL;
  if (png_flag) {
    asfPrintStatus("Generating debug image (PNG)...\n");
    pngname = appendExt(outname, ".png");
    initialize_png_file(pngname,meta,&ofp,&png_ptr,&png_info_ptr,TRUE);
  }
  else {
    asfPrintStatus("Generating debug image (JPEG)...\n");
    jpgname = appendExt(outname, ".jpg");
    initialize_jpeg_file(jpgname,meta,&ofp,&cinfo,TRUE);
  }

  // now read in the polar image, calculate RGB values, write to jpeg/png
  for (i=0; i<nl; ++i) {
    get_band_float_line(fp,meta,0,i,amp);
    get_band_float_line(fp,meta,1,i,phase);

    for (j=0; j<ns; ++j) {
      // scale to 2-sigma, to get brightness of the pixel
      unsigned char intensity;
          //=(unsigned char)(amp[j] * 128./(float)avg * 41./255.);
      if (amp[j]<=min)
        intensity=0;
      else if (amp[j]>=max)
        intensity=255;
      else
        intensity=(unsigned char)((amp[j]-min)/(max-min)*255.);

      // color of the pixel is determined by the phase
      unsigned char r=0,g=0,b=0;
      if (phase[j]<-PI) phase[j]+=TWOPI;     // ensure [-PI, PI)
      if (phase[j]>=PI) phase[j]-=TWOPI;
      int range = (int)((phase[j]+PI)/PIOVER3); // will be 0-6 (and rarely 6)
      switch (range) {
        case 0: r=1;           break;
        case 1: r=1; g=1;      break;
        case 2:      g=1;      break;
        case 3:      g=1; b=1; break;
        case 4:           b=1; break;
        case 5: r=1;      b=1; break;
        case 6:                break; // left black
        default:
          printf("phase: %f, range: %d\n", phase[j], range);
          assert(FALSE); break;
      }

      red[j] = r*intensity;
      grn[j] = g*intensity;
      blu[j] = b*intensity;
    }

    // write the line
    if (png_flag)
      write_rgb_png_byte2byte(ofp,red,grn,blu,png_ptr,png_info_ptr,ns);
    else
      write_rgb_jpeg_byte2byte(ofp,red,grn,blu,&cinfo,ns);

    // keep the user interested!
    asfPercentMeter((float)i/((float)nl));
  }
  asfPercentMeter(1.0);

  // clean up
  FCLOSE(fp);
  FREE(amp);
  FREE(phase);
  FREE(red);
  FREE(grn);
  FREE(blu);
  meta_free(meta);
  if (png_flag)
    finalize_png_file(ofp,png_ptr,png_info_ptr);
  else
    finalize_jpeg_file(ofp,&cinfo);
  FREE(jpgname);
  FREE(pngname);
  clean(polar_name);
  FREE(polar_name);
}
Beispiel #9
0
void calc_minmax_median(const char *inFile, char *band, double mask, 
			double *min, double *max)
{
  long long ii, jj;
  float logeps = 10.0 * log10(EPSILON);
  float median, median0;
  
  meta_parameters *meta = meta_read(inFile);
  int band_number =
    (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 :
    get_band_number(meta->general->bands, meta->general->band_count, band);
  long sample_count = meta->general->sample_count;
  long line_count = meta->general->line_count;
  long pixel_count = sample_count*line_count;
  long offset = line_count * band_number;
  float *data_line = MALLOC(sizeof(float) * sample_count);
  float *data = MALLOC(sizeof(float) * pixel_count);
  float *data2 = MALLOC(sizeof(float) * pixel_count);
			    
  // Culling invalid pixels
  FILE *fp = FOPEN(inFile, "rb");
  long valid_pixel_count = 0;
  asfPrintStatus("\nCalculating min and max using median...\n");
  for (ii=0; ii<line_count; ++ii) {
    get_float_line(fp, meta, ii + offset, data_line);
    asfPercentMeter(((double)ii/(double)line_count));
    for (jj=0; jj<sample_count; ++jj) {
      if (!FLOAT_EQUIVALENT(data_line[jj], -9999.99) ||
	  !FLOAT_EQUIVALENT(data_line[jj], logeps) ||
	  ISNAN(mask)) {
	data[valid_pixel_count] = data_line[jj];
	valid_pixel_count++;
      }
    }
  }
  asfPercentMeter(1.0);
  FCLOSE(fp);
  FREE(data_line);
  
  // Determine initial min and max
  *min = INIT_MINMAX;
  *max = -INIT_MINMAX;
  float minmin = INIT_MINMAX;
  float maxmax = -INIT_MINMAX;
  for (ii=0; ii<valid_pixel_count; ++ii) {
    data2[ii] = data[ii];
    if (data[ii] < minmin)
      minmin = data[ii];
    if (data[ii] > maxmax)
      maxmax = data[ii];
  }

  median0 = median_value(data, valid_pixel_count);

  // Determine minimum
  median = median0;
  *min = median0;
  for (ii=0; ii<3; ii++) {
    pixel_count = -1;
    for (jj=0; jj<valid_pixel_count; ++jj)
      if (median0 == minmin) {
	if (data[jj] <= median) {
	  pixel_count++;
	  data2[pixel_count] = data[jj];
	}
      }
      else {
	if (data[jj] < median) {
	  pixel_count++;
	  data2[pixel_count] = data[jj];
	}
      }
    median = median_value(data2, pixel_count);
    if (median == minmin)
      median = *min;
    *min = median;
  }

  // Determine maximum
  median = median0;
  *max = median0;
  for (ii=0; ii<3; ii++) {
    pixel_count = -1;
    for (jj=0; jj<valid_pixel_count; ++jj)
      if (median0 == maxmax) {
	if (data[jj] >= median) {
	  pixel_count++;
	  data2[pixel_count] = data[jj];
	}
      }
      else {
	if (data[jj] > median) {
	  pixel_count++;
	  data2[pixel_count] = data[jj];
	}
      }
    median = median_value(data2, pixel_count);
    if (median == maxmax)
      median = *max;
    *max = median;
  }

  FREE(data);
  FREE(data2);
}
Beispiel #10
0
void
calc_stats_rmse_from_file(const char *inFile, char *band, double mask,
                          double *min, double *max, double *mean,
                          double *stdDev, double *rmse,
                          gsl_histogram **histogram)
{
    double se;
    int ii,jj;

    *min = 999999;
    *max = -999999;
    *mean = 0.0;

    meta_parameters *meta = meta_read(inFile);
    int band_number =
        (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 :
        get_band_number(meta->general->bands, meta->general->band_count, band);
    long offset = meta->general->line_count * band_number;
    float *data = MALLOC(sizeof(float) * meta->general->sample_count);

    // pass 1 -- calculate mean, min & max
    FILE *fp = FOPEN(inFile, "rb");
    long long pixel_count=0;
    asfPrintStatus("\nCalculating min, max, and mean...\n");
    for (ii=0; ii<meta->general->line_count; ++ii) {
        asfPercentMeter(((double)ii/(double)meta->general->line_count));
        get_float_line(fp, meta, ii + offset, data);

        for (jj=0; jj<meta->general->sample_count; ++jj) {
            if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) {
                if (data[jj] < *min) *min = data[jj];
                if (data[jj] > *max) *max = data[jj];
                *mean += data[jj];
                ++pixel_count;
            }
        }
    }
    asfPercentMeter(1.0);
    FCLOSE(fp);

    *mean /= pixel_count;

    // Guard against weird data
    if(!(*min<*max)) *max = *min + 1;

    // Initialize the histogram.
    const int num_bins = 256;
    gsl_histogram *hist = gsl_histogram_alloc (num_bins);
    gsl_histogram_set_ranges_uniform (hist, *min, *max);
    *stdDev = 0.0;

    // pass 2 -- update histogram, calculate standard deviation
    fp = FOPEN(inFile, "rb");
    asfPrintStatus("\nCalculating standard deviation, rmse, and histogram...\n");
    se = 0.0;
    for (ii=0; ii<meta->general->line_count; ++ii) {
        asfPercentMeter(((double)ii/(double)meta->general->line_count));
        get_float_line(fp, meta, ii + offset, data);

        for (jj=0; jj<meta->general->sample_count; ++jj) {
            if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) {
                *stdDev += (data[jj] - *mean) * (data[jj] - *mean);
                gsl_histogram_increment (hist, data[jj]);
                se += (data[jj] - *mean) * (data[jj] - *mean);
            }
        }
    }
    asfPercentMeter(1.0);
    FCLOSE(fp);
    *stdDev = sqrt(*stdDev/(pixel_count - 1));
    *rmse = sqrt(se/(pixel_count - 1));

    FREE(data);

    *histogram = hist;
}
Beispiel #11
0
void
calc_stats_from_file_with_formula(const char *inFile, char *bands,
                                  calc_stats_formula_t formula_callback,
                                  double mask, double *min, double *max,
                                  double *mean, double *stdDev,
                                  gsl_histogram **histogram)
{
    int ii,jj,kk;
    const int N=MAX_BANDS;

    *min = 999999;
    *max = -999999;
    *mean = 0.0;

    meta_parameters *meta = meta_read(inFile);

    int band_numbers[N];
    for (ii=0; ii<N; ++ii)
        band_numbers[ii] = -1;

    int band_count = 0;
    if (bands) {
        char *s = STRDUP(bands); // a copy we can fiddle with
        char *q, *p = s;
        do {
            q = strchr(p, ',');
            if (q)
                *q = '\0';
            if (strlen(p) > 0 && strcmp(p, "???") != 0) {
                band_numbers[band_count] = get_band_number(meta->general->bands,
                    meta->general->band_count, p);
                //printf("%s -> %d\n", p, band_numbers[band_count]);
                ++band_count;
            }
            if (q)
                p = q+1;
        } while (q);
        FREE(s);
    }

    long band_offsets[N];
    float *band_data[N];

    for (ii=0; ii<N; ++ii) {
        if (band_numbers[ii] >= 0) {
            band_offsets[ii] = meta->general->line_count * band_numbers[ii];
            band_data[ii] = MALLOC(sizeof(float)*meta->general->sample_count);
        }
        else {
            band_offsets[ii] = -1;
            band_data[ii] = NULL;
        }
    }

    // pass 1 -- calculate mean, min & max
    FILE *fp = FOPEN(inFile, "rb");
    long long pixel_count=0;
    asfPrintStatus("\nCalculating min, max, and mean...\n");
    for (ii=0; ii<meta->general->line_count; ++ii) {
        asfPercentMeter((double)ii/(double)meta->general->line_count);

        for (kk=0; kk<N; ++kk) {
            if (band_data[kk]) {
                assert(band_offsets[kk] >= 0);
                get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]);
            }
        }

        for (jj=0; jj<meta->general->sample_count; ++jj) {
            int is_masked = FALSE;
            if (ISNAN(mask)) {
                for (kk=0; kk<N; ++kk)
                    if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask))
                        is_masked = TRUE;
            }

            if (!is_masked) {
                double data_arr[N];
                int ll;
                for (ll=0, kk=0; kk<N; ++kk)
                    if (band_data[kk])
                        data_arr[ll++] = band_data[kk][jj];
                assert(ll==band_count);

                double val = formula_callback(data_arr, mask);

                if (val < *min) *min = val;
                if (val > *max) *max = val;
                *mean += val;

                ++pixel_count;
            }
        }
    }
    asfPercentMeter(1.0);
    FCLOSE(fp);

    *mean /= pixel_count;

    // Guard against weird data
    if(!(*min<*max)) *max = *min + 1;

    // Initialize the histogram.
    const int num_bins = 256;
    gsl_histogram *hist = gsl_histogram_alloc (num_bins);
    gsl_histogram_set_ranges_uniform (hist, *min, *max);
    *stdDev = 0.0;

    // pass 2 -- update histogram, calculate standard deviation
    fp = FOPEN(inFile, "rb");
    asfPrintStatus("\nCalculating standard deviation and histogram...\n");
    for (ii=0; ii<meta->general->line_count; ++ii) {
        asfPercentMeter((double)ii/(double)meta->general->line_count);

        for (kk=0; kk<N; ++kk) {
            if (band_data[kk]) {
                assert(band_offsets[kk] >= 0);
                get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]);
            }
        }

        for (jj=0; jj<meta->general->sample_count; ++jj) {
            int is_masked = FALSE;
            if (ISNAN(mask)) {
                for (kk=0; kk<N; ++kk)
                    if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask))
                        is_masked = TRUE;
            }

            if (!is_masked) {
                double data_arr[N];
                int ll;
                for (ll=0, kk=0; kk<N; ++kk)
                    if (band_data[kk])
                        data_arr[ll++] = band_data[kk][jj];
                assert(ll==band_count);

                double val = formula_callback(data_arr, mask);

                *stdDev += (val - *mean) * (val - *mean);
                gsl_histogram_increment (hist, val);
            }
        }
    }
    asfPercentMeter(1.0);
    FCLOSE(fp);
    *stdDev = sqrt(*stdDev/(pixel_count - 1));

    for (ii=0; ii<N; ++ii)
        if (band_data[ii])
            FREE(band_data[ii]);

    *histogram = hist;
}
Beispiel #12
0
void c2p_ext(const char *inDataName, const char *inMetaName,
             const char *outfile, int multilook, int banded)
{
    meta_parameters *in_meta = meta_read(inMetaName);
    int data_type = in_meta->general->data_type;
    // the old code did this, but why??
    in_meta->general->data_type = meta_polar2complex(data_type);

    // some sanity checks
    switch (data_type) {
      case COMPLEX_BYTE:
      case COMPLEX_INTEGER16:
      case COMPLEX_INTEGER32:
      case COMPLEX_REAL32:
      case COMPLEX_REAL64:
          break;
      default:
          asfPrintError("c2p: %s is not a complex image.\n", inDataName);
    }

    if (in_meta->general->band_count != 1)
        asfPrintError("c2p: %s is not a single-band image.\n", inDataName);

    if (!in_meta->sar)
        asfPrintError("c2p: %s is missing a SAR block.\n", inDataName);

    asfPrintStatus("Converting complex image to amplitude/phase...\n");

    int nl = in_meta->general->line_count;
    int ns = in_meta->general->sample_count;
    // process 1 line at a time when not multilooking, otherwise grab nlooks
    int nlooks = multilook ? in_meta->sar->look_count : 1;

    if (nlooks == 1 && multilook) {
        asfPrintStatus("Not multilooking, look_count is 1.\n");
        multilook = FALSE;
    }

    if (multilook)
        asfPrintStatus("Multilooking with %d looks.\n", nlooks);

    meta_parameters *out_meta = meta_read(inMetaName);
    out_meta->general->data_type = meta_complex2polar(data_type);

    // set up input/output files
    FILE *fin = fopenImage(inDataName, "rb");

    // we either have 1 or 2 output files, per the "banded" flag.
    char *outfile_img = appendExt(outfile, ".img");
    char *amp_name=NULL, *phase_name=NULL;
    FILE *fout_banded=NULL, *fout_amp=NULL, *fout_phase=NULL;
    if (banded) {
        asfPrintStatus("Output is 2-band image: %s\n", outfile_img);
        fout_banded = fopenImage(outfile_img, "wb");
    } else {
        amp_name = appendToBasename(outfile_img, "_amp");
        phase_name = appendToBasename(outfile_img, "_phase");
        asfPrintStatus("Output amplitude file: %s\n", amp_name);
        asfPrintStatus("Output phase file: %s\n", phase_name);
        fout_amp = fopenImage(amp_name, "wb");
        fout_phase = fopenImage(phase_name, "wb");
    }
    if (banded)
        assert(fout_banded && !fout_amp && !fout_phase);
    else
        assert(!fout_banded && fout_amp && fout_phase);

    // get the metadata band_count correct, needed in the put_* calls
    if (banded) {
        out_meta->general->band_count = 2;
        strcpy(out_meta->general->bands, "AMP,PHASE");
    }

    // input buffer
    complexFloat *cpx = MALLOC(sizeof(complexFloat)*ns*nlooks);

    // output buffers
    float *amp = MALLOC(sizeof(float)*ns*nlooks);
    float *phase = MALLOC(sizeof(float)*ns*nlooks);

    int line_in;    // line in the input image
    int line_out=0; // line in the output image
    int samp;       // sample #, loop index
    int l;          // line loop index, iterates over the lines in the block

    out_meta->general->line_count = (int)ceil((double)nl/(double)nlooks);

    for (line_in=0; line_in<nl; line_in+=nlooks)
    {
        // lc = "line count" -- how many lines to read. normally we will read
        // nlooks lines, but near eof we might have to read fewer
        int lc = nlooks; 
        if (line_in + lc > nl)
            lc = nl - line_in;

        // read "nlooks" (or possibly fewer, if near eof) lines of data
        int blockSize = get_complexFloat_lines(fin,in_meta,line_in,lc,cpx);
        if (blockSize != lc*ns)
            asfPrintError("bad blockSize: bs=%d nlooks=%d ns=%d\n", 
			  blockSize, nlooks, ns);

        // first, compute the power/phase
        for (l=0; l<lc; ++l) {
            for (samp=0; samp<ns; ++samp) {
                int k = l*ns + samp; // index into the block
                float re = cpx[k].real;
                float im = cpx[k].imag;
                if (re != 0.0 || im != 0.0) {
                    amp[k] = re*re + im*im;
                    phase[k] = atan2(im, re);
                } else {
                    amp[k] = phase[k] = 0.0;
                }
            }
        }

        // now multilook, if requested
        if (multilook) {
            // put the multilooked data in the first "row" of amp,phase
            for (samp=0; samp<ns; ++samp) {
                float value = 0.0;
                for (l=0; l<lc; ++l)
                    value += amp[l*ns + samp];
                amp[samp] = sqrt(value/(float)lc);

                value = 0.0;
                for (l=0; l<lc; ++l)
                    value += phase[l*ns + samp];
                phase[samp] = value/(float)lc;
            }
        }
        else {
            for (samp=0; samp<ns*lc; ++samp)
                amp[samp] = sqrt(amp[samp]);
        }

        // write out a line (multilooked) or a bunch of lines (not multi)
        if (multilook) {
            if (banded) {
                put_band_float_line(fout_banded, out_meta, 0, line_out, amp);
                put_band_float_line(fout_banded, out_meta, 1, line_out, phase);
            } else {
                put_float_line(fout_amp, out_meta, line_out, amp);
                put_float_line(fout_phase, out_meta, line_out, phase);
            }
            ++line_out;
        } else {
            for (l=0; l<lc; ++l) {
                if (banded) {
                    put_band_float_line(fout_banded, out_meta, 0, line_in+l, amp);
                    put_band_float_line(fout_banded, out_meta, 1, line_in+l, phase);
                } else {
                    put_float_line(fout_amp, out_meta, line_in+l, amp);
                    put_float_line(fout_phase, out_meta, line_in+l, phase);
                }
                ++line_out;
            }
        }

        asfPercentMeter((float)line_in/(float)(nl));
    }
    asfPercentMeter(1.0);

    fclose(fin);
    if (fout_banded) fclose(fout_banded);
    if (fout_amp) fclose(fout_amp);
    if (fout_phase) fclose(fout_phase);

    if (multilook) {
        if (out_meta->general->line_count != line_out)
            asfPrintError("Line counts don't match: %d != %d\n",
                out_meta->general->line_count, line_out);
        out_meta->general->y_pixel_size *= nlooks;
        out_meta->sar->azimuth_time_per_pixel *= nlooks;
        out_meta->sar->multilook = TRUE;
    } else
        assert(line_out == nl);

    // write out the metadata, different whether multi-banded or not
    if (banded) {
        assert(!amp_name && !phase_name);
        meta_write(out_meta, outfile);
    } else {
        assert(amp_name && phase_name);
        
        out_meta->general->image_data_type = AMPLITUDE_IMAGE;
        meta_write(out_meta, amp_name);
        
        out_meta->general->image_data_type = PHASE_IMAGE;
        meta_write(out_meta, phase_name);
    }

    if (multilook)
        asfPrintStatus("Original line count: %d, after multilooking: %d "
            "(%d looks)\n", nl, line_out, nlooks);

    meta_free(in_meta);
    meta_free(out_meta);

    FREE(amp);
    FREE(phase);
    FREE(cpx);

    FREE(outfile_img);

    FREE(amp_name);
    FREE(phase_name);
}
Beispiel #13
0
int plan(const char *satellite, const char *beam_mode, double look_angle,
         long startdate, long enddate, double min_lat, double max_lat,
         double clat, double clon, int pass_type,
         int zone, Poly *aoi, const char *tle_filename,
         PassCollection **pc_out, char **errorstring)
{
  BeamModeInfo *bmi = get_beam_mode_info(satellite, beam_mode);
  if (!bmi) {
    *errorstring = STRDUP("Unknown satellite/beam mode combination.\n");
    return -1;
  }

  // Convert the input start/end times from longdates (dates as long ints)
  // to seconds from some reference time.  (midnight jan 1, 1900)
  // We add a day to the end date, so that the passed-in range is inclusive
  double start_secs = seconds_from_long(startdate);
  double end_secs = seconds_from_long(add_a_day(enddate));

  sat_t sat;
  read_tle(tle_filename, satellite, &sat);

  // if the planned acquisition period is further away than this amount,
  // we subtract multiples of the repeat cyle time until we are within
  // this threshold time of this tle
  double tle_time =
    time_to_secs(sat.tle.epoch_year, sat.tle.epoch_day, sat.tle.epoch_fod);

  // FIXME this is alos specific FIXME!!
  // should really read this out of a config file... or calculate it
  // from the TLE info?
  const double repeat_days = 46;
  const double orbits_per_cycle = 671;

  // repeat time, in seconds, all time references are in seconds
  double repeat_cycle_time = repeat_days * 24.*60.*60.;

  // how many days to pad the repeat cycle time, before modding the
  // start/end time
  const double days_of_padding = 5;

  // this is the cutoff, 
  double threshold = repeat_cycle_time + 24*60*60 * days_of_padding;

  int cycles_adjustment=0;
  if (start_secs-tle_time > threshold) {
    while (start_secs-tle_time > threshold) {
      start_secs -= repeat_cycle_time;
      end_secs -= repeat_cycle_time;
      ++cycles_adjustment;
    }
  }
  else if (tle_time-start_secs > threshold) { // planning backwards...
    while (tle_time-start_secs > threshold) {
      start_secs += repeat_cycle_time;
      end_secs += repeat_cycle_time;
      --cycles_adjustment;
    }
  }

  double time_adjustment = cycles_adjustment*repeat_cycle_time;
  if (cycles_adjustment != 0)
    asfPrintStatus("Adjusted start/end times %s by %d repeat cycle%s.\n",
           cycles_adjustment > 0 ? "forward" : "backward",
           cycles_adjustment > 0 ? cycles_adjustment : -cycles_adjustment,
           cycles_adjustment == 1 || cycles_adjustment == -1 ? "" : "s");

  // no deep space orbits can be planned
  assert((sat.flags & DEEP_SPACE_EPHEM_FLAG) == 0);

  if (is_utm(zone)) {
    asfPrintStatus("Target: UTM zone %d\n"
                   "  (%10.2f, %10.2f)  (%10.2f, %10.2f)\n"
                   "  (%10.2f, %10.2f)  (%10.2f, %10.2f)\n",
                   zone,
                   aoi->x[0], aoi->y[0],
                   aoi->x[1], aoi->y[1],
                   aoi->x[2], aoi->y[2],
                   aoi->x[3], aoi->y[3]);
  }
  else {
    asfPrintStatus("Target: Polar Stereo %s\n"
                   "  (%10.2f, %10.2f)  (%10.2f, %10.2f)\n"
                   "  (%10.2f, %10.2f)  (%10.2f, %10.2f)\n",
                   zone>0 ? "North" : "South",
                   aoi->x[0], aoi->y[0],
                   aoi->x[1], aoi->y[1],
                   aoi->x[2], aoi->y[2],
                   aoi->x[3], aoi->y[3]);
  }

  double curr = start_secs;
  double incr = bmi->image_time;
  stateVector st = tle_propagate(&sat, start_secs-incr);
  double lat_prev = sat.ssplat;
  int i,num_found = 0;

  // 
  // Calculate the number of frames to include before we hit the
  // area of interest.  Add 1 (i.e., round up), but if user puts in
  // zero seconds, then we want 0 lead-up frames.
  PassCollection *pc = pass_collection_new(clat, clon, aoi);

  asfPrintStatus("Searching...\n");
  while (curr < end_secs) {
    st = tle_propagate(&sat, curr);
    char dir = sat.ssplat > lat_prev ? 'A' : 'D';

    if ((dir=='A' && pass_type!=DESCENDING_ONLY) ||
        (dir=='D' && pass_type!=ASCENDING_ONLY))
    {
      OverlapInfo *oi =
        overlap(curr, &st, bmi, look_angle, zone, clat, clon, aoi);

      if (oi) {
        int n=0;

        // Calculate the orbit number -- we have to fudge this if we
        // modded the start time.
        int orbit_num = sat.orbit + orbits_per_cycle*cycles_adjustment;

        // This is an alternate way of calculating the orbit number that
        // was being used during testing... seems to produce numbers close
        // to (within 1) of the number obtained by sgpsdp...
        //double secs_per_orbit = repeat_cycle_time / orbits_per_cycle;
        // ALOS was launced on 1/24/06
        //double launch_secs = seconds_from_long(20060124);
        //double orbit_num2 = (curr - launch_secs) / secs_per_orbit;
        //orbit_num2 += orbits_per_cycle*cycles_adjustment;
        //printf("%f %f %f\n", orbit_num + sat.orbit_part,
        //       orbit_num2, orbit_num+sat.orbit_part-orbit_num2);

        // UPDATE!!  All this orbit number calculation business doesn't get
        // used for ALOS planning -- orbit number is re-calculated using
        // time since a refrence orbit.
        // See planner.c -- get_alos_orbit_number_at_time()

        PassInfo *pass_info = pass_info_new(orbit_num, sat.orbit_part, dir);
        double start_time = curr - bmi->num_buffer_frames*incr;

        // add on the buffer frames before the area of interest
        for (i=bmi->num_buffer_frames; i>0; --i) {
          double t = curr - i*incr;
          stateVector st1 = tle_propagate(&sat, t);
          double rclat, rclon; // viewable region center lat/lon

          Poly *region = get_viewable_region(&st1, bmi, look_angle,
                                             zone, clat, clon, &rclat, &rclon);

          if (region) {
            OverlapInfo *oi1 = overlap_new(0, 1000, region, zone, clat, clon,
                                           &st1, t);
            pass_info_add(pass_info, t+time_adjustment, oi1);

            if (pass_info->start_lat == -999) {
              // at the first valid buffer frame -- set starting latitude
              double start_lat, end_lat;
              get_latitude_range(region, zone, dir, &start_lat, &end_lat);
              pass_info_set_start_latitude(pass_info, start_lat);
            }
          }
        }

        // add the frames that actually image the area of interest
        while (curr < end_secs && oi) {
          pass_info_add(pass_info, curr+time_adjustment, oi);
          ++n;

          curr += incr;
          st = tle_propagate(&sat, curr);

          oi = overlap(curr, &st, bmi, look_angle, zone, clat, clon, aoi);
        }

        double end_time = curr + (bmi->num_buffer_frames-1)*incr;
        pass_info_set_duration(pass_info, end_time-start_time);

        // add on the buffer frames after the area of interest
        for (i=0; i<bmi->num_buffer_frames; ++i) {
          double t = curr + i*incr;
          stateVector st1 = tle_propagate(&sat, t);
          double rclat, rclon; // viewable region center lat/lon
          Poly *region = get_viewable_region(&st1, bmi, look_angle,
                                             zone, clat, clon, &rclat, &rclon);
          if (region) {
            OverlapInfo *oi1 = overlap_new(0, 1000, region, zone, clat, clon,
                                           &st1, t);
            pass_info_add(pass_info, t+time_adjustment, oi1);

            // set stopping latitude -- each frame overwrites the previous,
            // so the last valid frame will set the stopping latitude
            double start_lat, end_lat;
            get_latitude_range(region, zone, dir, &start_lat, &end_lat);
            pass_info_set_stop_latitude(pass_info, end_lat);
          }
        }

        // make sure we set all the required "after the fact" info
        // if not, then do not add the pass... must be invalid
        // (these used to be asserts, so it doesn't seem to ever happen)
        if (n>0 &&
            pass_info->start_lat != -999 &&
            pass_info->stop_lat != -999 &&
            pass_info->duration != -999)
        {
          // add the pass!
          pass_collection_add(pc, pass_info);
          ++num_found;
        }
        else
        {
          asfPrintStatus("Invalid pass found.  Skipped... \n"
                         " -- number of frames: %d, dir: %c\n"
                         " -- date: %s, orbit %d, %f\n --> (%f,%f,%f)\n",
                         n, pass_info->dir,
                         pass_info->start_time_as_string,
                         pass_info->orbit, pass_info->orbit_part,
                         pass_info->start_lat, pass_info->stop_lat,
                         pass_info->duration);
        }
      }
    }

    curr += incr;
    lat_prev = sat.ssplat;

    //printf("Lat: %f, Orbit: %d, Orbit Part: %f\n", sat.ssplat,
    //       (int)sat.orbit, sat.orbit_part);

    asfPercentMeter((curr-start_secs)/(end_secs-start_secs));
  }
  asfPercentMeter(1.0);

  *pc_out = pc;
  return num_found;
}