void update_pixel_info(ImageInfo *ii) { // update the left-hand "clicked pixel" information char buf[512]; GtkWidget *img = get_widget_checked("big_image"); GdkPixbuf *shown_pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(img)); double x = crosshair_samp; double y = crosshair_line; int nl = ii->meta->general->line_count; int ns = ii->meta->general->sample_count; CachedImage *data_ci = ii->data_ci; meta_parameters *meta = ii->meta; sprintf(buf, "Line: %.1f, Sample: %.1f\n", y, x); if (x < 0 || x >= ns || y < 0 || y >= nl) { // outside of the image sprintf(&buf[strlen(buf)], "Pixel Value: (outside image)\n"); } else { assert(meta); assert(shown_pixbuf); if (data_ci->data_type == GREYSCALE_FLOAT) { float fval = cached_image_get_pixel(data_ci, crosshair_line, crosshair_samp); if (have_lut()) { unsigned char r, g, b; cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp, &r, &g, &b); if (is_ignored(&ii->stats, fval)) { sprintf(&buf[strlen(buf)], "Pixel Value: %f [ignored]\n", fval); } else { sprintf(&buf[strlen(buf)], "Pixel Value: %f -> R:%d G:%d B:%d\n", fval, (int)r, (int)g, (int)b); } } else { int uval = calc_scaled_pixel_value(&(ii->stats), fval); if (is_ignored(&ii->stats, fval)) { sprintf(&buf[strlen(buf)], "Pixel Value: %f [ignored]\n", fval); } else { sprintf(&buf[strlen(buf)], "Pixel Value: %f -> %d\n", fval, uval); } } } else if (data_ci->data_type == RGB_BYTE) { unsigned char r, g, b; float rf, gf, bf; cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp, &r, &g, &b); cached_image_get_rgb_float(data_ci, crosshair_line, crosshair_samp, &rf, &gf, &bf); if (!is_ignored_rgb(&ii->stats_r, rf) && !is_ignored_rgb(&ii->stats_g, gf) && !is_ignored_rgb(&ii->stats_b, bf)) { sprintf(&buf[strlen(buf)], "Pixel Value: R,G,B = %d, %d, %d\n", (int)r, (int)g, (int)b); } else { sprintf(&buf[strlen(buf)], "Pixel Value: R,G,B = %d,%d,%d [ignored]\n", (int)rf, (int)gf, (int)bf); } } else if (data_ci->data_type == GREYSCALE_BYTE) { unsigned char r, g, b; cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp, &r, &g, &b); if (have_lut()) { int gs = (int)cached_image_get_pixel(data_ci, crosshair_line, crosshair_samp); if (is_ignored(&ii->stats, (float)gs)) sprintf(&buf[strlen(buf)], "Pixel Value: %d [ignored]\n", gs); else sprintf(&buf[strlen(buf)], "Pixel Value: %d -> R:%d G:%d B:%d\n", gs, (int)r, (int)g, (int)b); } else { int gs = (int)cached_image_get_pixel(data_ci, crosshair_line, crosshair_samp); if (is_ignored(&ii->stats, gs)) { sprintf(&buf[strlen(buf)], "Pixel Value: %d [ignored]\n", gs); } else if (ii->stats.truncate) { sprintf(&buf[strlen(buf)], "Pixel Value: %d\n", gs); } else { sprintf(&buf[strlen(buf)], "Pixel Value: %d -> %d\n", gs, (int)r); } } } else if (data_ci->data_type == RGB_FLOAT) { unsigned char r, g, b; float rf, gf, bf; cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp, &r, &g, &b); cached_image_get_rgb_float(data_ci, crosshair_line, crosshair_samp, &rf, &gf, &bf); if (is_ignored_rgb(&ii->stats_r, rf)) sprintf(&buf[strlen(buf)], "Red: %f [ignored]\n", rf); else sprintf(&buf[strlen(buf)], "Red: %f -> %d\n", rf, (int)r); if (is_ignored_rgb(&ii->stats_g, gf)) sprintf(&buf[strlen(buf)], "Green: %f [ignored]\n", gf); else sprintf(&buf[strlen(buf)], "Green: %f -> %d\n", gf, (int)g); if (is_ignored_rgb(&ii->stats_b, bf)) sprintf(&buf[strlen(buf)], "Blue: %f [ignored]\n", rf); else sprintf(&buf[strlen(buf)], "Blue: %f -> %d\n", bf, (int)b); } } double lat=0, lon=0; if (meta_supports_meta_get_latLon(meta)) { meta_get_latLon(meta, y, x, 0, &lat, &lon); sprintf(&buf[strlen(buf)], "Lat, Lon: %.5f, %.5f (deg)\n", lat, lon); //double px, py; //latLon2UTM(lat,lon,0,&px,&py); //printf("%14.7f %14.7f --> %13.2f %13.2f\n", lat, lon, px, py); } // skip projection coords if not projected, or lat/long pseudo (since // in that case the projection coords are just the lat/long values // we are already showing) if (meta->projection && meta->projection->type != LAT_LONG_PSEUDO_PROJECTION) { double projX, projY, projZ; latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0, &projX, &projY, &projZ); sprintf(&buf[strlen(buf)], "Proj X,Y: %.1f, %.1f m\n", projX, projY); } if (!meta->projection && meta->state_vectors && meta->sar) { double s,t; meta_get_timeSlantDop(meta, y, x, &t, &s, NULL); sprintf(&buf[strlen(buf)], "Incid: %.4f, Look: %.4f (deg)\n" "Slant: %.1f m Time: %.3f s\n" "Yaw: %.4f (deg)\n", R2D*meta_incid(meta,y,x), R2D*meta_look(meta,y,x), s, t, R2D*meta_yaw(meta,y,x)); } if (meta->projection && meta->projection->type != LAT_LONG_PSEUDO_PROJECTION && meta->projection->type != SCANSAR_PROJECTION) { distortion_t d; map_distortions(meta->projection, lat*D2R, lon*D2R, &d); sprintf(&buf[strlen(buf)], "Meridian scale factor: %.6f\n", d.h); sprintf(&buf[strlen(buf)], "Parallel scale factor: %.6f\n", d.k); sprintf(&buf[strlen(buf)], "Areal scale factor: %.6f\n", d.s); sprintf(&buf[strlen(buf)], "Angular distortion: %.4f (deg)\n", d.omega); } if (g_poly->n > 0) { // start distance measure at crosshair coords double cross_x, cross_y, prev_x, prev_y; line_samp_to_proj(ii, y, x, &cross_x, &cross_y); prev_x = cross_x; prev_y = cross_y; // iterate through ctrl-clicked coords int i; double d=0, A=0; // d=distance, A=area for (i=0; i<g_poly->n; ++i) { double proj_x, proj_y; line_samp_to_proj(ii, g_poly->line[i], g_poly->samp[i], &proj_x, &proj_y); d += hypot(proj_x-prev_x, proj_y-prev_y); A += prev_x * proj_y - proj_x * prev_y; prev_x = proj_x; prev_y = proj_y; // for the area calc, we close the polygon automatically if (i==g_poly->n-1) A += prev_x * cross_y - cross_x * prev_y; } A /= 2.; char *units = "m"; if (!meta_supports_meta_get_latLon(meta)) units = "pixels"; if (g_poly->n == 1) sprintf(&buf[strlen(buf)], "Distance to %.1f,%.1f: %.1f %s", g_poly->line[0], g_poly->samp[0], d, units); else sprintf(&buf[strlen(buf)], "Total distance: %.1f %s (%d points)\n" "Area (of closure): %.1f %s^2", d, units, g_poly->n+1, fabs(A), units); } else { sprintf(&buf[strlen(buf)], "Distance: (ctrl-click to measure)"); } put_text_in_textview(buf, "info_textview"); //GtkWidget *lbl = get_widget_checked("upper_label"); //gtk_label_set_text(GTK_LABEL(lbl), buf); }
static float get_data(ImageInfo *ii, int what_to_save, int line, int samp) { double t, s, d; meta_parameters *meta = ii->meta; CachedImage *data_ci = ii->data_ci; switch (what_to_save) { case PIXEL_VALUE: if (ii->data_ci->data_type == RGB_FLOAT) { // can't handle RGB subsets... return average of RGB values float r, g, b; cached_image_get_rgb_float(data_ci, line, samp, &r, &g, &b); return (r+g+b)/3.; } else { return cached_image_get_pixel(data_ci, line, samp); } case INCIDENCE_ANGLES: if (meta->sar) return R2D*meta_incid(meta, line, samp); else return 0; case LOOK_ANGLE: if (meta->sar) return R2D*meta_look(meta, line ,samp); else return 0; case SLANT_RANGE: if (meta->sar) { meta_get_timeSlantDop(meta, line, samp, &t, &s, NULL); return s; } else return 0; case SCALED_PIXEL_VALUE: if (ii->data_ci->data_type == RGB_FLOAT) { // can't handle RGB subsets... return average of scaled values float r, g, b; cached_image_get_rgb_float(data_ci, line, samp, &r, &g, &b); int rs = calc_rgb_scaled_pixel_value(&(ii->stats_r), r); int gs = calc_rgb_scaled_pixel_value(&(ii->stats_g), g); int bs = calc_rgb_scaled_pixel_value(&(ii->stats_b), b); return (rs+gs+bs)/3.; } else { return calc_scaled_pixel_value(&(ii->stats), cached_image_get_pixel(data_ci, line, samp)); } case TIME: if (meta->sar) { meta_get_timeSlantDop(meta, line, samp, &t, &s, NULL); return t; } else return 0; case DOPPLER: if (meta->sar) { meta_get_timeSlantDop(meta, line, samp, &t, &s, &d); return d; } else return 0; default: assert(0); return 0; } }
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); }