/* * 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 knnsc >>>> >>>> Private: >>>> main >>>> >>>> Static: >>>> Public: >>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<< */ #include "knnsc.h" clui_info_struct *clui_info = NULL; /*----------------------------------------------------------- | | Routine Name: main() - Analyse and count if pixel value not belongs to an interval | | Purpose: main program for knnsc | | Input: | char *clui_info->i_img_file; {Search image} | int clui_info->i_img_flag; {TRUE if -i_img specified} | | char *clui_info->t_img_file; {Template image} | int clui_info->t_img_flag; {TRUE if -t_img specified} | | int clui_info->ref_img_mean_int; {Reference image mean} | int clui_info->ref_img_mean_flag; {TRUE if -ref_img_mean specified} | | int clui_info->search_img_mean_int; {Search image mean} | int clui_info->search_img_mean_flag; {TRUE if -search_img_mean specified} | | int clui_info->interval_length_int; {Interval length around template} | int clui_info->interval_length_flag; {TRUE if -interval_length specified} | | char *clui_info->o_img_file; {Resulting output image} | int clui_info->o_img_flag; {TRUE if -o_img specified} | | Output: | Returns: | | Written By: Sergio Donizete Faria | Date: July 1, 1997 | Modifications: | ------------------------------------------------------------*/ int main( int argc, char **argv) { /* -main_variable_list */ kobject template; /* source object - input template image */ kobject src; /* source object - input search image */ kobject inf_template; /* destination object - inferior template */ kobject sup_template; /* destination object - superior template */ kobject dest; /* destination object - output image */ double ref_img_mean; /* constant - reference image mean */ double src_img_mean; /* constant - search image mean */ int interval_length; /* constant - interval length around template */ int template_width; /* input template image width (num cols) */ int template_height; /* input template image height (num rows) */ int template_depth; /* depth and time give number of input template images */ int template_time; int template_bands; /* number of bands per input template image */ int src_width; /* input search image width (num cols) */ int src_height; /* input search image height (num rows) */ int src_depth; /* depth and time give number of input search images */ int src_time; int src_bands; /* number of bands per input search image */ int num_regions; int size_template; double dif_mean; double shift_inf_template; double shift_sup_template; int h, i, i1, k, n; int hh, ii, jj, kk; int ii0, ii1, kk0, kk1; int index0, index1, aux1; int thresh; int num_not_sat_cond; double *template_data=NULL; double *inf_template_data=NULL; double *sup_template_data=NULL; 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/knnsc"); kexit_handler(knnsc_free_args, NULL); /* -main_get_args_call */ kclui_init("MATCHING", "knnsc", KGEN_KROUTINE, &clui_uis_spec, knnsc_usage_additions, knnsc_get_args, knnsc_free_args); /* -main_get_args_call_end */ /* -main_before_lib_call */ /* * Open the source (template and search image) and destination * (inf_template, sup_template and 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 ((template = kpds_open_input_object (clui_info->t_img_file)) == KOBJECT_INVALID) { kerror(NULL, "knnsc", "Cannot open source object template."); kexit(KEXIT_FAILURE); } if ((src = kpds_open_input_object (clui_info->i_img_file)) == KOBJECT_INVALID) { kerror(NULL, "knnsc", "Cannot open source object src."); kexit(KEXIT_FAILURE); kpds_close_object(template); } if ((dest = kpds_open_output_object (clui_info->o_img_file)) == KOBJECT_INVALID) { kerror(NULL, "knnsc", "Cannot open destination object (output image)."); kpds_close_object(template); kpds_close_object(src); kexit(KEXIT_FAILURE); } /* * Create temporary (inf_template and sup_template and dest) data * objects using kpds_create__object calls. These calls will the create * temporary data object with the flags set correctly. If a creation * fails, report the error using kerror and exit the program using kexit * call. */ if ((inf_template = kpds_create_object ()) == KOBJECT_INVALID) { kerror(NULL, "knnsc", "Cannot create object inf_template."); kexit(KEXIT_FAILURE); } if ((sup_template = kpds_create_object ()) == KOBJECT_INVALID) { kerror(NULL, "knnsc", "Cannot create object sup_template."); kexit(KEXIT_FAILURE); } /* * Copy the template and search image object to destination and * temporary objects. If the copy function fails, report the error and * exit. The object will be closed by kexit call. Since, the exit status * is KEXIT FAILURE the output object will not be writen to a permanent * transport. */ if (! kpds_copy_object (template, inf_template)) { kerror(NULL, "knnsc", "kpds_copy_object failed"); kexit(KEXIT_FAILURE); } if (! kpds_copy_object (template, sup_template)) { kerror(NULL, "knnsc", "kpds_copy_object failed"); kexit(KEXIT_FAILURE); } if (! kpds_copy_object (src, dest)) { kerror(NULL, "knnsc", "kpds_copy_object failed"); kexit(KEXIT_FAILURE); } /* Attribution of variables */ ref_img_mean = clui_info->ref_img_mean_int; src_img_mean = clui_info->search_img_mean_int; interval_length = clui_info->interval_length_int; dif_mean = src_img_mean - ref_img_mean; shift_inf_template = dif_mean - interval_length/2; shift_sup_template = dif_mean + interval_length/2; /* * Get the KPDS_VALUE_SIZE attribute of the object template, which * provides the information about number of data elements in each * direction of source object. */ if (! kpds_get_attribute (template, KPDS_VALUE_SIZE, &template_width, &template_height,&template_depth, &template_time, &template_bands)) { kerror(NULL,"knnsc","kpds_get_attribute failed for KPDS_VALUE_SIZE"); 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,"knnsc","kpds_get_attribute failed for KPDS_VALUE_SIZE"); kexit(KEXIT_FAILURE); } /* * Specifying the size of the region to process the template. * Set this region size to: * - template_width = width of region (template image width) * - template_height = height of region * - template_depth = depth size of region * - template_time = time size of region * - template_bands = number of bands in the region */ if (! kpds_set_attribute (template, KPDS_VALUE_REGION_SIZE, template_width, template_height, template_depth, template_time,template_bands)) { kerror("NULL", "knnsc", "kpds_get_attribute failed for KPDS_VALUE_REGION_SIZE (template)."); kexit(KEXIT_FAILURE); } if (! kpds_set_attribute (inf_template, KPDS_VALUE_REGION_SIZE, template_width, template_height, template_depth,template_time,template_bands)) { kerror("NULL", "knnsc", "kpds_get_attribute failed for KPDS_VALUE_REGION_SIZE (inf_template)."); kexit(KEXIT_FAILURE); } if (! kpds_set_attribute (sup_template, KPDS_VALUE_REGION_SIZE, template_width, template_height, template_depth,template_time,template_bands)) { kerror("NULL", "knnsc", "kpds_get_attribute failed for KPDS_VALUE_REGION_SIZE (sup_template)."); 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 (source image width) * - template_height = height of region * - template_depth = depth size of region * - template_time = time size of region * - template_bands = number of bands in the region */ if (! kpds_set_attribute (src, KPDS_VALUE_REGION_SIZE, src_width, template_height, template_depth, template_time, template_bands)) { kerror("NULL", "knnsc", "kpds_get_attribute failed for KPDS_VALUE_REGION_SIZE"); kexit(KEXIT_FAILURE); } if (! kpds_set_attribute (dest, KPDS_VALUE_REGION_SIZE, src_width, template_height, template_depth, template_time, template_bands)) { kerror("NULL", "knnsc", "kpds_get_attribute failed for KPDS_VALUE_REGION_SIZE (dest)"); kexit(KEXIT_FAILURE); } /* ********************************************************************** * Major loop for processing ********************************************************************** */ /* * Outer loops: variable h and i are the number of images in input * object. */ for (h = 0; h < template_time; h++) { for (i = 0; i < template_depth; i++) { /* * 1st Middle loop: variable is the number of bands (elements) to * process. * - template_bands = number of bands (elements) per template * image in source object */ for ( k = 0; k < template_bands; k++) { /* * Get a region of data and generate inf_template and * sup_template. */ kpds_set_attribute(template,KPDS_VALUE_POSITION,0,0,i,h,k); template_data = (double *)(kpds_get_data(template, KPDS_VALUE_REGION, template_data)); if (template_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_REGION."); kexit(KEXIT_FAILURE); } /* * Get a region of data in which temporarily store the results * of generation templates. */ kpds_set_attribute(inf_template, KPDS_VALUE_POSITION, 0, 0, i, h, k); inf_template_data = (double *)(kpds_get_data(inf_template, KPDS_VALUE_REGION, inf_template_data)); if (inf_template_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_REGION inf_template."); kexit(KEXIT_FAILURE); } kpds_set_attribute(sup_template, KPDS_VALUE_POSITION, 0, 0, i, h, k); sup_template_data = (double *)(kpds_get_data(sup_template, KPDS_VALUE_REGION, sup_template_data)); if (sup_template_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_REGION sup_template."); kexit(KEXIT_FAILURE); } /* * 2nd Middle loop: variable is the number of regions to * process * - size_template = size (height x width) of source * object (template) */ size_template = template_height * template_width; for (i1 = 0; i1 < size_template; i1++) { inf_template_data[i1] = template_data[i1] + shift_inf_template; sup_template_data[i1] = template_data[i1] + shift_sup_template; } if (! kpds_put_data(inf_template, KPDS_VALUE_REGION, inf_template_data)) { kerror("NULL", "knnsc", "kpds_put_data failed for destination object inf_template."); kexit(KEXIT_FAILURE); } if (! kpds_put_data(sup_template, KPDS_VALUE_REGION, sup_template_data)) { kerror("NULL", "knnsc", "kpds_put_data failed for destination object sup_template."); kexit(KEXIT_FAILURE); } } } }/* end of loop */ inf_template_data = (double *)(kpds_get_data(inf_template, KPDS_VALUE_ALL, inf_template_data)); if (inf_template_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_ALL."); kexit(KEXIT_FAILURE); } sup_template_data = (double *)(kpds_get_data(sup_template, KPDS_VALUE_ALL, sup_template_data)); if (sup_template_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_ALL."); kexit(KEXIT_FAILURE); } /* * Outer loops: variable hh and ii are the number of images in input * object. */ thresh = size_template; for (hh = 0; hh < src_time; hh++) { for (ii = 0; ii < src_depth; ii++) { /* * 1st Middle loop: variable is the number of bands (elements) to * process. * - src_bands = number of bands (elements) per image in source * object */ for ( kk = 0; kk < src_bands; kk++) { /* * 2nd Middle loop: variable is the number of regions to * process. * - num_regions = number of rows (height) of source object */ num_regions = src_height; jj = 0; for (ii1 = template_height-1; ii1 < num_regions; ii1++) { /* * Get a region of data and apply the operator across that * region. */ kpds_set_attribute(src,KPDS_VALUE_POSITION,0,jj,ii,hh,kk); src_data = (double *)(kpds_get_data(src, KPDS_VALUE_REGION, src_data)); if (src_data == NULL) { kerror("NULL", "knnsc", "kpds_get_data failed for KPDS_VALUE_REGION."); kexit(KEXIT_FAILURE); } /* * Get a region of data in which temporarily store the * results of operator. */ kpds_set_attribute(dest,KPDS_VALUE_POSITION,0,jj,ii,hh,kk); dest_data = (double *)(kpds_get_data(dest,KPDS_VALUE_REGION, dest_data)); if (dest_data == NULL) { kerror("NULL", "knnsc", "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) * - template_width = width of template image */ /* * Number of Not Satisfied Conditions. */ for (ii0 = template_width - 1; ii0 < src_width; ii0++) { num_not_sat_cond = 0; index1 = template_height - 1; for (kk1 = 0; kk1 < template_height; kk1++) { index0 = index1 * src_width + ii0; for (kk0 = 0; kk0 < template_width; kk0++) { n = template_width * template_height - template_width * kk1 - kk0 - 1; if (inf_template_data[n] > src_data[index0] || sup_template_data[n] < src_data[index0]) { num_not_sat_cond++; index0--; } else { index0--; } if (num_not_sat_cond > thresh) { kk0 = template_width; kk1 = template_height; } } index1--; } if (thresh > num_not_sat_cond) { thresh = num_not_sat_cond; } aux1 = ii0 - (((template_width - 1)/2) - 1) + (((template_width - 1)/2) * src_width - 1); dest_data[aux1] = num_not_sat_cond; } if (! kpds_put_data(dest, KPDS_VALUE_REGION, dest_data)) { kerror("NULL", "knnsc", "kpds_put_data failed for destination object."); kexit(KEXIT_FAILURE); } jj++; } } } }/* end of loop */ /* -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("knnsc", "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(template); kpds_close_object(dest); kpds_close_object(inf_template); kpds_close_object(sup_template); /* -main_after_lib_call_end */ kexit(KEXIT_SUCCESS); return KEXIT_SUCCESS; } /*----------------------------------------------------------- | | Routine Name: knnsc_usage_additions | | Purpose: Prints usage additions in knnsc_usage routine | | Input: None | | Output: None | Written By: ghostwriter -oname knnsc | Date: July 1, 1997 | Modifications: | ------------------------------------------------------------*/ void knnsc_usage_additions(void) { kfprintf(kstderr, "\tAnalyse and count if pixel value not belongs to an interval\n"); /* -usage_additions */ /* -usage_additions_end */ } /*----------------------------------------------------------- | | Routine Name: knnsc_free_args | | Purpose: Frees CLUI struct allocated in knnsc_get_args() | | Input: None | | Output: None | Written By: ghostwriter -oname knnsc | Date: July 1, 1997 | Modifications: | ------------------------------------------------------------*/ /* ARGSUSED */ void knnsc_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->t_img_file); kfree_and_NULL(clui_info->o_img_file); kfree_and_NULL(clui_info); } /* -free_handler_additions */ /* -free_handler_additions_end */ }