Beispiel #1
0
// Determine radiometrically correction amplitude value
float get_rad_cal_dn(meta_parameters *meta, int line, int sample, char *bandExt,
		     float inDn, float radCorr)
{
  // Return background value unchanged
  if (FLOAT_EQUIVALENT(inDn, 0.0))
    return 0.0;

  meta->general->radiometry = r_SIGMA;
  double incid = meta_incid(meta, line, sample);
  double sigma = get_cal_dn(meta, incid, sample, inDn, bandExt, FALSE);
  double calValue, invIncAngle;

  // Calculate according to the calibration data type
  if (meta->calibration->type == asf_cal) { // ASF style data (PP and SSP)

    asf_cal_params *p = meta->calibration->asf;
    double index = (double)sample*256./(double)(p->sample_count);
    int base = (int) index;
    double frac = index - base;
    double *noise = p->noise;

    // Determine the noise value
    double noiseValue = noise[base] + frac*(noise[base+1] - noise[base]);

    // Convert (amplitude) data number to scaled, noise-removed power
    //scaledPower = (p->a1*(inDn*inDn-p->a0*noiseValue) + p->a2)*invIncAngle;
    calValue = sqrt(((sigma * radCorr) - p->a2)/p->a1 + p->a0*noiseValue);
  }
  else if (meta->calibration->type == asf_scansar_cal) { // ASF style ScanSar

    invIncAngle = 1.0;
    asf_scansar_cal_params *p = meta->calibration->asf_scansar;
    double look = 25.0; // FIXME: hack to get things compiled
    double index = (look-16.3)*10.0;
    double noiseValue;
    double *noise = p->noise;

    if (index <= 0)
      noiseValue = noise[0];
    else if (index >= 255)
      noiseValue = noise[255];
    else {
      // Use linear interpolation on noise array
      int base = (int)index;
      double frac = index - base;
      noiseValue = noise[base] + frac*(noise[base+1] - noise[base]);
    }

    // Convert (amplitude) data number to scaled, noise-removed power
    //scaledPower = (p->a1*(inDn*inDn-p->a0*noiseValue) + p->a2)*invIncAngle;
    calValue = sqrt(((sigma * radCorr) - p->a2)/p->a1 + p->a0*noiseValue);
  }
  else if (meta->calibration->type == esa_cal) { // ESA style ERS and JERS data

    esa_cal_params *p = meta->calibration->esa;
    //scaledPower = inDn*inDn/p->k*sin(p->ref_incid*D2R)/sin(incid);
    calValue = sqrt(sigma * radCorr * p->k*sin(p->ref_incid*D2R)*sin(incid));
  }
  else if (meta->calibration->type == rsat_cal) { // CDPF style Radarsat data

    invIncAngle = 1/tan(incid);

    rsat_cal_params *p = meta->calibration->rsat;
    double a2;
    if (meta->calibration->rsat->focus)
      a2 = p->lut[0];
    else if (sample < (p->samp_inc*(p->n-1))) {
      int i_low = sample/p->samp_inc;
      int i_up = i_low + 1;
      a2 = p->lut[i_low] +
	((p->lut[i_up] - p->lut[i_low])*((sample/p->samp_inc) - i_low));
    }
    else
      a2 = p->lut[p->n-1] +
	((p->lut[p->n-1] - p->lut[p->n-2])*((sample/p->samp_inc) - p->n-1));
    if (p->slc)
      //scaledPower = (inDn*inDn)/(a2*a2)*invIncAngle;
      calValue = sqrt(sigma * radCorr *a2*a2/invIncAngle);
    else
      //scaledPower = (inDn*inDn + p->a3)/a2*invIncAngle;
      calValue = sqrt((sigma * radCorr *a2/invIncAngle) - p->a3);
  }
  else if (meta->calibration->type == alos_cal) { // ALOS data

    alos_cal_params *p = meta->calibration->alos;
    double cf;
    if (strstr(bandExt, "HH"))
      cf = p->cf_hh;
    else if (strstr(bandExt, "HV"))
      cf = p->cf_hv;
    else if (strstr(bandExt, "VH"))
      cf = p->cf_vh;
    else if (strstr(bandExt, "VV"))
      cf = p->cf_vv;
    
    //scaledPower = pow(10, cf/10.0)*inDn*inDn*invIncAngle;
    calValue = sqrt(sigma * radCorr / pow(10, cf/10.0));
  }
  else if (meta->calibration->type == tsx_cal) {

    invIncAngle = 1/tan(incid);
    double cf = meta->calibration->tsx->k;
    //scaledPower = cf*inDn*inDn*invIncAngle;
    calValue = sqrt(sigma * radCorr / (cf*invIncAngle));
  }

  return calValue;
}
Beispiel #2
0
int asf_calibrate(const char *inFile, const char *outFile, 
		  radiometry_t outRadiometry, int wh_scaleFlag)
{
  meta_parameters *metaIn = meta_read(inFile);
  meta_parameters *metaOut = meta_read(inFile);

  if (!metaIn->calibration) {
    asfPrintError("This data cannot be calibrated, missing calibration block.\n");
  }

  // Check for valid output radiometry
  if (outRadiometry == r_AMP || outRadiometry == r_POWER)
    asfPrintError("Invalid radiometry (%s) passed into calibration function!\n",
		  radiometry2str(outRadiometry));

  // Check whether output radiometry fits with Woods Hole scaling flag
  if (wh_scaleFlag && outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA)
    outRadiometry += 3;

  // This can only work if the image is in some SAR geometry
  if (metaIn->projection && metaIn->projection->type != SCANSAR_PROJECTION)
    asfPrintError("Can't apply calibration factors to map projected images\n"
                  "(Amplitude or Power only)\n");

  radiometry_t inRadiometry = metaIn->general->radiometry;
  asfPrintStatus("Calibrating %s image to %s image\n\n", 
		 radiometry2str(inRadiometry), radiometry2str(outRadiometry));
  // FIXME: This function should be able to remap between different
  //        radiometry projections.
  if (metaIn->general->radiometry != r_AMP)
    asfPrintError("Currently only AMPLITUDE as radiometry is supported!\n");

  metaOut->general->radiometry = outRadiometry;
  int dbFlag = FALSE;
  if (outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA)
    metaOut->general->no_data = 0.0001;
  if (outRadiometry >= r_SIGMA_DB && outRadiometry <= r_GAMMA_DB) {
    metaOut->general->no_data = -40.0;
    dbFlag = TRUE;
  }
  if (metaIn->general->image_data_type != POLARIMETRIC_IMAGE) {
    if (outRadiometry == r_SIGMA || outRadiometry == r_SIGMA_DB)
      metaOut->general->image_data_type = SIGMA_IMAGE;
    else if (outRadiometry == r_BETA || outRadiometry == r_BETA_DB)
      metaOut->general->image_data_type = BETA_IMAGE;
    else if (outRadiometry == r_GAMMA || outRadiometry == r_GAMMA_DB)
      metaOut->general->image_data_type = GAMMA_IMAGE;
  }
  if (wh_scaleFlag)
    metaOut->general->data_type = ASF_BYTE;

  char *input = appendExt(inFile, ".img");
  char *output = appendExt(outFile, ".img");
  FILE *fpIn = FOPEN(input, "rb");
  FILE *fpOut = FOPEN(output, "wb");

  int dualpol = strncmp_case(metaIn->general->mode, "FBD", 3) == 0 ? 1 : 0;
  int band_count = metaIn->general->band_count;
  int sample_count = metaIn->general->sample_count;
  int line_count = metaIn->general->line_count;
  char **bands = 
    extract_band_names(metaIn->general->bands, band_count);

  float *bufIn = (float *) MALLOC(sizeof(float)*sample_count);
  float *bufOut = (float *) MALLOC(sizeof(float)*sample_count);
  float *bufIn2 = NULL, *bufOut2 = NULL, *bufOut3 = NULL;
  if (dualpol && wh_scaleFlag) {
    bufIn2 = (float *) MALLOC(sizeof(float)*sample_count);
    bufOut2 = (float *) MALLOC(sizeof(float)*sample_count);
    bufOut3 = (float *) MALLOC(sizeof(float)*sample_count);
    metaOut->general->band_count = 3;
    sprintf(metaOut->general->bands, "%s,%s,%s-%s", 
	    bands[0], bands[1], bands[0], bands[1]);
  }

  int ii, jj, kk;
  float cal_dn, cal_dn2;
  double incid;
  if (dualpol && wh_scaleFlag) {
    metaOut->general->image_data_type = RGB_STACK;
    for (ii=0; ii<line_count; ii++) {
      get_band_float_line(fpIn, metaIn, 0, ii, bufIn);
      get_band_float_line(fpIn, metaIn, 1, ii, bufIn2);
      for (jj=0; jj<sample_count; jj++) {
	// Taking the remapping of other radiometries out for the moment
	//if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB)
	//bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]);
	incid = meta_incid(metaIn, ii, jj);
	cal_dn = 
	  get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[0], dbFlag);
	cal_dn2 = 
	  get_cal_dn(metaOut, incid, jj, bufIn2[jj], bands[1], dbFlag);
	if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data) ||
	    cal_dn == cal_dn2) {
	  bufOut[jj] = 0;
	  bufOut2[jj] = 0;
	  bufOut3[jj] = 0;
	}
	else {
	  bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5;
	  bufOut2[jj] = (cal_dn2 + 31) / 0.15 + 1.5;
	  bufOut3[jj] = bufOut[jj] - bufOut2[jj];
	}
      }
      put_band_float_line(fpOut, metaOut, 0, ii, bufOut);
      put_band_float_line(fpOut, metaOut, 1, ii, bufOut2);
      put_band_float_line(fpOut, metaOut, 2, ii, bufOut3);
      asfLineMeter(ii, line_count);
    }
  }
  else {
    for (kk=0; kk<band_count; kk++) {
      for (ii=0; ii<line_count; ii++) {
	get_band_float_line(fpIn, metaIn, kk, ii, bufIn);
	for (jj=0; jj<sample_count; jj++) {
	  // Taking the remapping of other radiometries out for the moment
	  //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB)
	  //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]);
	  if (strstr(bands[kk], "PHASE") == NULL) {
	    incid = meta_incid(metaIn, ii, jj);
	    cal_dn =
	      get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[kk], dbFlag);
	    if (wh_scaleFlag) {
	      if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data))
		bufOut[jj] = 0;
	      else
		bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5;
	    }
	    else
	      bufOut[jj] = cal_dn;
	  }
	  else // PHASE band, do nothing
	    bufOut[jj] = bufIn[jj];
	}
	put_band_float_line(fpOut, metaOut, kk, ii, bufOut);
	asfLineMeter(ii, line_count);
      }
      if (kk==0)
	sprintf(metaOut->general->bands, "%s-%s", 
		radiometry2str(outRadiometry), bands[kk]);
      else {
	char tmp[255];
	sprintf(tmp, ",%s-%s", radiometry2str(outRadiometry), bands[kk]);
	strcat(metaOut->general->bands, tmp);
      }
    }
  }
  meta_write(metaOut, outFile);
  meta_free(metaIn);
  meta_free(metaOut);
  FREE(bufIn);
  FREE(bufOut);
  if (dualpol) {
    FREE(bufIn2);
    FREE(bufOut2);
    FREE(bufOut3);
  }
  for (kk=0; kk<band_count; ++kk)
    FREE(bands[kk]);
  FREE(bands);
  FCLOSE(fpIn);
  FCLOSE(fpOut);
  FREE(input);
  FREE(output);

  return FALSE;
}