int calc_zoomLevel(int pixel, double kilometers) { return calc_zoomLevel_res(calc_resolution(pixel, kilometers)); }
int main(int argc, char *argv[]) { char szImg[255], szImage[255], buffer[1000], crID[10], szCrList[255], szOut[255]; int ii, kk, size, bigSize=oversampling_factor*srcSize; int mainlobe_azimuth_min, mainlobe_azimuth_max, mainlobe_range_min; int mainlobe_range_max, sidelobe_azimuth_min, sidelobe_azimuth_max; int sidelobe_range_min, sidelobe_range_max, peak_line, peak_sample; float azimuth_processing_bandwidth, chirp_rate, pulse_duration, sampling_rate; float prf, srcPeakX, srcPeakY, bigPeakX, bigPeakY, clutter_power, peak_power, scr; float azimuth_resolution, range_resolution, azimuth_pslr, range_pslr; float azimuth_window_size, range_window_size; float azimuth_profile[bigSize], range_profile[bigSize]; static complexFloat *s, *t; double lat, lon, elev, posX, posY, look_angle; FILE *fpIn, *fpOut, *fp, *fpText; meta_parameters *meta, *meta_debug; float *original_amplitude, *amplitude, *phase; fcpx *src_fft, *trg_fft; int debug=FALSE; char *text=NULL; int overwrite=FALSE; if (argc==1) usage(); if (strcmp(argv[1],"-help")==0) help_page(); /* exits program */ if (strcmp(argv[1],"-overwrite")==0) overwrite=TRUE; int required_args = 4; if (overwrite) ++required_args; if(argc != required_args) usage();/*This exits with a failure*/ /* Fetch required arguments */ strcpy(szImg, argv[argc - 3]); strcpy(szCrList,argv[argc - 2]); strcpy(szOut,argv[argc - 1]); /* DEFAULT VALUES: size of region to oversample - 64 pixels mainlobe width factor - 2.6 sidelobe width factor - 20.0 maximum oversampling factor - 8 */ // Read metadata sprintf(szImage, "%s.img", szImg); meta = meta_read(szImage); lines = meta->general->line_count; samples = meta->general->sample_count; text = (char *) MALLOC(255*sizeof(char)); // Handle input and output file fpIn = FOPEN(szCrList, "r"); fpOut = FOPEN(szOut, "w"); fprintf(fpOut, "POINT TARGET ANALYSIS RESULTS\n\n"); fprintf(fpOut, "CR\tLat\tLon\tElev\tAz peak\tRng peak\tLook\t" "Az res\tRng res\tAz PSLR\tRng PSLR\tSCR\n"); // RCS needs some more coding // Loop through corner reflector location file while (fgets(buffer, 1000, fpIn)) { if (overwrite) { sscanf(buffer, "%s\t%lf\t%lf", crID, &posY, &posX); printf(" %s: posX = %.2lf, posY = %.2lf\n", crID, posX, posY); } else { sscanf(buffer, "%s\t%lf\t%lf\t%lf", crID, &lat, &lon, &elev); meta_get_lineSamp(meta, lat, lon, elev, &posY, &posX); printf(" %s: lat = %.4lf, lon = %.4lf, posX = %.2lf, posY = %.2lf\n", crID, lat, lon, posX, posY); } // Check bounds - Get average spectra from chip in range direction if (!(outOfBounds(posX, posY, srcSize))) { // READ SUBSET FROM THE IMAGE WITH CORNER REFLECTOR IN THE CENTER size = srcSize*srcSize*sizeof(float); original_amplitude = (float *) MALLOC(size); phase = (float *) MALLOC(size); s = (complexFloat *) MALLOC(2*size); readComplexSubset(szImage, srcSize, srcSize, posX-srcSize/2, posY-srcSize/2, s); my_complex2polar(s, srcSize, srcSize, original_amplitude, phase); if (debug) { // Store original image for debugging fp = FOPEN("original.img", "wb"); size = bigSize*bigSize*sizeof(float); FWRITE(original_amplitude, size, 1, fp); FCLOSE(fp); meta_debug = meta_init(szImage); meta_debug->general->line_count = meta_debug->general->sample_count = srcSize; meta_debug->general->data_type = REAL32; meta_debug->general->start_line = posY-srcSize/2; meta_debug->general->start_sample = posX-srcSize/2; meta_debug->general->center_latitude = lat; meta_debug->general->center_longitude = lon; meta_write(meta_debug, "original.meta"); meta_free(meta_debug); } // Find amplitude peak in original image chip if (!findPeak(original_amplitude, srcSize, &srcPeakX, &srcPeakY)) { fprintf(fpOut, " Could not find amplitude peak in original image chip!\n"); goto SKIP; } // Cut out the subset again around the peak to make sure we have data for // the analysis readComplexSubset(szImage, srcSize, srcSize, posX-srcSize+srcPeakY, posY-srcSize+srcPeakX, s); my_complex2polar(s, srcSize, srcSize, original_amplitude, phase); FREE(phase); findPeak(original_amplitude, srcSize, &srcPeakX, &srcPeakY); // Determine look angle look_angle = meta_look(meta, srcSize/2, srcSize/2); /**************************** - special ScanSAR case: images are "projected" - need to be rotated back to allow analysis in azimuth and range direction (ss_extract.c) *********************/ // BASEBAND THE DATA IN EACH DIMENSION IN THE FREQUENCY DOMAIN // Oversample image src_fft = forward_fft(s, srcSize, srcSize); trg_fft = oversample(src_fft, srcSize, oversampling_factor); // Determine azimuth and range window size azimuth_processing_bandwidth = (float) meta->sar->azimuth_processing_bandwidth; prf = (float) meta->sar->prf; chirp_rate = (float) meta->sar->chirp_rate; pulse_duration = (float) meta->sar->pulse_duration; sampling_rate = (float) meta->sar->range_sampling_rate; azimuth_window_size = azimuth_processing_bandwidth / prf; range_window_size = fabs(chirp_rate) * pulse_duration / sampling_rate; printf("azimuth window size: %.2f, range window size: %.2f\n", azimuth_window_size, range_window_size); asfRequire(azimuth_window_size > 0.0 && azimuth_window_size < 1.0, "azimuth window size out of range (0 to 1)!\n"); asfRequire(range_window_size > 0.0 && range_window_size < 1.0, "range window size out of range (0 to 1)!\n"); if (range_window_size < 0.5) range_window_size = 0.5; // for ScanSAR both 0.5 // run debugger to check units are correct! // Baseband image in range direction //baseband(src_fft, range_window_size); /* // Transpose matrix to work in azimuth direction //transpose(s); // Baseband image in azimuth direction // baseband(s, azimuth_window_size); // Transpose matrix back into original orientation //transpose(s); */ t = inverse_fft(trg_fft, bigSize, bigSize); amplitude = (float *) MALLOC(sizeof(float)*bigSize*bigSize); phase = (float *) MALLOC(sizeof(float)*bigSize*bigSize); my_complex2polar(t, bigSize, bigSize, amplitude, phase); FREE(phase); if (debug) { // Store oversampled image for debugging fp = FOPEN("oversample.img", "wb"); size = bigSize*bigSize*sizeof(float); FWRITE(amplitude, size, 1, fp); FCLOSE(fp); meta_debug = meta_init("oversample.meta"); meta_debug->general->line_count = meta_debug->general->sample_count = bigSize; meta_debug->general->data_type = REAL32; meta_write(meta_debug, "oversample.meta"); meta_free(meta_debug); } // Find the amplitude peak in oversampled image if (!findPeak(amplitude, bigSize, &bigPeakX, &bigPeakY)) { fprintf(fpOut, " Could not find amplitude peak in oversampled image chip!\n"); goto SKIP; } peak_line = (int)(bigPeakX + 0.5); peak_sample = (int)(bigPeakY + 0.5); // Write text version of oversampled image sprintf(text, "%s_%s_chip.txt", szImg, crID); fpText = FOPEN(text, "w"); for (ii=peak_line-32; ii<peak_line+32; ii++) { for (kk=peak_sample-32; kk<peak_sample+32; kk++) fprintf(fpText, "%12.4f\t", amplitude[ii*bigSize+kk]); fprintf(fpText, "\n"); } FCLOSE(fpText); // EXTRACTING PROFILES IN AZIMUTH AND RANGE THROUGH PEAK for (ii=0; ii<bigSize; ii++) { azimuth_profile[ii] = amplitude[ii*bigSize+peak_sample]; range_profile[ii] = amplitude[bigSize*peak_line+ii]; } sprintf(text, "%s_%s_azimuth.txt", szImg, crID); fp = FOPEN(text, "w"); fprintf(fp, "Azimuth profile\n"); for (ii=0; ii<bigSize; ii++) fprintf(fp, "%.3f\n", azimuth_profile[ii]); FCLOSE(fp); sprintf(text, "%s_%s_range.txt", szImg, crID); fp = FOPEN(text, "w"); fprintf(fp, "Range profile\n"); for (ii=0; ii<bigSize; ii++) fprintf(fp, "%.3f\n", range_profile[ii]); FCLOSE(fp); // FINALLY GET TO THE IMAGE QUALITY PARAMETERS clutter_power = 0.0; // Find main lobes in oversampled image if (!find_mainlobe(amplitude, azimuth_profile, bigSize, peak_line, clutter_power, &mainlobe_azimuth_min, &mainlobe_azimuth_max)) { fprintf(fpOut, " No mainlobes could be found for %s in azimuth!\n", crID); goto SKIP; } //printf("mainlobe azimuth: min = %d, max = %d\n", // mainlobe_azimuth_min, mainlobe_azimuth_max); if (!find_mainlobe(amplitude, range_profile, bigSize, peak_sample, clutter_power, &mainlobe_range_min, &mainlobe_range_max)) { fprintf(fpOut, " No mainlobes could be found for %s in range!\n", crID); goto SKIP; } //printf("mainlobe range: min = %d, max = %d\n", // mainlobe_range_min, mainlobe_range_max); // Calculate resolution in azimuth and range for profiles if (!calc_resolution(azimuth_profile, mainlobe_azimuth_min, mainlobe_azimuth_max, peak_line, meta->general->y_pixel_size, clutter_power, &azimuth_resolution)) fprintf(fpOut, " Negative azimuth resolution for %s - invalid result!" "\n", crID); //printf("azimuth resolution = %.2f\n", azimuth_resolution); if (!calc_resolution(range_profile, mainlobe_range_min, mainlobe_range_max, peak_sample, meta->general->x_pixel_size, clutter_power, &range_resolution)) fprintf(fpOut, " Negative range resolution for %s - invalid result!\n", crID); //printf("range resolution = %.2f\n", range_resolution); // Find peak of original data - thought we had that already: check !!! // Calculate the clutter power azimuth_resolution /= meta->general->x_pixel_size; range_resolution /= meta->general->y_pixel_size; clutter_power = calc_clutter_power(original_amplitude, srcSize, peak_sample, peak_line, azimuth_resolution, range_resolution); //printf(" Clutter power: %8.3f\n", clutter_power); // Calculate resolution in azimuth and range with estimated clutter power if (!calc_resolution(azimuth_profile, mainlobe_azimuth_min, mainlobe_azimuth_max, peak_line, meta->general->y_pixel_size, clutter_power, &azimuth_resolution)) fprintf(fpOut, " Negative azimuth resolution for %s - invalid result!" "\n", crID); if (!calc_resolution(range_profile, mainlobe_range_min, mainlobe_range_max, peak_sample, meta->general->x_pixel_size, clutter_power, &range_resolution)) fprintf(fpOut, " Negative range resolution for %s - invalid result!\n", crID); //printf(" Azimuth resolution: %.3f\n", azimuth_resolution); //printf(" Range resolution: %.3f\n", range_resolution); // Find sidelobes in oversampled image and calculate the point-to-sidelobe // ratio in azimuth and range direction if (find_sidelobe(azimuth_profile, bigSize, 1, peak_line, mainlobe_azimuth_max, &sidelobe_azimuth_max) && find_sidelobe(azimuth_profile, bigSize, -1, peak_line, mainlobe_azimuth_min, &sidelobe_azimuth_min)) { if (!calc_pslr(azimuth_profile, bigSize, peak_line, sidelobe_azimuth_min, sidelobe_azimuth_max, &azimuth_pslr)) //printf(" Azimuth PSLR: %.3f\n", azimuth_pslr); //printf(" No valid PSLR in azimuth could be determined!\n"); ; } else { fprintf(fpOut, " Problem in finding sidelobes for %s in azimuth - " "invalid PSLR!\n", crID); } if (find_sidelobe(range_profile, bigSize, 1, peak_sample, mainlobe_range_max, &sidelobe_range_max) && find_sidelobe(range_profile, bigSize, -1, peak_sample, mainlobe_range_min, &sidelobe_range_min)) { if (!calc_pslr(range_profile, bigSize, peak_sample, sidelobe_range_min, sidelobe_range_max, &range_pslr)) //printf(" Range PSLR: %.3f\n", range_pslr); //printf(" No valid PSLR in range could be determined!\n"); ; } else { fprintf(fpOut, " Problem in finding sidelobes for %s in range -" " invalid PSLR!\n", crID); } //printf("sidelobe_azimuth: min = %d, max = %d\n", // sidelobe_azimuth_min, sidelobe_azimuth_max); //printf("sidelobe_range: min = %d, max = %d\n", // sidelobe_range_min, sidelobe_range_max); // Calculate the signal-to-clutter ratio (SCR) peak_power = amplitude[peak_line*bigSize+peak_sample] * amplitude[peak_line*bigSize+peak_sample]; if (clutter_power>0 && peak_power>clutter_power) scr = 10 * log((peak_power - clutter_power)/clutter_power); else scr = 0.0; if (peak_power > 0.0) { peak_power = 10 * log(peak_power); //printf(" Peak power: %.3f\n", peak_power); //printf(" SCR: %.3f\n", scr); } else fprintf(fpOut, " Negative peak power - invalid result!\n"); FREE(amplitude); FREE(original_amplitude); // Write values in output files fprintf(fpOut, "%s\t%.4lf\t%.4lf\t%.1lf\t%.1lf\t%.1f\t%.3f\t" "%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", crID, lat, lon, elev, posX-srcSize+srcPeakY, posY-srcSize+srcPeakX, look_angle*R2D, azimuth_resolution, range_resolution, azimuth_pslr, range_pslr, scr); SKIP: continue; } else fprintf(fpOut, "\n WARNING: Target %s outside the image boundaries!\n", crID); } FCLOSE(fpIn); FCLOSE(fpOut); FREE(meta); return(0); }