/* * Khoros: $Id$ */ #if !defined(__lint) && !defined(__CODECENTER__) static char rcsid[] = "Khoros: $Id$"; #endif /* * Copyright (C) 1997, INPE. Sergio Donizete Faria, Gerald Jean Francis Banon * All rights reserved. See $K_PROG/repos/license/License. */ /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<< >>>> >>>> Main program for klgmax >>>> >>>> Private: >>>> main >>>> >>>> Static: >>>> Public: >>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<< */ #include "klgmax.h" clui_info_struct *clui_info = NULL; /*----------------------------------------------------------- | | Routine Name: main() - Search for global maximum and generate a binary image and report | | Purpose: main program for klgmax | | Input: | char *clui_info->i_img_file; {Input data object} | int clui_info->i_img_flag; {TRUE if -i_img specified} | | char *clui_info->o_img_file; {Resulting output data object} | int clui_info->o_img_flag; {TRUE if -o_img specified} | | char *clui_info->f_file; {Formatted ASCII output file} | int clui_info->f_flag; {TRUE if -f specified} | | int clui_info->wpoint_int; {Specifies the expected point width} | int clui_info->wpoint_flag; {TRUE if -wpoint specified} | | int clui_info->hpoint_int; {Specifies the expected point height} | int clui_info->hpoint_flag; {TRUE if -hpoint specified} | | int clui_info->wsize_int; {Specifies the region width} | int clui_info->wsize_flag; {TRUE if -wsize specified} | | int clui_info->hsize_int; {Specifies the region height} | int clui_info->hsize_flag; {TRUE if -hsize specified} | | Output: | Returns: | | Written By: Sergio Donizete Faria | Date: November 10, 1997 | Modifications: June 24, 1998; October 30, 1998 | ------------------------------------------------------------*/ int main( int argc, char **argv) { /* -main_variable_list */ kobject src; /* source object - input search image */ kobject dest; /* destination object - output image */ kfile *ascii_file=NULL; char *filename=NULL; int output_ascii; int src_width; /* input image width (num cols) */ int src_height; /* input image height (num rows) */ int src_depth; /* depth and time give number of input images */ int src_time; int src_bands; /* number of bands per input image */ int num_regions, num_of_max, dim_src; int type1; int h, i, i0, i1, j, k, k0, k1; int width_expected, height_expected, sum_height, sum_width; double vmax, alfa1, alfa2, alfa3, alfa4, alfa123, alfa14; double dist, dist_max, dist_min; double dist_gc, gravity_center_h, gravity_center_w; double sum_src; int region_width, region_height; int shift_region_width, shift_region_height, shift_i0, shift_j; double *src_data=NULL; double *dest_data=NULL; /* -main_variable_list_end */ khoros_init(argc, argv, "MATCHING", PRODUCT_RELEASE_DATE, PRODUCT_RELEASE_NAME, PRODUCT_RELEASE_VERSION, PRODUCT_RELEASE_MAJOR, PRODUCT_RELEASE_MINOR, "$MATCHING/objects/kroutine/klgmax"); kexit_handler(klgmax_free_args, NULL); /* -main_get_args_call */ kclui_init("MATCHING", "klgmax", KGEN_KROUTINE, &clui_uis_spec, klgmax_usage_additions, klgmax_get_args, klgmax_free_args); /* -main_get_args_call_end */ /* -main_before_lib_call */ /* * Open the source (src) and destination (dest) data objects using * kpds_open_input_object and kpds_open_output_object calls. These calls * will open the source and destination data object with the flags set * correctly. If an open fails, report the error using kerror, close * opened objects if necessary, and exit the program using kexit call. */ if ((src = kpds_open_input_object (clui_info->i_img_file)) == KOBJECT_INVALID) { kerror(NULL, "klgmax", "Cannot open source object src."); kexit(KEXIT_FAILURE); } if ((dest = kpds_open_output_object (clui_info->o_img_file)) == KOBJECT_INVALID) { kerror(NULL, "klgmax", "Cannot open destination object."); kpds_close_object(src); kexit(KEXIT_FAILURE); } /* * Copy the source object src to destination object. If the copy * function fails, report the error and exit. The object will be closed * by kexit. Since, the exit status is KEXIT FAILURE the output object * will not be written to a permanent transport. */ if (! kpds_copy_object (src, dest)) { kerror(NULL, "klgmax", "kpds_copy_object failed"); kexit(KEXIT_FAILURE); } /* * Open the ASCII output file. */ output_ascii = TRUE; if (clui_info->f_flag) ascii_file = kfopen(clui_info->f_file, "w"); else output_ascii = FALSE; if (output_ascii) { filename = kbasename(clui_info->i_img_file, NULL); kfprintf(ascii_file, "FILE: %s\n",filename); } /* * Check the datatype, and return if the data is complex. Set the * presentation type to double. */ if (! kpds_get_attribute(src, KPDS_VALUE_DATA_TYPE, &type1)) { kerror("klgmax", "main", "kpds_get_attribute failed for KPDS_VALUE_DATA_TYPE"); kexit(KEXIT_FAILURE); } if ((type1 == KCOMPLEX) || (type1 == KDCOMPLEX)) { kerror("klgmax", "main", "Cannot compute complex statistics at this time.\n"); kexit(KEXIT_FAILURE); } type1 = KDOUBLE; if (! kpds_set_attribute(src, KPDS_VALUE_DATA_TYPE, type1)) { kerror("klgmax", "main", "kpds_set_attribute failed for KPDS_VALUE_DATA_TYPE"); kexit(KEXIT_FAILURE); } /* * Get the KPDS_VALUE_SIZE attribute of the source object (src) which * provides the information about number of data elements in each * direction of source object. */ if (! kpds_get_attribute (src, KPDS_VALUE_SIZE, &src_width, &src_height, &src_depth, &src_time, &src_bands)) { kerror(NULL,"klgmax", "kpds_get_attribute failed for KPDS_VALUE_SIZE"); kexit(KEXIT_FAILURE); } /* * Specifying the size of the region to process by selection a set of * rows from the source image as the region process. * Set this region size to: * - src_width = width of region (width source image) * - 1 = height of region * - 1 = depth size of region * - 1 = time size of region * - 1 = number of bands in the region */ if (! kpds_set_attribute (src, KPDS_VALUE_REGION_SIZE, src_width, 1, 1, 1, 1)) { kerror("NULL", "klgmax", "kpds_set_attribute failed for KPDS_VALUE_REGION_SIZE"); kexit(KEXIT_FAILURE); } if (! kpds_set_attribute (dest, KPDS_VALUE_REGION_SIZE, src_width, 1, 1, 1, 1)) { kerror("NULL", "klgmax", "kpds_set_attribute failed for KPDS_VALUE_REGION_SIZE (dest)"); kexit(KEXIT_FAILURE); } /* * If ascii output, print the object size now */ if (output_ascii) { kfprintf(ascii_file," Matching points: "); kfprintf(ascii_file,"\n"); } /* *********************************************************************** * Loop for search maximum *********************************************************************** */ /* * Outer loops: variable h and i are the number of images in input * object. */ dim_src = src_width * src_height; for (h = 0; h < src_time; h++) { for (i = 0; i < src_depth; i++) { /* * 1st Middle loop: variable is the number of bands (elements) * to process. * - src_bands = number of bands (elements) per image in source * object */ for ( k = 0; k < src_bands; k++) { /* * 2nd Middle loop: variable is the number of regions to * process * - num_regions = number of rows (height) of source object */ num_regions = src_height; j = 0; vmax = (- 1) * dim_src; for (i1 = 0; i1 < num_regions; i1++) { /* * Get a region of data and apply the operator across that * region. */ kpds_set_attribute(src, KPDS_VALUE_POSITION, 0, j, i, h, k); src_data = (double *)(kpds_get_data(src, KPDS_VALUE_REGION, src_data)); if (src_data == NULL) { kerror("NULL", "klgmax", "kpds_get_data failed for KPDS_VALUE_REGION src."); kexit(KEXIT_FAILURE); } /* * Inner loop: variable is the number of columns of region * to be processed. * - src_width = width of source object (input image) */ /* * Global Maximum */ for (i0 = 0; i0 < src_width; i0++) { if (src_data[i0] > vmax) vmax = src_data[i0]; } j++; } } } }/* end of loop */ /* *********************************************************************** * Loop for generate image with maximum and some assessment measure *********************************************************************** */ /* * Outer loops: variable h and i are the number of images in input * object. */ width_expected = clui_info->wpoint_int; height_expected = clui_info->hpoint_int; num_of_max = 0; dist_max = 0; dist_min = ksqrt(ksqr(src_width - 1) + ksqr(src_height - 1)); sum_height = 0; sum_width = 0; region_width = clui_info->wsize_int; region_height = clui_info->hsize_int; shift_region_width = region_width/2; shift_region_height = region_height/2; for (h = 0; h < src_time; h++) { for (i = 0; i < src_depth; i++) { /* * 1st Middle loop: variable is the number of bands (elements) * to process. * - src_bands = number of bands (elements) per image in source * object */ for ( k = 0; k < src_bands; k++) { /* * 2nd Middle loop: variable is the number of regions to * process * - num_regions = number of rows (height) of source object */ j = 0; for (i1 = 0; i1 < num_regions; i1++) { /* * Get a region of data and apply the operator across that * region. */ kpds_set_attribute(src, KPDS_VALUE_POSITION, 0, j, i, h, k); src_data = (double *)(kpds_get_data(src, KPDS_VALUE_REGION, src_data)); if (src_data == NULL) { kerror("NULL", "klgmax", "kpds_get_data failed for KPDS_VALUE_REGION src."); kexit(KEXIT_FAILURE); } /* * Get a region of data in which temporarily store the * results of the operator. */ kpds_set_attribute(dest, KPDS_VALUE_POSITION, 0, j, i, h, k); dest_data = (double *)(kpds_get_data(dest, KPDS_VALUE_REGION, dest_data)); if (dest_data == NULL) { kerror("NULL", "klgmax", "kpds_get_data failed for KPDS_VALUE_REGION dest."); kexit(KEXIT_FAILURE); } /* * Inner loop: variable is the number of columns of region * to be processed. * - src_width = width of source object (input image) */ /* * Generate binary image indicating where is the global * maximum and some assessment measure */ for (i0 = 0; i0 < src_width; i0++) { if (src_data[i0] == vmax) { dest_data[i0] = vmax; num_of_max ++; shift_i0 = i0 + shift_region_width; shift_j = j + shift_region_height; dist = ksqrt(ksqr(height_expected - shift_j) + ksqr(width_expected - shift_i0)); if (dist > dist_max) { dist_max = dist; } if (dist < dist_min) { dist_min = dist; } sum_height += shift_j; sum_width += shift_i0; if (num_of_max <= 10) { if (output_ascii) kfprintf(ascii_file," w=%d ", shift_i0); if (output_ascii) kfprintf(ascii_file,"h=%d ", shift_j); kfprintf(ascii_file,"\n"); } if (num_of_max == 11) { if (output_ascii) kfprintf(ascii_file," ... "); kfprintf(ascii_file,"\n"); } } else { if (vmax == 0.0) { dest_data[i0] = 1.0; } else { dest_data[i0] = 0.0; } } } if (! kpds_put_data(dest, KPDS_VALUE_REGION, dest_data)) { kerror("NULL", "klgmax", "kpds_put_data failed for destination object."); kexit(KEXIT_FAILURE); } j++; } } } }/* end of loop */ kfprintf(ascii_file,"\n"); kfprintf(ascii_file," Number of matching points: "); if (output_ascii) kfprintf(ascii_file, "%d ", num_of_max); kfprintf(ascii_file,"\n"); kfprintf(ascii_file," Value matching: "); if (output_ascii) kfprintf(ascii_file, " %g ", vmax); kfprintf(ascii_file,"\n"); gravity_center_h = sum_height/num_of_max; gravity_center_w = sum_width/num_of_max; dist_gc = ksqrt(ksqr(height_expected - gravity_center_h) + ksqr(width_expected - gravity_center_w)); alfa1 = (10.0 - num_of_max)/9.0; if (alfa1 < 0) { alfa1 = 0; } alfa2 = (3 - dist_min)/3; if (alfa2 < 0) { alfa2 = 0; } alfa3 = (3 - dist_max)/3; if (alfa3 < 0) { alfa3 = 0; } alfa4 = (3 - dist_gc)/3; if (alfa4 < 0) { alfa4 = 0; } alfa123 = alfa1 * alfa2 * alfa3; alfa14 = alfa1 * alfa4; kfprintf(ascii_file," Assesment measure: "); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa1 = %g ", alfa1); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa2 = %g ", alfa2); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa3 = %g ", alfa3); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa4 = %g ", alfa4); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa123 = %g ", alfa123); kfprintf(ascii_file,"\n"); if (output_ascii) kfprintf(ascii_file," alfa14 = %g ", alfa14); /* -main_before_lib_call_end */ /* -main_library_call */ /* -main_library_call_end */ /* -main_after_lib_call */ /* add history to the output object */ if (!kpds_set_attribute(dest, KPDS_HISTORY, kpds_history_string())) { kerror("klgmax", "main", "Unable to set history on the destination object"); kexit(KEXIT_FAILURE); } /* * If the library call succeeded, close the source, kernel and * destination data objects using kpds_close_object and exit * using kexit. */ kpds_close_object(src); kpds_close_object(dest); /* -main_after_lib_call_end */ kexit(KEXIT_SUCCESS); return KEXIT_SUCCESS; } /*----------------------------------------------------------- | | Routine Name: klgmax_usage_additions | | Purpose: Prints usage additions in klgmax_usage routine | | Input: None | | Output: None | Written By: ghostwriter -oname klgmax | Date: July 1, 1997 | Modifications: | ------------------------------------------------------------*/ void klgmax_usage_additions(void) { kfprintf(kstderr, "\tSearch for global maximum and generate a binary image and\n"); kfprintf(kstderr, "\treport\n"); /* -usage_additions */ /* -usage_additions_end */ } /*----------------------------------------------------------- | | Routine Name: klgmax_free_args | | Purpose: Frees CLUI struct allocated in klgmax_get_args() | | Input: None | | Output: None | Written By: ghostwriter -oname klgmax | Date: July 1, 1997 | Modifications: | ------------------------------------------------------------*/ /* ARGSUSED */ void klgmax_free_args( kexit_status status, kaddr client_data) { /* do the wild and free thing */ if (clui_info != NULL) { kfree_and_NULL(clui_info->i_img_file); kfree_and_NULL(clui_info->o_img_file); kfree_and_NULL(clui_info->f_file); kfree_and_NULL(clui_info); } /* -free_handler_additions */ /* -free_handler_additions_end */ }