diff --git a/Modules/ThirdParty/Edison/CMakeLists.txt b/Modules/ThirdParty/Edison/CMakeLists.txt deleted file mode 100644 index bd4f9350ab1e77aaeada29c84e8c3b6727c47a12..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(OTBEdison) -set(OTBEdison_THIRD_PARTY 1) - -set(OTBEdison_INCLUDE_DIRS ${OTBEdison_SOURCE_DIR}/src/otbedison) -set(OTBEdison_LIBRARIES otbedison) - -otb_module_impl() diff --git a/Modules/ThirdParty/Edison/otb-module.cmake b/Modules/ThirdParty/Edison/otb-module.cmake deleted file mode 100644 index f6eb4164105b575503d9e910c8c4a78c11cdc91c..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/otb-module.cmake +++ /dev/null @@ -1,12 +0,0 @@ -set(DOCUMENTATION "This module imports Edison to the build system") - -otb_module(OTBEdison - DEPENDS - - TEST_DEPENDS - - DESCRIPTION - "${DOCUMENTATION}" - ) - -otb_module_activation_option("Enable Edison segmentation dependent modules" ON) diff --git a/Modules/ThirdParty/Edison/src/CMakeLists.txt b/Modules/ThirdParty/Edison/src/CMakeLists.txt deleted file mode 100644 index efe306e322999a226b7c65ce9047639190cad87e..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -set(OTB3P_INSTALL_EXPORT_NAME "${OTBEdison-targets}") -set(OTB3P_INSTALL_INCLUDE_DIR "${OTBEdison_INSTALL_INCLUDE_DIR}") -set(OTB3P_INSTALL_RUNTIME_DIR "${OTBEdison_INSTALL_RUNTIME_DIR}") -set(OTB3P_INSTALL_LIBRARY_DIR "${OTBEdison_INSTALL_LIBRARY_DIR}") -set(OTB3P_INSTALL_ARCHIVE_DIR "${OTBEdison_INSTALL_ARCHIVE_DIR}") - -set(EDISON_SOURCES -# prompt/parser.cpp -# prompt/globalFnc.cpp -# prompt/edison.cpp -# prompt/libppm.cpp - otbedison/msSysPrompt.cpp - otbedison/ms.cpp - otbedison/msImageProcessor.cpp - otbedison/RAList.cpp - otbedison/rlist.cpp -# edge/BgEdge.cpp -# edge/BgEdgeDetect.cpp -# edge/BgEdgeList.cpp -# edge/BgGlobalFc.cpp -# edge/BgImage.cpp - ) - -set(EDISON_HEADERS -# prompt/parser.h -# prompt/defs.h -# prompt/error.h -# prompt/flags.h -# prompt/edison.h -# prompt/imfilt.h -# prompt/libppm.h - otbedison/tdef.h - otbedison/RAList.h - otbedison/ms.h - otbedison/msImageProcessor.h - otbedison/msSys.h - otbedison/rlist.h -# edge/BgDefaults.h -# edge/BgEdge.h -# edge/BgEdgeDetect.h -# edge/BgImage.h - ) - -add_library(otbedison ${EDISON_SOURCES}) - -# Apply user-defined properties to the library target. -if(OTB_LIBRARY_PROPERTIES) - set_target_properties(otbedison PROPERTIES ${OTB_LIBRARY_PROPERTIES}) -endif(OTB_LIBRARY_PROPERTIES) - -install(TARGETS otbedison - EXPORT ${OTB3P_INSTALL_EXPORT_NAME} - RUNTIME DESTINATION ${OTB3P_INSTALL_RUNTIME_DIR} COMPONENT RuntimeLibraries - LIBRARY DESTINATION ${OTB3P_INSTALL_LIBRARY_DIR} COMPONENT RuntimeLibraries - ARCHIVE DESTINATION ${OTB3P_INSTALL_ARCHIVE_DIR} COMPONENT Development - ) - -# Forced to install edison headers into the main include dir -# unless we patch the includes to add a "otbedison" root dir -# in all #include directives -install(FILES - ${EDISON_HEADERS} - DESTINATION ${OTB3P_INSTALL_INCLUDE_DIR} - COMPONENT Development - ) - -otb_module_target( otbedison NO_INSTALL ) \ No newline at end of file diff --git a/Modules/ThirdParty/Edison/src/otbedison/MSReadme.txt b/Modules/ThirdParty/Edison/src/otbedison/MSReadme.txt deleted file mode 100644 index dfd4ccb7955de11a604467d8219c1719e21ee66b..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/MSReadme.txt +++ /dev/null @@ -1,176 +0,0 @@ -Mean Shift Image Processor Class ver1.0 README ----------------------------------------------- - -Class Overview: -=============== - -The mean shift image processor class is designed to offer the following functionality: - - (1) Perform image segmentation and edge-preserving filtering using the mean shift algorithm. - (2) Perform (1) using a general kernel and/or an arbitrary input data space. - -Table of Contents: -------------------- -(A) Image Segmentation and Filtering -(B) Synergistic Image Segmentation -(C) Using a General Kernel -(D) Using an Arbitrary Input Data Space -(E) The Class Error Handler -(F) Current Version Information -(G) References -(H) Contact Information - -================================================================================================ - -(A) Image Segmentation and Filtering - -------------------------------------------------------------------------------------------------- - -Mean shift based image segmentation and filtering is performed using use the following methods: - - msImageProcess::Filter - filters the image - msImageProcessor::Segment - segments the image - -The input image processed by these methods is defined via the method, - -msImageProcessor::DefineImage - this uploads the RGB data into the msImageProcessor class for processing - -To obtain the output call: - - msImageProcessor::GetResults - returns filtered or segmented image in RGB space - msImageProcessor::GetBoundaries - returns the boundaries of regions resulting from filtering - or segmentation - msImageProcessor::GetRegions - returns the classification structure that maps each - data point in the image to a given mode, and also - the number of points in the image correlating to each mode. - -NOTE: ------ - -The modes returned by GetRegions are not in the RGB space. If DefineImage was used, they are in the LUV space. The modes may be converted from LUV to RGB (and visa versa) using the space conversion methods of the msImageProcessor class: - - msImageProcessor::RGBtoLUV - converts data points from the RGB data space to LUV - msImageProcessor::LUVtoRGB - converts data points from the LUV data space to RGB - -Alternatively, mean shift may be applyed to data that lies in a space other than LUV. This may be accomplished through the use of the method MeanShift::DefineLInput (see section D). - -================================================================================================ - -(B) Synergistic Image Segmentation - -------------------------------------------------------------------------------------------------- - -A weight map may be provided to the mean shift image processor class, used to perform synergistic image segmentation as described in the paper [3]. One may specify a weight map by calling either of the following methods: - - MeanShift::SetWeightMap - defines the weight map used to specify a weighted kernel during - mean shift; the weight map may only be used for data that lies - on a lattice (e.g. an image) - msImageProcessor::SetWeightMap - specifies a weight map to be used for performing synergistic image - segmentation - -Each of the above methods accept a floating point array of size L elements containing the weight map. When using the mean shift base class L is the number of data points in the specified data set; when using the image processor class L = height x width, where height and width are the dimensions of the image. The method msImageProcessor::SetWeightMap accepts an additional parameter, namely t_e, a threshold value used during the transitive closure step of the image segmentation algorithm. See the paper [3] for details. - -================================================================================================ - -(C) Using a General Kernel - -------------------------------------------------------------------------------------------------- - -A general kernel can be used to perform mean shift filtering and segmentation by calling the inherited method: - - MeanShift::DefineKernel - defines an N-dimensional kernel having kp subspaces, in which each subspace - can be of one of three types: Uniform, Gaussian, or UserDefined. - -DefineImage, used to define the input image when performing image segmentation or filtering, defines a Uniform kernel having two subspaces (one spatial (x,y) and one range (L,U,V)) each subspace having bandwidths sigmaS and sigmaR respectively. By skimming the method definition one may get an idea of how to define a general kernel. - -NOTE: ----- - -For data that is defined on a lattice, it is always assumed that the spatial domain is treated as a single subspace. Also, DefineKernel() must be called *after* DefineImage() when these methods are used together. - -================================================================================================ - -(D) Using an Arbitrary Input Data Space - -------------------------------------------------------------------------------------------------- - -Mean shift filtering and segmentation may be performed on an arbitary image data space. Such data is defined through calling the inherited method: - - MeanShift::DefineLInput - specifies input defined on a lattice - -DefineImage() calls this method using the LUV data it generates. Through the use of the above methods, mean shift may be applied to an arbitrary input data space using a general kernel. In doing so, one must ensure that the dimension of the input data space and kernel are the same (N). If their dimensions do not agree an error will be flagged. - -================================================================================================ - -(F) The Class Error Handler - -------------------------------------------------------------------------------------------------- - -The mean shift image processor class uses an error message string and error-level flag to perform error handling. These two variables, MeanShift::ErrorMessage and MeanShift::ErrorLevel, are public data members of the class. - -Upon the occurance of an error, - - * An error message is copied into the error message string. - * The error level of the class is set to EL_ERROR. - -The following example demonstrates the use of the error handling mechanism described above. - -msImageProcessor iProc; - -... - -iProc.Segment(sigmaS, sigmaR, minRegion, SPEEDUP); -if(iProc.ErrorLevel == EL_ERROR) -{ - fprintf(stderr, iProc.ErrorMessage); - exit(1); -} - -... - -================================================================================================ - -(G) Current Version Information - -------------------------------------------------------------------------------------------------- - -The current version of the code was tested under both UNIX and Windows environments. - -================================================================================================ - -(H) References - -------------------------------------------------------------------------------------------------- - -[1] D. Comanicu, P. Meer: "Mean shift: A robust approach toward feature space analysis". - IEEE Trans. Pattern Anal. Machine Intell., May 2002. - -[2] P. Meer, B. Georgescu: "Edge detection with embedded confidence". IEEE Trans. Pattern Anal. - Machine Intell., 28, 2001. - -[3] C. Christoudias, B. Georgescu, P. Meer: "Synergism in low level vision". 16th International - Conference of Pattern Recognition, Track 1 - Computer Vision and Robotics, Quebec City, - Canada, August 2001. - -================================================================================================ - -(I) Contact Information - -------------------------------------------------------------------------------------------------- - -Personal Contact Information ----------------------------- - -Email: - - cmch@caip.rutgers.edu (Chris Christoudias) - georgesc@caip.rutgers.edu (Bogdan Georgescu) - -Laboratory Contact Information ------------------------------- - -Laboratory Website: - - www.caip.rutgers.edu/riul/ - -================================================================================================ \ No newline at end of file diff --git a/Modules/ThirdParty/Edison/src/otbedison/RAList.cpp b/Modules/ThirdParty/Edison/src/otbedison/RAList.cpp deleted file mode 100644 index b5abe87552d64782fc7795e5a1829ad2380ce55c..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/RAList.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Region Adjacency List: - ===================== - - The Region Adjacency List class is used by the Image - Processor class in the construction of a Region Adjacency - Matrix, used by this class to applying transitive closure - and to prune spurious regions during image segmentation. - - The definition of the RAList class is provided below. Its - prototype is provided in "RAList.h". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ -//include Region Adjacency List class prototype -#include "RAList.h" - -//include needed libraries -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Constructor */ -/*******************************************************/ -/*Constructs a RAList object. */ -/*******************************************************/ -/*Post: */ -/* - a RAlist object has been properly constru- */ -/* cted. */ -/*******************************************************/ - -RAList::RAList( void ) -{ - //initialize label and link - label = -1; - next = NULL; - - //initialize edge strenght weight and count - edgeStrength = 0; - edgePixelCount = 0; -} - -/*******************************************************/ -/*Class Destructor */ -/*******************************************************/ -/*Destructrs a RAList object. */ -/*******************************************************/ -/*Post: */ -/* - the RAList object has been properly dest- */ -/* ructed. */ -/*******************************************************/ - -RAList::~RAList( void ) -{ - //do nothing -} - -/*******************************************************/ -/*Insert */ -/*******************************************************/ -/*Insert a region node into the region adjacency list. */ -/*******************************************************/ -/*Pre: */ -/* - entry is a node representing a connected re- */ -/* gion */ -/*Post: */ -/* - entry has been inserted into the region adj- */ -/* acency list if it does not already exist */ -/* there. */ -/* - if the entry already exists in the region */ -/* adjacency list 1 is returned otherwise 0 is */ -/* returned. */ -/*******************************************************/ - -int RAList::Insert(RAList *entry) -{ - - //if the list contains only one element - //then insert this element into next - if(!next) - { - //insert entry - next = entry; - entry->next = NULL; - - //done - return 0; - } - - //traverse the list until either: - - //(a) entry's label already exists - do nothing - //(b) the list ends or the current label is - // greater than entry's label, thus insert the entry - // at this location - - //check first entry - if(next->label > entry->label) - { - //insert entry into the list at this location - entry->next = next; - next = entry; - - //done - return 0; - } - - //check the rest of the list... - exists = 0; - cur = next; - while(cur) - { - if(entry->label == cur->label) - { - //node already exists - exists = 1; - break; - } - else if((!(cur->next))||(cur->next->label > entry->label)) - { - //insert entry into the list at this location - entry->next = cur->next; - cur->next = entry; - break; - } - - //traverse the region adjacency list - cur = cur->next; - } - - //done. Return exists indicating whether or not a new node was - // actually inserted into the region adjacency list. - return (int)(exists); - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - diff --git a/Modules/ThirdParty/Edison/src/otbedison/RAList.h b/Modules/ThirdParty/Edison/src/otbedison/RAList.h deleted file mode 100644 index 2c37fcff60cf9d26806bb5fed72ffc5cdebbd21b..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/RAList.h +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Region Adjacency List: - ===================== - - The Region Adjacency List class is used by the Image - Processor class in the construction of a Region Adjacency - Matrix, used by this class to applying transitive closure - and to prune spurious regions during image segmentation. - - The prototype for the RAList class is provided below. Its - defition is provided in "RAList.cc". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -#ifndef RALIST_H -#define RALIST_H - -//define Region Adjacency List class prototype -class RAList { - -public: - - //============================ - // *** Public Data Members *** - //============================ - - ////////////RAM Label////////// - int label; - - ////////////RAM Weight///////// - float edgeStrength; - int edgePixelCount; - - ////////////RAM Link/////////// - RAList *next; - - //======================= - // *** Public Methods *** - //======================= - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //***Class Constrcutor*** - RAList( void ); - - //***Class Destructor*** - ~RAList( void ); - - /*/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* RAM List Manipulation */ - /*\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //Usage: Insert(entry) - int Insert(RAList*); //Insert a region node into the region adjecency list - -private: - - //============================= - // *** Private Data Members *** - //============================= - - ///////current and previous pointer///// - RAList *cur, *prev; - - ////////flag/////////// - unsigned char exists; - -}; - -#endif diff --git a/Modules/ThirdParty/Edison/src/otbedison/SysReadme.txt b/Modules/ThirdParty/Edison/src/otbedison/SysReadme.txt deleted file mode 100644 index 5a5c5721f026f71e80a2844a0282a8505fb95c82..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/SysReadme.txt +++ /dev/null @@ -1,104 +0,0 @@ -Edge Detection and Image SegmentatiON (EDISON) System ver1.0 README -------------------------------------------------------------------- - -System Overview: -=============== - -The EDISON system is a low-level vision tool that performs confidence based edge detection and synergistic image segmentation. It is packaged under a platform independent graphical user interface. A command prompt version is also provided. - -Table of Contents: -------------------- - -(A) System Overview -(B) Help Files -(C) Current Version Information -(D) Using wxWindows -(E) References -(F) Contact Information - -================================================================================================ - -(A) System Overview - -------------------------------------------------------------------------------------------------- - -The low-level image processor system is comprised of four components: - -(1) An image segmentation module consisting of a collection of classes that are designed to - perform mean shift based and synergistic segmentation. -(2) An edge detection module consisting of a collection of classes that are designed to perform - confidence based edge detection. -(3) A platform independent graphical user interface programmed using wxWindows. -(4) A command prompt version. - -The code for each module is available in its own directory. The directory structure is outlined below: - - - segm : code for image segmentation - - edge : code for edge detection - - GUI : code for graphical user interface - - prompt: code for system command prompt - -================================================================================================ - -(B) Help Files - -------------------------------------------------------------------------------------------------- - -The system help files are located in the 'help' directory. This directory contains the help files needed for both the graphical user interface and command prompt versions of the system. The 'doc' directory contains the help files needed for the graphical user interface. This directory must be placed in the same directory as the program executable to be used with the system. The file 'specification.html' contains the command prompt version specification. - -================================================================================================ - -(C) Current Version Info - -------------------------------------------------------------------------------------------------- - -Both versions of the system were tested under a Windows environment. The command prompt version was also tested under UNIX. The graphical user interface was compiled using Microsoft Visual C++. The project files used to package the system code are located in the 'project' directory under the project name 'EDISON'. The makefile needed to compile the command prompt is also located in this directory. For any further questions on the compilation of this code, please contact us using the provided contact information below. - -Although our system is thoroughly tested bugs may still exist. We would greatly appreciate any bug reports you may provide to assist us in building a more stable system. - -================================================================================================ - -(D) Using wxWindows - -------------------------------------------------------------------------------------------------- - -In order to compile the graphical user interface version of EDISON wxWindows must be download and installed. It may be obtained from the wxWindows web site at http://www.wxWindows.org. - -================================================================================================ - -(E) References - -------------------------------------------------------------------------------------------------- - -[1] D. Comanicu, P. Meer: "Mean shift: A robust approach toward feature space analysis". - IEEE Trans. Pattern Anal. Machine Intell., May 2002. - -[2] P. Meer, B. Georgescu: "Edge detection with embedded confidence". IEEE Trans. Pattern Anal. - Machine Intell., 28, 2001. - -[3] C. Christoudias, B. Georgescu, P. Meer: "Synergism in low level vision". 16th International - Conference of Pattern Recognition, Track 1 - Computer Vision and Robotics, Quebec City, - Canada, August 2001. - -================================================================================================ - -(F) Contact Information - -------------------------------------------------------------------------------------------------- - -Personal Contact Information ----------------------------- - -Email: - - cmch@caip.rutgers.edu (Chris M. Christoudias) - georgesc@caip.rutgers.edu (Bogdan Georgescu) - -Laboratory Contact Information ------------------------------- - -Laboratory Website: - - www.caip.rutgers.edu/riul/ - -================================================================================================ diff --git a/Modules/ThirdParty/Edison/src/otbedison/ms.cpp b/Modules/ThirdParty/Edison/src/otbedison/ms.cpp deleted file mode 100644 index ee4d9ed64a2f6f7a0f67d71d70bb367bcc1a8306..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/ms.cpp +++ /dev/null @@ -1,2465 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - MeanShift Base Class: - ==================== - - The mean shift library of routines is realized - via the creation of a MeanShift base class. This class - provides a mechanism for calculating the mean shift vector - at a specified data point, using an arbitrary N-dimensional - data set, and a user-defined kernel. - - For image processing the mean shift base class also allows - for the definition of a data set that is on a two-dimensional - lattice. The amount of time needed to compute the mean shift - vector using such a data set is much less than that of an - arbitrary one. Because images usually contain many data points, - defining the image input data points as being on a lattice - greatly improves computation time and makes algorithms such - as image filtering practical. - - The definition of the MeanShift class is provided below. Its - prototype is provided in 'ms.h'. - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - - -//Include Needed Libraries - -#include "ms.h" -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Constructor/Destructor ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Constructor */ -/*******************************************************/ -/*Post: */ -/* The MeanShift class has been properly */ -/* initialized. */ -/*******************************************************/ - -MeanShift::MeanShift( void ) -{ - - //intialize input data set parameters... - P = NULL; - L = 0; - N = 0; - kp = 0; - - //initialize input data set storage structures... - data = NULL; - - //initialize input data set kd-tree - root = NULL; - forest = NULL; - range = NULL; - - //intialize lattice structure... - height = 0; - width = 0; - - //intialize kernel strucuture... - h = NULL; - kernel = NULL; - w = NULL; - offset = NULL; - increment = NULL; - uniformKernel = false; - - //initialize weight function linked list... - head = cur = NULL; - - //intialize mean shift processing data structures... - uv = NULL; - - //set lattice weight map to null - weightMap = NULL; - - //indicate that the lattice weight map is undefined - weightMapDefined = false; - - //allocate memory for error message buffer... - ErrorMessage = new char [256]; - - //initialize error status to OKAY - ErrorStatus = EL_OKAY; - - //Initialize class state... - class_state.INPUT_DEFINED = false; - class_state.KERNEL_DEFINED = false; - class_state.LATTICE_DEFINED = false; - class_state.OUTPUT_DEFINED = false; - -} - -/*******************************************************/ -/*Class Destructor */ -/*******************************************************/ -/*Post: */ -/* The MeanShift class has been properly */ -/* destroyed. */ -/*******************************************************/ - -MeanShift::~MeanShift( void ) -{ - delete [] ErrorMessage; - if (weightMap) - { - delete [] weightMap; - } - - //de-allocate memory used to store - //user defined weight functions - ClearWeightFunctions(); - - //de-allocate memory used for kernel - DestroyKernel(); - - //de-allocate memory used for input - ResetInput(); - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Creation/Initialization of Mean Shift Kernel ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Define Kernel */ -/*******************************************************/ -/*Creats custom user defined Kernel to be used by the */ -/*mean shift procedure. */ -/*******************************************************/ -/*Pre: */ -/* - kernel is an array of kernelTypes specifying */ -/* the type of kernel to be used on each sub- */ -/* space of the input data set x */ -/* - h is the set of bandwidths used to define the*/ -/* the search window */ -/* - P is a one dimensional array of integers of */ -/* size kp, that specifies the dimension of each*/ -/* subspace of the input data set x */ -/* - kp is the total number of subspaces used to */ -/* the input data set x */ -/*Post: */ -/* - the custom kernel has been created for use */ -/* by the mean shift procedure. */ -/*******************************************************/ - -void MeanShift::DefineKernel(kernelType *kernel_, float *h_, int *P_, int kp_) -{ - - // Declare variables - int i, kN; - - //if a kernel has already been created then destroy it - if(kp) - DestroyKernel(); - - //Obtain kp... - if((kp = kp_) <= 0) - { - ErrorHandler("MeanShift", "CreateKernel", "Subspace count (kp) is zero or negative."); - return; - } - - //Allocate memory for h, P, kernel, offset, and increment - if((!(P = new int [kp]))||(!(h = new float [kp]))||(!(kernel = new kernelType [kp]))|| - (!(offset = new float [kp]))||(!(increment = new double [kp]))) - { - ErrorHandler("MeanShift", "CreateKernel", "Not enough memory available to create kernel."); - return; - } - - //Populate h, P and kernel, also use P to calculate - //the dimension (N_) of the potential input data set x - kN = 0; - for(i = 0; i < kp; i++) - { - if((h[i] = h_[i]) <= 0) - { - ErrorHandler("MeanShift", "CreateKernel", "Negative or zero valued bandwidths are prohibited."); - return; - } - if((P[i] = P_[i]) <= 0) - { - ErrorHandler("MeanShift", "CreateKernel", "Negative or zero valued subspace dimensions are prohibited."); - return; - } - kernel[i] = kernel_[i]; - kN += P[i]; - } - - //Allocate memory for range vector and uv using N_ - if((!(range = new float [2*kN]))||(!(uv = new double [kN]))) - { - ErrorHandler("MeanShift", "CreateKernel", "Not enough memory available to create kernel."); - return; - } - - // Generate weight function lookup table - // using above information and user - // defined weight function list - generateLookupTable(); - - //check for errors - if(ErrorStatus == EL_ERROR) - return; - - //indicate that the kernel has been defined - class_state.KERNEL_DEFINED = true; - - //done. - return; - -} - -/*******************************************************/ -/*Add Weight Function */ -/*******************************************************/ -/*Adds a weight function to the Mean Shift class to be */ -/*used by the mean shift procedure */ -/*******************************************************/ -/*Pre: */ -/* - g(u) is the normalized weight function with */ -/* respect to u = (norm(x-xi))^2/h^2 */ -/* - sampleNumber is the number of samples to be */ -/* taken of g(u) over halfWindow interval */ -/* - halfWindow is the radius of g(u) such that */ -/* g(u) is defined for 0 <= u <= halfWindow */ -/* - subspace is the subspace number for which */ -/* g(u) is to be applied during the mean shift */ -/* procedure. */ -/*Post: */ -/* - g(u) has been added to the Mean Shift class */ -/* private data structure to be used by the */ -/* mean shift procedure. */ -/* - if a weight function has already been spec- */ -/* ified for the specified subspace, the weight */ -/* function for this subspace has been replaced.*/ -/*******************************************************/ - -void MeanShift::AddWeightFunction(double g(double), float halfWindow, int sampleNumber, int subspace) -{ - - // Declare Variables - int i; - double increment; - - // Search to see if a weight function has already been - // defined for specified subspace, if not then insert - // into the head of the weight function list, otherwise - // replace entry - - // Perform Search - cur = head; - while((cur)&&(cur->subspace != subspace)) - cur = cur->next; - - // Entry Exists - Replace It! - // Otherwise insert at the head of the the weight functon list - if(cur) - delete cur->w; - else - { - cur = new userWeightFunct; - cur->next = head; - head = cur; - } - - // Generate lookup table - increment = halfWindow/(double)(sampleNumber); - - cur->w = new double [sampleNumber+1]; - for(i = 0; i <= sampleNumber; i++) - cur->w[i] = g((double)(i*increment)); - - // Set weight function parameters - cur->halfWindow = halfWindow; - cur->sampleNumber = sampleNumber; - cur->subspace = subspace; - - //done. - return; - -} - -/*******************************************************/ -/*Clear Weight Functions */ -/*******************************************************/ -/*Clears user defined weight from the Mean Shift class */ -/*private data structure. */ -/*******************************************************/ -/*Post: */ -/* - all user defined weight functions ahve been */ -/* cleared from the private data structure of */ -/* the mean shift class. */ -/*******************************************************/ - -void MeanShift::ClearWeightFunctions( void ) -{ - - while(head) - { - delete head->w; - cur = head; - head = head->next; - delete cur; - } - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Input Data Set Declaration ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Define Input */ -/*******************************************************/ -/*Uploads input data set x into the mean shift class. */ -/*******************************************************/ -/*Pre: */ -/* - x is a one dimensional array of L N-dimen- */ -/* ional data points. */ -/*Post: */ -/* - x has been uploaded into the mean shift */ -/* class. */ -/* - the height and width of a previous data set */ -/* has been undefined. */ -/*******************************************************/ - -void MeanShift::DefineInput(float *x, int L_, int N_) -{ - - - //if input data is defined de-allocate memory, and - //re-initialize the input data structure - if((class_state.INPUT_DEFINED)||(class_state.LATTICE_DEFINED)) - ResetInput(); - - //make sure x is not NULL... - if(!x) - { - ErrorHandler("MeanShift", "UploadInput", "Input data set is NULL."); - return; - } - - //Obtain L and N - if(((L = L_) <= 0)||((N = N_) <= 0)) - { - ErrorHandler("MeanShift", "UploadInput", "Input data set has negative or zero length or dimension."); - return; - } - - //Allocate memory for data - if(!(data = new float [L*N])) - { - ErrorHandler("MeanShift", "UploadInput", "Not enough memory."); - return; - } - - //Allocate memory for input data set, and copy - //x into the private data members of the mean - //shift class - InitializeInput(x); - - //check for errors - if(ErrorStatus == EL_ERROR) - return; - - // Load x into the MeanShift object using - // using a kd-tree, resulting in better - // range searching of the input data points - // x - also upload window centers into - // msRawData - CreateBST(); - - //indicate that the input has been recently defined - class_state.INPUT_DEFINED = true; - class_state.LATTICE_DEFINED = false; - class_state.OUTPUT_DEFINED = false; - - //done. - return; - -} - -/*******************************************************/ -/*Define Lattice */ -/*******************************************************/ -/*Defines the height and width of the input lattice. */ -/*******************************************************/ -/*Pre: */ -/* - ht is the height of the lattice */ -/* - wt is the width of the lattice */ -/*Post: */ -/* - the height and width of the lattice has been */ -/* specified. */ -/* - if a data set is presently loaded into the */ -/* mean shift class, an error is flagged if the */ -/* number of elements in that data set does not */ -/* equal the product ht*wt. */ -/*******************************************************/ - -void MeanShift::DefineLInput(float *x, int ht, int wt, int N_) -{ - - //if input data is defined de-allocate memory, and - //re-initialize the input data structure - if((class_state.INPUT_DEFINED)||(class_state.LATTICE_DEFINED)) - ResetInput(); - - //Obtain lattice height and width - if(((height = ht) <= 0)||((width = wt) <= 0)) - { - ErrorHandler("MeanShift", "DefineLInput", "Lattice defined using zero or negative height and/or width."); - return; - } - - //Obtain input data dimension - if((N = N_) <= 0) - { - ErrorHandler("MeanShift", "DefineInput", "Input defined using zero or negative dimension."); - return; - } - - //compute the data length, L, of input data set - //using height and width - L = height*width; - - //Allocate memory for input data set, and copy - //x into the private data members of the mean - //shift class - InitializeInput(x); - - //check for errors - if(ErrorStatus == EL_ERROR) - return; - - //allocate memory for weight map - if(!(weightMap = new float [L])) - { - ErrorHandler("MeanShift", "InitializeInput", "Not enough memory."); - return; - } - - //initialize weightMap to an array of zeros - memset(weightMap, 0, L*(sizeof(float))); - - //Indicate that a lattice input has recently been - //defined - class_state.LATTICE_DEFINED = true; - class_state.INPUT_DEFINED = false; - class_state.OUTPUT_DEFINED = false; - - //done. - return; - -} - -/*******************************************************/ -/*Set Lattice Weight Map */ -/*******************************************************/ -/*Populates the lattice weight map with specified */ -/*weight values. */ -/*******************************************************/ -/*Pre: */ -/* - wm is a floating point array of size L */ -/* specifying for each data point a weight */ -/* value */ -/*Post: */ -/* - wm has been used to populate the lattice */ -/* weight map. */ -/*******************************************************/ - -void MeanShift::SetLatticeWeightMap(float *wm) -{ - //make sure wm is not NULL - if(!wm) - { - ErrorHandler("MeanShift", "SetWeightMap", "Specified weight map is NULL."); - return; - } - - //populate weightMap using wm - int i; - for(i = 0; i < L; i++) - weightMap[i] = wm[i]; - - //indicate that a lattice weight map has been specified - weightMapDefined = true; - - //done. - return; - -} - - -/*******************************************************/ -/*Remove Lattice Weight Map */ -/*******************************************************/ -/*Removes the lattice weight map. */ -/*******************************************************/ -/*Post: */ -/* - the lattice weight map has been removed. */ -/* - if a weight map did not exist NO error is */ -/* flagged. */ -/*******************************************************/ - -void MeanShift::RemoveLatticeWeightMap(void) -{ - - //only remove weight map if it exists, otherwise - //do nothing... - if(weightMapDefined) - { - //set values of lattice weight map to zero - memset(weightMap, 0, L*sizeof(float)); - - //indicate that a lattice weight map is no longer - //defined - weightMapDefined = false; - } - - //done. - return; - -} - - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Mean Shift Operations ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Mean Shift Vector */ -/*******************************************************/ -/*Calculates the mean shift vector at a specified data */ -/*point yk. */ -/*******************************************************/ -/*Pre: */ -/* - a kernel has been created */ -/* - a data set has been uploaded */ -/* - Mh is an N dimensional mean shift vector */ -/* - yk is an N dimensional data point */ -/*Post: */ -/* - the mean shift vector at yk has been */ -/* calculated and stored in and returned by Mh. */ -/*******************************************************/ - -void MeanShift::msVector(double *Mh, double *yk) -{ - - //make sure that Mh and/or yk are not NULL... - if((!Mh)||(!yk)) - { - ErrorHandler("MeanShift", "msVector", "Invalid argument(s) passed to this method."); - return; - } - - //make sure that a kernel has been created, data has - //been uploaded, and that they are consistent with one - //another... - classConsistencyCheck(N, false); - - //calculate mean shift vector at yk using created kernel - //and uploaded data set - MSVector(Mh, yk); - - //done. - return; - -} - -/*******************************************************/ -/*Lattice Mean Shift Vector */ -/*******************************************************/ -/*Calculates the mean shift vector at a specified data */ -/*point yk, assuming that the data set exhists on a */ -/*height x width two dimensional lattice. */ -/*******************************************************/ -/*Pre: */ -/* - a kernel has been created */ -/* - a data set has been uploaded */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/* - Mh is an N dimensional mean shift vector */ -/* - yk is an N dimensional data point */ -/*Post: */ -/* - the mean shift vector at yk has been */ -/* calculated and stored in and returned by Mh. */ -/* - Mh was calculated using the defined input */ -/* lattice. */ -/*******************************************************/ - -void MeanShift::latticeMSVector(double *Mh, double *yk) -{ - - //make sure that Mh and/or yk are not NULL... - if((!Mh)||(!yk)) - { - ErrorHandler("MeanShift", "lmsVector", "Invalid argument(s) passed to this method."); - return; - } - - //make sure that a kernel has been created, data has - //been uploaded, and that they are consistent with one - //another... - classConsistencyCheck(N+2, true); - - //calculate mean shift vector at yk using created kernel - //and uploaded data set - LatticeMSVector(Mh, yk); - - //done. - return; - -} - -/*******************************************************/ -/*Find Mode */ -/*******************************************************/ -/*Calculates the mode of a specified data point yk. */ -/*******************************************************/ -/*Pre: */ -/* - a kernel has been created */ -/* - a data set has been uploaded */ -/* - mode is the N dimensional mode of the N-dim- */ -/* ensional data point yk */ -/*Post: */ -/* - the mode of yk has been calculated and */ -/* stored in mode. */ -/*******************************************************/ - -void MeanShift::FindMode(double *mode, double *yk) -{ - - //make sure that mode and/or yk are not NULL... - if((!mode)||(!yk)) - { - ErrorHandler("MeanShift", "FindMode", "Invalid argument(s) passed to this method."); - return; - } - - //make sure that a kernel has been created, data has - //been uploaded, and that they are consistent with one - //another... - classConsistencyCheck(N, false); - - //allocate memory for Mh - double *Mh = new double [N]; - - //copy yk into mode - int i; - for(i = 0; i < N; i++) - mode[i] = yk[i]; - - //calculate mean shift vector at yk - MSVector(Mh, yk); - - //calculate mvAbs = |Mh|^2 - double mvAbs = 0; - for(i = 0; i < N; i++) - mvAbs += Mh[i]*Mh[i]; - - //shift mode until convergence (mvAbs = 0)... - int iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - //shift mode... - for(i = 0; i < N; i++) - mode[i] += Mh[i]; - - //re-calculate mean shift vector at new - //window location have center defined by - //mode - MSVector(Mh, mode); - - //calculate mvAbs = |Mh|^2 - mvAbs = 0; - for(i = 0; i < N; i++) - mvAbs += Mh[i]*Mh[i]; - - //increment interation count... - iterationCount++; - - } - - //shift mode... - for(i = 0; i < N; i++) - mode[i] += Mh[i]; - - //de-allocate memory - delete [] Mh; - - //done. - return; - -} - -/*******************************************************/ -/*Find Lattice Mode */ -/*******************************************************/ -/*Calculates the mode of a specified data point yk, */ -/*assuming that the data set exhists on a height x */ -/*width two dimensional lattice. */ -/*******************************************************/ -/*Pre: */ -/* - a kernel has been created */ -/* - a data set has been uploaded */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/* - mode is the N dimensional mode of the N-dim- */ -/* ensional data point yk */ -/*Post: */ -/* - the mode of yk has been calculated and */ -/* stored in mode. */ -/* - mode was calculated using the defined input */ -/* lattice. */ -/*******************************************************/ - -void MeanShift::FindLMode(double *mode, double *yk) -{ - - //make sure that mode and/or yk are not NULL... - if((!mode)||(!yk)) - { - ErrorHandler("MeanShift", "FindLMode", "Invalid argument(s) passed to this method."); - return; - } - - //make sure the lattice height and width have been defined... - if(!height) - { - ErrorHandler("MeanShift", "FindLMode", "Lattice height and width is undefined."); - return; - } - - //make sure that a kernel has been created, data has - //been uploaded, and that they are consistent with one - //another... - classConsistencyCheck(N+2, true); - - //define gridN - int gridN = N+2; - - //allocate memory for Mh - double *Mh = new double [gridN]; - - //copy yk into mode - int i; - for(i = 0; i < gridN; i++) - mode[i] = yk[i]; - - //calculate mean shift vector at yk - LatticeMSVector(Mh, mode); - - //calculate mvAbs = |Mh|^2 - double mvAbs = 0; - for(i = 0; i < gridN; i++) - mvAbs += Mh[i]*Mh[i]; - - //shift mode until convergence (mvAbs = 0)... - int iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - //shift mode... - for(i = 0; i < gridN; i++) - mode[i] += Mh[i]; - - //re-calculate mean shift vector at new - //window location have center defined by - //mode - LatticeMSVector(Mh, mode); - - //calculate mvAbs = |Mh|^2 - mvAbs = 0; - for(i = 0; i < gridN; i++) - mvAbs += Mh[i]*Mh[i]; - - //increment interation count... - iterationCount++; - - } - - //shift mode... - for(i = 0; i < gridN; i++) - mode[i] += Mh[i]; - - //de-allocate memory - delete [] Mh; - - //done. - return; - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PROTECTED METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using kd-Tree */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Mean Shift Vector */ -/*******************************************************/ -/*Computes the mean shift vector at a window location */ -/*yk using input data set x using a custom, user defin-*/ -/*ed kernel. */ -/*******************************************************/ -/*Pre: */ -/* - input data has been uploaded into the private*/ -/* data members of the MeanShift class */ -/* - a window center yk has been defined */ -/* - uniformKernel indicates the which type of */ -/* kernel to be used by this procedure: uniform */ -/* or general */ -/*Post: */ -/* - the mean shift vector calculated at yk */ -/* using a either a custom, user defined kernel */ -/* or a uniform kernel is returned */ -/*******************************************************/ - -void MeanShift::MSVector(double *Mh_ptr, double *yk_ptr) -{ - - // Declare Variables - int i,j; - - // Initialize mean shift vector - for(i = 0; i < N; i++) - Mh_ptr[i] = 0; - - // Initialize wsum to zero, the sum of the weights of each - // data point found to lie within the search window (sphere) - wsum = 0; - - // Build Range Vector using h[i] and yk - - int s = 0; - - // The flag uniformKernel is used to determine which - // kernel function is to be used in the calculation - // of the mean shift vector - if(uniformKernel) - { - for(i = 0; i < kp; i++) - { - for(j = 0; j < P[i]; j++) - { - range[2*(s+j) ] = (float)(yk_ptr[s+j] - h[i]); - range[2*(s+j)+1] = (float)(yk_ptr[s+j] + h[i]); - } - s += P[i]; - } - } - else - { - for(i = 0; i < kp; i++) - { - for(j = 0; j < P[i]; j++) - { - range[2*(s+j) ] = (float)(yk_ptr[s+j] - h[i]*float(sqrt(offset[i]))); - range[2*(s+j)+1] = (float)(yk_ptr[s+j] + h[i]*float(sqrt(offset[i]))); - } - s += P[i]; - } - } - - // Traverse through the data set x, performing the - // weighted sum of each point xi that lies within - // the search window (sphere) using a general, - // user defined kernel or uniform kernel depending - // on the uniformKernel flag - if(uniformKernel) - uniformSearch(root, 0, Mh_ptr, yk_ptr); - else - generalSearch(root, 0, Mh_ptr, yk_ptr); - - // Calculate the mean shift vector using Mh and wsum - for(i = 0; i < N; i++) - { - - // Divide Sum by wsum - Mh_ptr[i] /= wsum; - - // Calculate mean shift vector: Mh(yk) = y(k+1) - y(k) - Mh_ptr[i] -= yk_ptr[i]; - - } - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using Lattice */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Lattice Mean Shift Vector */ -/*******************************************************/ -/*Computes the mean shift vector at a specfied window */ -/*yk using the lattice data structure. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr and yh_ptr are arrays of doubles con- */ -/* aining N+2 elements */ -/* - Mh_ptr is the mean shift vector calculated */ -/* at window center yk_ptr */ -/*Post: */ -/* - the mean shift vector at the window center */ -/* pointed to by yk_ptr has been calculated and */ -/* stored in the memory location pointed to by */ -/* Mh_ptr */ -/*******************************************************/ - -void MeanShift::LatticeMSVector(double *Mh_ptr, double *yk_ptr) -{ - - // Initialize mean shift vector - register int i; - for(i = 0; i < N+2; i++) - Mh_ptr[i] = 0; - - // Initialize wsum - wsum = 0; - - // Perform lattice search summing - // all the points that lie within the search - // window defined using the kernel specified - //by uniformKernel - if(uniformKernel) - uniformLSearch(Mh_ptr, yk_ptr); - else - generalLSearch(Mh_ptr, yk_ptr); - - // Compute mean shift vector using sum computed - // by lattice search, wsum, and yk_ptr: - // Mh = Mh/wsum - yk_ptr - - if (wsum > 0) - { - for(i = 0; i < N+2; i++) - Mh_ptr[i] = Mh_ptr[i]/wsum - yk_ptr[i]; - } - else - { - for(i = 0; i < N+2; i++) - Mh_ptr[i] = 0; - } - - // done. - return; - -} - -/*******************************************************/ -/*Optimized Lattice Mean Shift Vector */ -/*******************************************************/ -/*Computes the mean shift vector at a specfied window */ -/*yk using the lattice data structure. Also the points */ -/*that lie within the window are stored into the basin */ -/*of attraction structure used by the optimized mean */ -/*shift algorithms. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr and yh_ptr are arrays of doubles con- */ -/* aining N+2 elements */ -/* - Mh_ptr is the mean shift vector calculated */ -/* at window center yk_ptr */ -/*Post: */ -/* - the mean shift vector at the window center */ -/* pointed to by yk_ptr has been calculated and */ -/* stored in the memory location pointed to by */ -/* Mh_ptr */ -/* - the data points lying within h of of yk_ptr */ -/* have been stored into the basin of attract- */ -/* ion data structure. */ -/*******************************************************/ - -void MeanShift::OptLatticeMSVector(double *Mh_ptr, double *yk_ptr) -{ - - // Initialize mean shift vector - register int i; - for(i = 0; i < N+2; i++) - Mh_ptr[i] = 0; - - // Initialize wsum - wsum = 0; - - // Perform lattice search summing - // all the points that lie within the search - // window defined using the kernel specified - //by uniformKernel - if(uniformKernel) - optUniformLSearch(Mh_ptr, yk_ptr); - else - optGeneralLSearch(Mh_ptr, yk_ptr); - - // Compute mean shift vector using sum computed - // by lattice search, wsum, and yk_ptr: - // Mh = Mh/wsum - yk_ptr - - if (wsum > 0) - { - for(i = 0; i < N+2; i++) - Mh_ptr[i] = Mh_ptr[i]/wsum - yk_ptr[i]; - } else - { - for (i=0; i< N+2; i++) - Mh_ptr[i] = 0; - } - - // done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Kernel-Input Data Consistency ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Consistency Check */ -/*******************************************************/ -/*Checks the state of the class prior to the applicat- */ -/*ion of mean shift. */ -/*******************************************************/ -/*Pre: */ -/* - iN is the specified dimension of the input, */ -/* iN = N for a general input data set, iN = N */ -/* + 2 for a input set defined using a lattice */ -/*Post: */ -/* - if the kernel has not been created, an input */ -/* has not been defined and/or the specified */ -/* input dimension (iN) does not match that of */ -/* the kernel a fatal error is flagged. */ -/*******************************************************/ - -void MeanShift::classConsistencyCheck(int iN, bool usingLattice) -{ - - //make sure that kernel has been created... - if(class_state.KERNEL_DEFINED == false) - { - ErrorHandler("MeanShift", "classConsistencyCheck", "Kernel not created."); - return; - } - - //make sure input data set has been loaded into mean shift object... - if((class_state.INPUT_DEFINED == false)&&(!usingLattice)) - { - ErrorHandler("MeanShift", "classConsistencyCheck", "No input data specified."); - return; - } - - //make sure that the lattice is defined if it is being used - if((class_state.LATTICE_DEFINED == false)&&(usingLattice)) - { - ErrorHandler("MeanShift", "classConsistencyCheck", "Latice not created."); - return; - } - - //make sure that dimension of the kernel and the input data set - //agree - - //calculate dimension of kernel (kN) - int i, kN = 0; - for(i = 0; i < kp; i++) - kN += P[i]; - - //perform comparison... - if(iN != kN) - { - ErrorHandler("MeanShift", "classConsitencyCheck", "Kernel dimension does not match defined input data dimension."); - return; - } - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Class Error Handler ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Error Handler */ -/*******************************************************/ -/*Class error handler. */ -/*******************************************************/ -/*Pre: */ -/* - className is the name of the class that fl- */ -/* agged an error */ -/* - methodName is the name of the method that */ -/* flagged an error */ -/* - errmsg is the error message given by the */ -/* calling function */ -/*Post: */ -/* - the error message errmsg is flagged on beh- */ -/* ave of method methodName belonging to class */ -/* className: */ -/* */ -/* (1) ErrorMessage has been updated with the */ -/* appropriate error message using the arg- */ -/* ments passed to this method. */ -/* (2) ErrorStatus is set to ERROR */ -/* (ErrorStatus = 1) */ -/*******************************************************/ - -void MeanShift::ErrorHandler(char *className, char *methodName, char* errmsg) -{ - - //store trace into error message - strcpy(ErrorMessage, className); - strcat(ErrorMessage, "::"); - strcat(ErrorMessage, methodName); - strcat(ErrorMessage, " Error: "); - - //store message into error message - strcat(ErrorMessage, errmsg); - - //set error status to ERROR - ErrorStatus = EL_ERROR; - - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PRIVATE METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Kernel Creation/Manipulation ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Generate Lookup Table */ -/*******************************************************/ -/*A weight function look up table is generated. */ -/*******************************************************/ -/*Pre: */ -/* - kernel is an array of kernelTypes specifying */ -/* the type of kernel to be used on each sub- */ -/* space of the input data set x */ -/* - kp is the total number of subspaces used to */ -/* the input data set x */ -/* - the above information has been pre-loaded */ -/* into the MeanShift class private members */ -/*Post: */ -/* - a lookup table is generated for the weight */ -/* function of the resulting kernel */ -/* - uniformKernel is set to true if the kernel */ -/* to be used is uniform, false is returned */ -/* otherwise */ -/* - if a user defined weight function is requred */ -/* for a given subspace but not defined in the */ -/* user defined weight function list, an error */ -/* is flagged and the program is halted */ -/*******************************************************/ - -void MeanShift::generateLookupTable( void ) -{ - - // Declare Variables - int i,j; - - // Allocate memory for lookup table w - w = new double*[kp]; - - // Traverse through kernel generating weight function - // lookup table w - - // Assume kernel is uniform - uniformKernel = true; - - for(i = 0; i < kp; i++) - { - switch(kernel[i]) - { - // *Uniform Kernel* has weight funciton w(u) = 1 - // therefore, a weight funciton lookup table is - // not needed for this kernel --> w[i] = NULL indicates - // this - case Uniform: - - w [i] = NULL; //weight function not needed for this kernel - offset [i] = 1; //uniform kernel has u < 1.0 - increment[i] = 1; //has no meaning - break; - - // *Gaussian Kernel* has weight function w(u) = constant*exp(-u^2/[2h[i]^2]) - case Gaussian: - - // Set uniformKernel to false - uniformKernel = false; - - // generate weight function using expression, - // exp(-u/2), where u = norm(xi - x)^2/h^2 - - // Allocate memory for weight table - w[i] = new double [GAUSS_NUM_ELS+1]; - - for(j = 0; j <= GAUSS_NUM_ELS; j++) - w[i][j] = exp(-j*GAUSS_INCREMENT/2); - - // Set offset = offset^2, and set increment - offset [i] = (float)(GAUSS_LIMIT*GAUSS_LIMIT); - increment[i] = GAUSS_INCREMENT; - - // done - break; - - // *User Define Kernel* uses the weight function wf(u) - case UserDefined: - - // Set uniformKernel to false - uniformKernel = false; - - // Search for user defined weight function - // defined for subspace (i+1) - cur = head; - while((cur)&&(cur->subspace != (i+1))) - cur = cur->next; - - // If a user defined subspace has not been found - // for this subspace, flag an error - if(cur == NULL) - { - fprintf(stderr, "\ngenerateLookupTable Fatal Error: User defined kernel for subspace %d undefined.\n\nAborting Program.\n\n", i+1); - exit(1); - } - - // Otherwise, copy weight function lookup table to w[i] - w[i] = new double [cur->sampleNumber+1]; - for(j = 0; j <= cur->sampleNumber; j++) - w[i][j] = cur->w[j]; - - // Set offset and increment accordingly - offset [i] = (float)(cur->halfWindow); - increment[i] = cur->halfWindow/(float)(cur->sampleNumber); - - // done - break; - - default: - - ErrorHandler("MeanShift", "generateLookupTable", "Unknown kernel type."); - - } - - } -} - -/*******************************************************/ -/*Destroy Kernel */ -/*******************************************************/ -/*Destroys and initializes kernel. */ -/*******************************************************/ -/*Post: */ -/* - memory for the kernel private data members */ -/* have been destroyed and the kernel has been */ -/* initialized for re-use. */ -/*******************************************************/ - -void MeanShift::DestroyKernel( void ) -{ - - //de-allocate memory... - if(kernel) delete [] kernel; - if (h) delete [] h; - if (P) delete [] P; - if (range) delete [] range; - - if (uv) delete [] uv; - if(increment) delete [] increment; - if (offset) delete [] offset; - - if (kp>0) - { - if (w) - { - int i; - for (i=0; i<kp; i++) - delete [] w[i]; - delete [] w; - } - w = NULL; - } - - //intialize kernel for re-use... - kp = 0; - kernel = NULL; - h = NULL; - P = NULL; - range = NULL; - - increment = NULL; - uv = NULL; - offset = NULL; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Input Data Initialization/Destruction ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Create Binary Search Tree */ -/*******************************************************/ -/*Uploads input data set x into a kd-BST. */ -/*******************************************************/ -/*Pre: */ -/* - x is a one dimensional array of L N-dimensi- */ -/* onal data points */ -/*Post: */ -/* - x has been uploaded into a balanced kd-BST */ -/* data structure for use by the mean shift */ -/* procedure */ -/*******************************************************/ - -void MeanShift::CreateBST( void ) -{ - - // Create BST using data.... - - // Allocate memory for tree - forest = new tree[L]; - - // Populate 'forest' of tree's with - // the values stored in x - int i; - for(i = 0; i < L; i++) - { - forest[i].x = &data[i*N]; - forest[i].right = NULL; - forest[i].left = NULL; - forest[i].parent = NULL; - } - - // Build balanced Nd-tree from the - // forest of trees generated above - // retaining the root of this tree - - root = BuildKDTree(forest, L, 0, NULL); - - //done. - return; - -} - -/*******************************************************/ -/*Initialize Input */ -/*******************************************************/ -/*Allocates memory for and initializes the input data */ -/*structure. */ -/*******************************************************/ -/*Pre: */ -/* - x is a floating point array of L, N dimens- */ -/* ional input data points */ -/*Post: */ -/* - memory has been allocated for the input data */ -/* structure and x has been stored using into */ -/* the mean shift class using the resulting */ -/* structure. */ -/*******************************************************/ - -void MeanShift::InitializeInput(float *x) -{ - - //allocate memory for input data set - if(!(data = new float [L*N])) - { - ErrorHandler("MeanShift", "InitializeInput", "Not enough memory."); - return; - } - - //copy x into data - int i; - for(i = 0; i < L*N; i++) - data[i] = x[i]; - - //done. - return; - -} - -/*******************************************************/ -/*Reset Input */ -/*******************************************************/ -/*De-allocates memory for and re-intializes input data */ -/*structure. */ -/*******************************************************/ -/*Post: */ -/* - the memory of the input data structure has */ -/* been de-allocated and this strucuture has */ -/* been initialized for re-use. */ -/*******************************************************/ - -void MeanShift::ResetInput( void ) -{ - - //de-allocate memory of input data structure (BST) - if(data) delete [] data; - if(forest) delete [] forest; - - //initialize input data structure for re-use - data = NULL; - forest = NULL; - root = NULL; - L = 0; - N = 0; - width = 0; - height = 0; - - //re-set class input to indicate that - //an input is not longer stored by - //the private data members of this class - class_state.INPUT_DEFINED = class_state.LATTICE_DEFINED = false; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** k-dimensional Binary Search Tree ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Build KD Tree (for Tree Structure) */ -/*******************************************************/ -/*Builds a KD Tree given a forest of tree's. */ -/*******************************************************/ -/*Pre: */ -/* - subset is a subset of L un-ordered tree nodes*/ -/* each containing an N-dimensional data point */ -/* - d is the depth of the subset, used to specify*/ -/* the dimension used to construct the tree at */ -/* the given depth */ -/* - parent is the parent tree of subset */ -/*Post: */ -/* - a balanced KD tree has been constructed using*/ -/* the forest subset, the root of this tree has */ -/* been returned */ -/*******************************************************/ - -tree *MeanShift::BuildKDTree(tree *subset, int length, int d, tree* parent) -{ - - // If the subset is a single tree - // then return this tree otherwise - // partition the subset and place - // these subsets recursively into - // the left and right sub-trees having - // their root specified by the median - // of this subset in dimension d - if(length == 1) - { - subset->parent = parent; - return subset; - } - else if(length > 1) - { - - // Sort Subset - QuickMedian(subset, 0, length-1, d); - - // Get Median of Subset and Partition - // it into two sub-trees - create - // a tree with its root being the median - // of the subset and its left and right - // children being the medians of the subsets - int median = length/2; - subset[median].parent = parent; - subset[median].left = BuildKDTree(subset , median , (d+1)%N, &subset[median]); - subset[median].right = BuildKDTree(&subset[median+1], length-median-1, (d+1)%N, &subset[median]); - - // Output tree structure - return &subset[median]; - - } - else - return NULL; - - //done. - -} - -/*******************************************************/ -/*Quick Median (for Tree Structure) */ -/*******************************************************/ -/*Finds the median element in an un-ordered set, re- */ -/*structuring the set such that points less than the */ -/*median point are located to the left of the median */ -/*and points greater than the median point are located */ -/*to the right. */ -/*******************************************************/ -/*Pre: */ -/* - arr is a subset of tree nodes whose leftmost */ -/* element is specified by left and rightmost */ -/* element is specified by left */ -/* - d is the dimension of the data set stored by */ -/* the tree structure that is used to find */ -/* the median */ -/*Post: */ -/* - the median point is found and the subset */ -/* of trees is re-ordered such that all trees */ -/* whose data points with d dimensional value */ -/* less than that of the median tree node are */ -/* located to the left of the median tree node, */ -/* otherwise they are located to the right */ -/*******************************************************/ - -void MeanShift::QuickMedian(tree *arr, int left, int right, int d) -{ - unsigned long k; - unsigned long n; - float* a; - float* temp; - n = right-left+1; - k = n/2 + 1; - unsigned long i, ir, j, l, mid; - - l = 1; - ir = n; - for (;;) - { - if (ir <= l+1) - { - if (ir == l+1 && arr[ir-1].x[d] < arr[l-1].x[d]) - { - SWAP(arr[l-1].x, arr[ir-1].x) - } - return; - } else - { - mid = (l+ir) >> 1; - SWAP(arr[mid-1].x, arr[l+1-1].x) - if (arr[l-1].x[d] > arr[ir-1].x[d]) - { - SWAP(arr[l-1].x, arr[ir-1].x) - } - if (arr[l+1-1].x[d] > arr[ir-1].x[d]) - { - SWAP(arr[l+1-1].x, arr[ir-1].x) - } - if (arr[l-1].x[d] > arr[l+1-1].x[d]) - { - SWAP(arr[l-1].x, arr[l+1-1].x) - } - i = l+1; - j = ir; - a = arr[l+1-1].x; - for (;;) { - do i++; while (arr[i-1].x[d] < a[d]); - do j--; while (arr[j-1].x[d] > a[d]); - if (j<i) break; - SWAP(arr[i-1].x, arr[j-1].x) - } - arr[l+1-1].x = arr[j-1].x; - arr[j-1].x = a; - if (j>=k) ir = j-1; - if (j<=k) l = i; - } - } -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Mean Shift: Using kd-Tree ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Uniform Search */ -/*******************************************************/ -/*Searches the input data using a kd-tree, performs the*/ -/*sum on the data within the Hypercube defined by the */ -/*tree using a uniform kernel. */ -/*******************************************************/ -/*Pre: */ -/* - gt is a possibly NULL pointer to a kd tree */ -/* - Mh_ptr is a pointer to the mean shift vector */ -/* being calculated */ -/* - yk_ptr is a pointer to the current window */ -/* center location */ -/* - gd is the depth of the current subtree */ -/*Post: */ -/* - the mean of the points within the Hypercube */ -/* of the kd tree is computed using a uniform */ -/* kernel */ -/*******************************************************/ - -void MeanShift::uniformSearch(tree *gt, int gd, double *Mh_ptr, double *yk_ptr) -{ - tree* c_t; - int c_d; - int i; - int actionType; - - c_t = gt; - c_d = gd; - actionType = 0; - - double el, diff; - int k, j, s; - - while (c_t != NULL) - { - switch(actionType) { - case 0: // forward - if ((c_t->x[c_d] > range[2*c_d]) && ((c_t->left) != NULL)) - { - c_t = c_t->left; - c_d = (c_d+1)%N; - } else - { - actionType = 1; - } - break; - case 1: // backleft - - for(i = 0; i < N; i++) - { - if((c_t->x[i] < range[2*i])||(c_t->x[i] > range[2*i+1])) - break; - } - - if(i == N) - { - - // *** Visit Tree *** - - // Check if xi is in the window centered about yk_ptr - // If so - use it to compute y(k+1) - diff = 0; - j = 0; - s = 0; - while((diff < 1.0)&&(j < kp)) // Partial Distortion Search (PDS) - { - - // test each sub-dimension independently - diff = 0; - for(k = 0; k < P[j]; k++) - { - el = (c_t->x[s+k] - yk_ptr[s+k])/h[j]; - diff += el*el; - } - - s += P[j]; // next subspace - j++; - - } - - if(diff < 1.0) - { - wsum += 1; - for(j = 0; j < N; j++) - Mh_ptr[j] += c_t->x[j]; - } - - } - if ((c_t->x[c_d] < range[2*c_d+1]) && ((c_t->right) != NULL)) - { - c_t = c_t->right; - c_d = (c_d+1)%N; - actionType = 0; - } else - { - actionType = 2; - } - break; - case 2: // backright - c_d = (c_d+N-1)%N; - - if (c_t->parent == NULL) - { - c_t = NULL; - break; - } - - if (c_t->parent->left == c_t) - actionType = 1; - else - actionType = 2; - c_t = c_t->parent; - break; - } - } -} - -/*******************************************************/ -/*General Search */ -/*******************************************************/ -/*Searches the input data using a kd tree, performs the*/ -/*sum on the data within the Hypercube defined by the */ -/*tree using a general kernel. */ -/*******************************************************/ -/*Pre: */ -/* - gt is a possibly NULL pointer to a kd tree */ -/* - Mh_ptr is a pointer to the mean shift vector */ -/* being calculated */ -/* - yk_ptr is a pointer to the current window */ -/* center location */ -/* - gd is the depth of the current subtree */ -/*Post: */ -/* - the mean of the points within the Hypercube */ -/* of the kd tree is computed using a general */ -/* kernel */ -/*******************************************************/ - -void MeanShift::generalSearch(tree *gt, int gd, double *Mh_ptr, double *yk_ptr) -{ - tree* c_t; - int c_d; - int i; - int actionType; - - c_t = gt; - c_d = gd; - actionType = 0; - - double el, diff, u, tw, y0, y1; - int k, j, s, x0, x1; - - while (c_t != NULL) - { - switch(actionType) { - case 0: // forward - if ((c_t->x[c_d] > range[2*c_d]) && ((c_t->left) != NULL)) - { - c_t = c_t->left; - c_d = (c_d+1)%N; - } else - { - actionType = 1; - } - break; - case 1: // backleft - - for(i = 0; i < N; i++) - { - if((c_t->x[i] < range[2*i])||(c_t->x[i] > range[2*i+1])) - break; - } - - if(i == N) - { - - // *** Visit Tree *** - - // Check if xi is in the window centered about yk_ptr - // If so - use it to compute y(k+1) - s = 0; - for(j = 0; j < kp; j++) - { - - // test each sub-dimension independently - diff = 0; - for(k = 0; k < P[j]; k++) - { - el = (c_t->x[s+k] - yk_ptr[s+k])/h[j]; - diff += uv[s+k] = el*el; // Update uv and diff - if(diff >= offset[j]) // Partial Distortion Search (PDS) - break; - } - - if(diff >= offset[j]) // PDS - break; - - s += P[j]; // next subspace - - } - - // j == kp indicates that all subspaces passed the test: - // the data point is within the search window - if(j == kp) j--; - if(diff < offset[j]) - { - - // Initialize total weight to 1 - tw = 1; - - // Calculate weight factor using weight function - // lookup tables and uv - s = 0; - for(j = 0; j < kp; j++) - { - if(kernel[j]) // not uniform kernel - { - // Compute u[i] - u = 0; - for(k = 0; k < P[j]; k++) - u += uv[s+k]; - - // Accumulate tw using calculated u - // and weight function lookup table - - // Linear interpolate values given by - // lookup table - - // Calculate x0 and x1, the points surounding - // u - x0 = (int)(u/increment[j]); - x1 = x0+1; - - // Get y0 and y1 from the lookup table - y0 = w[j][x0]; - y1 = w[j][x1]; - - // Accumulate tw using linear interpolation - tw *= (((double)(x1)*increment[j] - u)*y0+(u - (double)(x0)*increment[j])*y1)/(double)(x1*increment[j] - x0*increment[j]); - - } - s += P[j]; // next subspace - } - - // Perform weighted sum using xi - for(j = 0; j < N; j++) - Mh_ptr[j] += tw*c_t->x[j]; - - // Increment wsum by tw - wsum += tw; - - } - } - if ((c_t->x[c_d] < range[2*c_d+1]) && ((c_t->right) != NULL)) - { - c_t = c_t->right; - c_d = (c_d+1)%N; - actionType = 0; - } else - { - actionType = 2; - } - break; - case 2: // backright - c_d = (c_d+N-1)%N; - - if (c_t->parent == NULL) - { - c_t = NULL; - break; - } - - if (c_t->parent->left == c_t) - actionType = 1; - else - actionType = 2; - c_t = c_t->parent; - break; - } - } -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Mean Shift: Using Lattice ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Uniform Lattice Search */ -/*******************************************************/ -/*Performs search on data set for all points lying */ -/*within the search window defined using a uniform */ -/*kernel. Their point-wise sum and count is computed */ -/*and returned. */ -/* */ -/*NOTE: This method is the only method in the */ -/* MeanShift class that uses the weight */ -/* map asside from optUniformLSearch. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr is a length N array of doubles */ -/* - yk_ptr is a length N array of doubles */ -/* - Mh_ptr is the sum of the data points found */ -/* within search window having center yk_ptr */ -/*Post: */ -/* - a search on the data set using the lattice */ -/* has been performed, and all points found to */ -/* lie within the search window defined using */ -/* a uniform kernel are summed and counted. */ -/* - their point wise sum is pointed to by Mh_ptr */ -/* and their count is stored by wsum. */ -/*******************************************************/ - -void MeanShift::uniformLSearch(double *Mh_ptr, double *yk_ptr) -{ - - //Declare variables - register int i, j, k; - int s, p, dataPoint, lN; - double diff, el, dx, dy, tx, weight; - - //Define lattice data dimension... - lN = N + 2; - - //Define bounds of lattice... - - //the lattice is a 2dimensional subspace whose - //search window bandwidth is specified by - //h[0]: - tx = yk_ptr[0] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundX = 0; - else - LowerBoundX = (int) tx; - tx = yk_ptr[1] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundY = 0; - else - LowerBoundY = (int) tx; - tx = yk_ptr[0] + h[0] - DELTA; - if (tx >= width) - UpperBoundX = width-1; - else - UpperBoundX = (int) tx; - tx = yk_ptr[1] + h[0] - DELTA; - if (tx >= height) - UpperBoundY = height - 1; - else - UpperBoundY = (int) tx; - - //Perform search using lattice - for(i = LowerBoundY; i <= UpperBoundY; i++) - for(j = LowerBoundX; j <= UpperBoundX; j++) - { - - //get index into data array - dataPoint = N*(i*width+j); - - //Determine if inside search window - k = 1; - s = 0; - dx = j - yk_ptr[0]; - dy = i - yk_ptr[1]; - diff = (dx*dx+dy*dy)/(h[0]*h[0]); - while((diff < 1.0)&&(k != kp)) // Partial Distortion Search - { - //Calculate distance squared of sub-space s - diff = 0; - for(p = 0; p < P[k]; p++) - { - el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k]; - if((!p)&&(yk_ptr[2] > 80)) - diff += 4*el*el; - else - diff += el*el; - } - - //next subspace - s += P[k]; - k++; - } - - //if its inside search window perform sum and count - if(diff < 1.0) - { - weight = 1 - weightMap[i*width+j]; - Mh_ptr[0] += weight*j; - Mh_ptr[1] += weight*i; - for(k = 2; k < lN; k++) - Mh_ptr[k] += weight*data[dataPoint+k-2]; - wsum += weight; - } - //done. - } - //done. - return; - -} - -/*******************************************************/ -/*Optimized Uniform Latice Search */ -/*******************************************************/ -/*Performs search on data set for all points lying */ -/*within the search window defined using a uniform */ -/*kernel. Their point-wise sum and count is computed */ -/*and returned. Also the points that lie within the */ -/*window are stored into the basin of attraction stru- */ -/*cture used by the optimized mean shift algorithms. */ -/* */ -/*NOTE: This method is the only method in the */ -/* MeanShift class that uses the weight */ -/* map asside from uniformLSearch. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr is a length N array of doubles */ -/* - yk_ptr is a length N array of doubles */ -/* - Mh_ptr is the sum of the data points found */ -/* within search window having center yk_ptr */ -/*Post: */ -/* - a search on the data set using the latice */ -/* has been performed, and all points found to */ -/* lie within the search window defined using */ -/* a uniform kernel are summed and counted. */ -/* - their point wise sum is pointed to by Mh_ptr */ -/* and their count is stored by wsum. */ -/* - the data points lying within h of of yk_ptr */ -/* have been stored into the basin of attract- */ -/* ion data structure. */ -/*******************************************************/ - -void MeanShift::optUniformLSearch(double *Mh_ptr, double *yk_ptr) -{ - - //Declare variables - register int i, j, k; - int s, p, dataPoint, pointIndx, lN; - double diff, el, dx, dy, tx, weight; - - //Define latice data dimension... - lN = N + 2; - - //Define bounds of latice... - - //the latice is a 2dimensional subspace whose - //search window bandwidth is specified by - //h[0]: - tx = yk_ptr[0] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundX = 0; - else - LowerBoundX = (int) tx; - tx = yk_ptr[1] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundY = 0; - else - LowerBoundY = (int) tx; - tx = yk_ptr[0] + h[0] - DELTA; - if (tx >= width) - UpperBoundX = width-1; - else - UpperBoundX = (int) tx; - tx = yk_ptr[1] + h[0] - DELTA; - if (tx >= height) - UpperBoundY = height - 1; - else - UpperBoundY = (int) tx; - - //Perform search using latice - for(i = LowerBoundY; i <= UpperBoundY; i++) - for(j = LowerBoundX; j <= UpperBoundX; j++) - { - - //get index into data array - pointIndx = i*width+j; - dataPoint = N*(pointIndx); - - //Determine if inside search window - k = 1; - s = 0; - dx = j - yk_ptr[0]; - dy = i - yk_ptr[1]; - diff = (dx*dx+dy*dy)/(h[0]*h[0]); - while((diff < 1.0)&&(k != kp)) // Partial Distortion Search - { - //Calculate distance squared of sub-space s - diff = 0; - for(p = 0; p < P[k]; p++) - { - el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k]; - if((!p)&&(yk_ptr[2] > 80)) - diff += 4*el*el; - else - diff += el*el; - } - - //next subspace - s += P[k]; - k++; - } - - //if its inside search window perform sum and count - if(diff < 1.0) - { - weight = 1 - weightMap[i*width+j]; - Mh_ptr[0] += weight*j; - Mh_ptr[1] += weight*i; - for(k = 2; k < lN; k++) - Mh_ptr[k] += weight*data[dataPoint+k-2]; - wsum += weight; - - //set basin of attraction mode table - if (diff < 0.5) - { - if(modeTable[pointIndx] == 0) - { - pointList[pointCount++] = pointIndx; - modeTable[pointIndx] = 2; - } - } - - } - - //done. - - } - - //done. - return; - -} - -/*******************************************************/ -/*General Lattice Search */ -/*******************************************************/ -/*Performs search on data set for all points lying */ -/*within the search window defined using a general */ -/*kernel. Their point-wise sum and count is computed */ -/*and returned. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr is a length N array of doubles */ -/* - yk_ptr is a length N array of doubles */ -/* - Mh_ptr is the sum of the data points found */ -/* within search window having center yk_ptr */ -/*Post: */ -/* - a search on the data set using the lattice */ -/* has been performed, and all points found to */ -/* lie within the search window defined using */ -/* a general kernel are summed and counted */ -/* - their point wise sum is pointed to by Mh_ptr */ -/* and their count is stored by wsum */ -/*******************************************************/ - -void MeanShift::generalLSearch(double *Mh_ptr, double *yk_ptr) -{ - - //Declare variables - register int i, j, k; - int s, p, dataPoint, lN, x0, x1; - double diff, el, dx, dy, tw, u, y0, y1, tx; - - //Define lattice data dimension... - lN = N + 2; - - //Define bounds of lattice... - - //the lattice is a 2dimensional subspace whose - //search window bandwidth is specified by - //h[0]: - tx = yk_ptr[0] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundX = 0; - else - LowerBoundX = (int) tx; - tx = yk_ptr[1] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundY = 0; - else - LowerBoundY = (int) tx; - tx = yk_ptr[0] + h[0] - DELTA; - if (tx >= width) - UpperBoundX = width-1; - else - UpperBoundX = (int) tx; - tx = yk_ptr[1] + h[0] - DELTA; - if (tx >= height) - UpperBoundY = height - 1; - else - UpperBoundY = (int) tx; - - //Perform search using lattice - for(i = LowerBoundY; i <= UpperBoundY; i++) - for(j = LowerBoundX; j <= UpperBoundX; j++) - { - - //get index into data array - dataPoint = N*(i*width+j); - - //Determine if inside search window - k = 1; - s = 0; - dx = j - yk_ptr[0]; - dy = i - yk_ptr[1]; - uv[0] = (dx*dx)/(h[0]*h[0]); - uv[1] = (dy*dy)/(h[0]*h[0]); - diff = uv[0] + uv[1]; - while((diff < offset[k-1])&&(k != kp)) // Partial Distortion Search - { - //Calculate distance squared of sub-space s - diff = 0; - for(p = 0; p < P[k]; p++) - { - el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k]; - diff += uv[p+s+2] = el*el; - } - - //next subspace - s += P[k]; - k++; - } - - //if its inside search window perform weighted sum and count - if(diff < offset[k-1]) - { - - // Initialize total weight to 1 - tw = 1; - - // Calculate weight factor using weight function - // lookup tables and uv - s = 0; - for(k = 0; k < kp; k++) - { - if(kernel[k]) // not uniform kernel - { - // Compute u[i] - u = 0; - for(p = 0; p < P[k]; p++) - u += uv[s+p]; - - // Accumulate tw using calculated u - // and weight function lookup table - - // Linear interpolate values given by - // lookup table - - // Calculate x0 and x1, the points surounding - // u - x0 = (int)(u/increment[k]); - x1 = x0+1; - - // Get y0 and y1 from the lookup table - y0 = w[k][x0]; - y1 = w[k][x1]; - - // Accumulate tw using linear interpolation - tw *= (((double)(x1)*increment[k] - u)*y0+(u - (double)(x0)*increment[k])*y1)/(double)(x1*increment[k] - x0*increment[k]); - - } - s += P[k]; // next subspace - } - - // Perform weighted sum using xi - Mh_ptr[0] += tw*j; - Mh_ptr[1] += tw*i; - for(k = 0; k < N; k++) - Mh_ptr[k+2] += tw*data[dataPoint+k]; - - // Increment wsum by tw - wsum += tw; - - } - - //done. - - } - - //done. - return; - -} - -/*******************************************************/ -/*Optimized General Lattice Search */ -/*******************************************************/ -/*Performs search on data set for all points lying */ -/*within the search window defined using a general */ -/*kernel. Their point-wise sum and count is computed */ -/*and returned. Also the points that lie within the */ -/*window are stored into the basin of attraction stru- */ -/*cture used by the optimized mean shift algorithms. */ -/*******************************************************/ -/*Pre: */ -/* - Mh_ptr is a length N array of doubles */ -/* - yk_ptr is a length N array of doubles */ -/* - Mh_ptr is the sum of the data points found */ -/* within search window having center yk_ptr */ -/*Post: */ -/* - a search on the data set using the lattice */ -/* has been performed, and all points found to */ -/* lie within the search window defined using */ -/* a general kernel are summed and counted */ -/* - their point wise sum is pointed to by Mh_ptr */ -/* and their count is stored by wsum */ -/* - the data points lying within h*offset of */ -/* yk_ptr have been stored into the basin of */ -/* attraction data structure. */ -/*******************************************************/ - -void MeanShift::optGeneralLSearch(double *Mh_ptr, double *yk_ptr) -{ - - //Declare variables - register int i, j, k; - int s, p, dataPoint, pointIndx, lN, x0, x1; - double diff, el, dx, dy, tw, u, y0, y1, tx; - - //Define lattice data dimension... - lN = N + 2; - - //Define bounds of lattice... - - //the lattice is a 2dimensional subspace whose - //search window bandwidth is specified by - //h[0]: - tx = yk_ptr[0] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundX = 0; - else - LowerBoundX = (int) tx; - tx = yk_ptr[1] - h[0] + DELTA + 0.99; - if (tx < 0) - LowerBoundY = 0; - else - LowerBoundY = (int) tx; - tx = yk_ptr[0] + h[0] - DELTA; - if (tx >= width) - UpperBoundX = width-1; - else - UpperBoundX = (int) tx; - tx = yk_ptr[1] + h[0] - DELTA; - if (tx >= height) - UpperBoundY = height - 1; - else - UpperBoundY = (int) tx; - - //Perform search using lattice - for(i = LowerBoundY; i <= UpperBoundY; i++) - for(j = LowerBoundX; j <= UpperBoundX; j++) - { - - //get index into data array - pointIndx = i*width+j; - dataPoint = N*(i*width+j); - - //Determine if inside search window - k = 1; - s = 0; - dx = j - yk_ptr[0]; - dy = i - yk_ptr[1]; - uv[0] = (dx*dx)/(h[0]*h[0]); - uv[1] = (dy*dy)/(h[0]*h[0]); - diff = uv[0] + uv[1]; - while((diff < offset[k-1])&&(k != kp)) // Partial Distortion Search - { - //Calculate distance squared of sub-space s - diff = 0; - for(p = 0; p < P[k]; p++) - { - el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k]; - diff += uv[p+s+2] = el*el; - } - - //next subspace - s += P[k]; - k++; - } - - //if its inside search window perform weighted sum and count - if(diff < offset[k-1]) - { - - // Initialize total weight to 1 - tw = 1; - - // Calculate weight factor using weight function - // lookup tables and uv - s = 0; - for(k = 0; k < kp; k++) - { - if(kernel[k]) // not uniform kernel - { - // Compute u[i] - u = 0; - for(p = 0; p < P[k]; p++) - u += uv[s+p]; - - // Accumulate tw using calculated u - // and weight function lookup table - - // Linear interpolate values given by - // lookup table - - // Calculate x0 and x1, the points surounding - // u - x0 = (int)(u/increment[k]); - x1 = x0+1; - - // Get y0 and y1 from the lookup table - y0 = w[k][x0]; - y1 = w[k][x1]; - - // Accumulate tw using linear interpolation - tw *= (((double)(x1)*increment[k] - u)*y0+(u - (double)(x0)*increment[k])*y1)/(double)(x1*increment[k] - x0*increment[k]); - - } - s += P[k]; // next subspace - } - - // Perform weighted sum using xi - Mh_ptr[0] += tw*j; - Mh_ptr[1] += tw*i; - for(k = 0; k < N; k++) - Mh_ptr[k+2] += tw*data[dataPoint+k]; - - // Increment wsum by tw - wsum += tw; - - //set basin of attraction mode table - if(modeTable[pointIndx] == 0) - { - pointList[pointCount++] = pointIndx; - modeTable[pointIndx] = 2; - } - - } - - //done. - - } - - //done. - return; - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - diff --git a/Modules/ThirdParty/Edison/src/otbedison/ms.h b/Modules/ThirdParty/Edison/src/otbedison/ms.h deleted file mode 100644 index f6ce409403f79f7637a36f68535837235a4f6f0e..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/ms.h +++ /dev/null @@ -1,926 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - MeanShift Base Class: - ==================== - - The mean shift library of routines is realized - via the creation of a MeanShift base class. This class - provides a mechanism for calculating the mean shift vector - at a specified data point, using an arbitrary N-dimensional - data set, and a user-defined kernel. - - For image processing the mean shift base class also allows - for the definition of a data set that is on a two-dimensional - lattice. The amount of time needed to compute the mean shift - vector using such a data set is much less than that of an - arbitrary one. Because images usually contain many data points, - defining the image input data points as being on a lattice - greatly improves computation time and makes algorithms such - as image filtering practical. - - The MeanShift class prototype is provided below. Its - definition is provided in 'ms.cc'. - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -#ifndef MS_H -#define MS_H - -//Included needed libraries - -//Include type definitions -#include "tdef.h" - -//include mean shift system used -//for function timing and system output -#include "msSys.h" - -//Include Debugging Constant -//#define DEBUG - -//Define Prompt - Prompts user on progress of Mean Shift algorithm -#define PROMPT - -//Define Show Progress - Prompts user on percent complete of a given -// mean shift algorithm -//#define SHOW_PROGRESS - -//Define Progress Rate - Indicates the number of convergences before -// checking progress -#define PROGRESS_RATE 100 - -// Define Macros -#define SWAP(d_a, d_b) temp=(d_a);(d_a)=(d_b);(d_b)=temp; - -// Define Structures - - //k-Dimensional Binary Search Tree -struct tree { - float *x; - tree *right; - tree *left; - tree *parent; -}; - - // User Defined Weight Function -struct userWeightFunct { - - double *w; - double halfWindow; - int sampleNumber; - int subspace; - userWeightFunct *next; - -}; - -//Define class state structure -struct ClassStateStruct { - bool KERNEL_DEFINED; - bool INPUT_DEFINED; - bool LATTICE_DEFINED; - bool OUTPUT_DEFINED; -}; - -// Define Constants - - // Threshold -const double EPSILON = 0.01; // define threshold (approx. Value of Mh at a peak or plateau) -const double MU = 0.05; // define threshold required that window is near convergence -const double TC_DIST_FACTOR = 0.5; // cluster search windows near convergence that are a distance - // h[i]*TC_DIST_FACTOR of one another (transitive closure) -const double SQ_TC_DFACTOR = 0.0625; // (TC_DIST_FACTOR)^2 -const int LIMIT = 100; // define max. # of iterations to find mode - - // Gaussian Lookup Table -const int GAUSS_NUM_ELS = 16; // take 16 samples of exp(-u/2) -const double GAUSS_LIMIT = 2.9; // GAUSS_LIMIT = c -const double GAUSS_INCREMENT = GAUSS_LIMIT*GAUSS_LIMIT/GAUSS_NUM_ELS; - // GAUSS_INCREMENT = (c^2)/(# of samples) - - // Numerical Analysis -const double DELTA = 0.00001; // used for floating point to integer conversion - -//MeanShift Prototype -class MeanShift { - - public: - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - MeanShift( void ); //Default Constructor - ~MeanShift( void ); //Class Destructor - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Creation/Initialization of Mean Shift Kernel */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Define Kernel * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Uploads a custom kernel into the private data |// - //| members of the mean shift class. This kernel is |// - //| used by the mean shift class to perform mean |// - //| shift. |// - //| |// - //| In order to create a valid kernel the following |// - //| argumens must be provided this method: |// - //| |// - //| <* kernel *> |// - //| A one dimensional array of type kernelType used |// - //| to specify the kernel type (Uniform, Gaussian, |// - //| or User Defined) of a given subspace of the input|// - //| set. Entry i of kernel correlates to the i-th |// - //| subspace of the input data set. |// - //| |// - //| <* h *> |// - //| A one dimensional array of floating point numb- |// - //| ers that are used to normalize the input data |// - //| set, each bandwidth specifying the relative imp- |// - //| ortance of a subspace of the input data set. |// - //| |// - //| <* kp *> |// - //| An integer that specifies the number of sub- |// - //| contained by the input data set. Both P and h |// - //| therefore consist of kp entries. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| DefineKernel(kernel, h, P, kp) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void DefineKernel(kernelType*, float*, int*, int); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Add Weight Function * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Each subspace specified as User Defined is un- |// - //| quely defined by a correlating weight function |// - //| which is user defined. |// - //| |// - //| A weight function w(u) exhibits the following |// - //| properties: |// - //| |// - //| (1) w(u) = w(-u) |// - //| (2) u = ((x_i-y_k)^2)/(h^2) (see docs) |// - //| (3) w(u) = 0, for |u| >= halfWindow |// - //| |// - //| To add a weight function to the mean shift class |// - //| the following must be specified: |// - //| |// - //| <* g() *> |// - //| A pointer the weight function w(u) exhibiting |// - //| the above properties. |// - //| |// - //| <* halfWindow *> |// - //| A floating point number specifying where w(u) |// - //| exists (is non zero). [See Property 3 Above] |// - //| |// - //| <* sampleNumber *> |// - //| An integer used to specify the number of samples |// - //| used to describe w(u). Linear interpolation is |// - //| used during the mean shift calculation using the |// - //| the samples of w(u) to determine the value of w |// - //| at a location |u| < halfWindow. |// - //| |// - //| <* subspace *> |// - //| An integer specifying which kernel w(u) defines. |// - //| |// - //| Weight functions are accounted for every time |// - //| a new kernel is created. |// - //| |// - //| If a weight function is added to non-existing |// - //| subspace of the input data set (example: the |// - //| input data set containes 3 subspaces and this |// - //| method is given subspace = 4) then the weight |// - //| defintion will simply be ignored by the mean |// - //| shift class. |// - //| |// - //| If a subspace is declared as kernel type User |// - //| Defined and a weight function is not defined |// - //| for that subspace a fatal error will occur. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| AddWeightFunction(g(u) , halfWindow, |// - //| sampleNumber, subspace); |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void AddWeightFunction(double g(double), float, int, int); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Clear Weight Functions * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Removes all user defined weight functions added |// - //| using method AddWeightFunction() from the |// - //| private data members of the mean shift class. |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void ClearWeightFunctions( void ); - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Input Data Set Declaration */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Define Input * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Uploads a one dimensional array containing L |// - //| N-dimensional data points into the mean shift |// - //| class. |// - //| |// - //| An input data set is specified by: |// - //| |// - //| <* x *> |// - //| A pointer to a floating point array. |// - //| |// - //| <* L *> |// - //| The number of data points stored by x. |// - //| |// - //| <* N *> |// - //| The dimension of the data points stored by x. |// - //| |// - //| The input x has the following format: |// - //| |// - //| x = <x11, x12,..., x1N,..., xL1, xL2,..., xLN> |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| DefineInput(x, L, N) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void DefineInput(float*, int, int); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Define Lattice Input * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Use this method to specify define an input data |// - //| set defined on a lattice. |// - //| |// - //| The arguments of this method are: |// - //| |// - //| <* x *> |// - //| A pointer to a floating point array containing |// - //| height*width, N-dimensional data points. |// - //| |// - //| <* height *> |// - //| An integer specifying the height of the lattice. |// - //| |// - //| <* width *> |// - //| An integer specifying the width of the lattice. |// - //| |// - //| <* N *> |// - //| The dimension of the data points stored by x. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| DefineLInput(x, height, width, N) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void DefineLInput(float*, int, int, int); - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Lattice Weight Map */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Set Lattice Weight Map * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Uploads weight map specifying for each data |// - //| point a value used to weight the uniform kernel |// - //| when computing mean shift. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* weightMap *> |// - //| A floating point array of size L specifying for |// - //| each data point a weight. |// - //| |// - //| Note: DefineLInput must be called prior to call- |// - //| ing this method. DefineLInput is used to |// - //| define the dimensions of the input data |// - //| set. |// - //| |// - //| |// - //| The weight map is used to weight the uniform |// - //| kernel used to computing meanshift on a data |// - //| point situated on a lattice. Alternatively, a |// - //| weight function may defined, however, if speed |// - //| is an issue, the lattice may be exploited to |// - //| result in a faster implementation of a weighted |// - //| kernel. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| SetLatticeWeightMap(weightMap) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void SetLatticeWeightMap(float*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Remove Lattice Weight Map * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Removes lattice weight map. An error is NOT |// - //| flagged if a weight map was not defined prior |// - //| to calling this method. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| RemoveLatticeWeightMap(weightMap) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void RemoveLatticeWeightMap(void); - - /*/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift Operations */ - /*\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Mean Shift Vector * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| If a kernel is created and input is uploaded, |// - //| this method calcualtes the mean shift vector, |// - //| Mh, at specific data point yk. |// - //| |// - //| The arguments of this method are: |// - //| |// - //| <* Mh *> |// - //| An array of N doubles storing the N dimensional |// - //| mean shift vector. |// - //| |// - //| <* yk *> |// - //| An array of N doubles storing the N dimensional |// - //| data point where the mean shift vector is to be |// - //| calculate. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| msVector(Mh, yk) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void msVector(double*, double*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Lattice Mean Shift Vector * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| If a kernel is created and input is uploaded, |// - //| this method calcualtes the mean shift vector, |// - //| Mh, at specific data point yk, assuming that the |// - //| data set exhists on a height x width two dim- |// - //| ensional lattice. |// - //| |// - //| The arguments of this method are: |// - //| |// - //| <* Mh *> |// - //| An array of N doubles storing the N dimensional |// - //| mean shift vector. |// - //| |// - //| <* yk *> |// - //| An array of N doubles storing the N dimensional |// - //| data point where the mean shift vector is to be |// - //| calculate. |// - //| |// - //| The height and width of the lattice must be |// - //| specified using DefineLattice() method. If this |// - //| is not performed prior to calling this method a |// - //| fatal error will be flagged. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| latticeMSVector(Mh, yk) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void latticeMSVector(double*, double*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Find Mode * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| If a kernel is created and input is uploaded, |// - //| this method calcualtes the mode of a specified |// - //| data point yk. |// - //| |// - //| The arguments of this method are: |// - //| |// - //| <* mode *> |// - //| An array of N doubles storing the N dimensional |// - //| mode of yk. |// - //| |// - //| <* yk *> |// - //| An array of N doubles storing the N dimensional |// - //| data point where the mean shift vector is to be |// - //| calculate. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| FindMode(mode, yk) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void FindMode(double*, double*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Find Lattice Mode * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| If a kernel is created and input is uploaded, |// - //| this method calcualtes the mode of a specified |// - //| data point yk, assuming that the data set |// - //| exhists on a height x width two dimensional |// - //| lattice. |// - //| |// - //| The arguments of this method are: |// - //| |// - //| <* mode *> |// - //| An array of N doubles storing the N dimensional |// - //| mode of yk. |// - //| |// - //| <* yk *> |// - //| An array of N doubles storing the N dimensional |// - //| data point where the mean shift vector is to be |// - //| calculate. |// - //| |// - //| The height and width of the lattice must be |// - //| specified using DefineLattice() method. If this |// - //| is not performed prior to calling this method a |// - //| fatal error will be flagged. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| FindLMode(mode, yk) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void FindLMode(double*, double*); - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Error Handler Mechanism */ - /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| ErrorMessage is an error message that is set by |// - //| a mean shift library class when an error occurs. |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - char *ErrorMessage; - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| ErrorStatus indicates if an error has occured as |// - //| a result of improper use of a mean shift library |// - //| class method or because of insufficient resour- |// - //| ces. ErrorStatus is set to EL_ERROR (ErrorStatus |// - //| = 1) if an error has occured. If no error occur- |// - //| ed when calling a particular method ErrorStatus |// - //| is set to EL_OKAY (ErrorStatus = 0). |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - ErrorLevel ErrorStatus; - - protected: - - //========================== - // *** Protected Methods *** - //========================== - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using kd-Tree */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - ///////////////////////////////////////// - // <<*>> Usage: MSVector(Mh, yk) <<*>> // - ///////////////////////////////////////// - - void MSVector (double*, double*); // Computes the mean shift vector at a specified - // window location yk in the data set x given - // the vector yk - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using Lattice */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //////////////////////////////////////////////// - // <<*>> Usage: LatticeMSVector(Mh, yk) <<*>> // - //////////////////////////////////////////////// - - void LatticeMSVector (double*, double*); // Uses the lattice defined by DefineLattice to compute the - // mean shift vector at a specified window location yk - - /////////////////////////////////////////////////// - // <<*>> Usage: OptLatticeMSVector(Mh, yk) <<*>> // - /////////////////////////////////////////////////// - - void OptLatticeMSVector (double*, double*); // Uses the lattice defined by DefineLattice to compute the - // mean shift vector at a specified window location yk using - // the basin of attraction optimization for better performace - // during mean shift filtering - used by a derived class - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Kernel-Input Data Consistency */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - ///////////////////////////////////////////////// - // <<*>> Usage: classConsistencyCheck(N) <<*>> // - ///////////////////////////////////////////////// - - void classConsistencyCheck(int, bool); // checks to see that a kernel is created and input defined, as - // well as the specified dimension of the data set matches that of - // the kernel, if not an error is flagged and the program is halted - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Error Handler */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - - ///////////////////////////////////////////////////// - // <<*>> Usage: ErrorHandler( <<*>> // - // className, functName, errMessage) // - ///////////////////////////////////////////////////// - - void ErrorHandler(char*, char*, char*); // flags an error and halts the system - - - //=============================== - // *** Protected Data Members *** - //=============================== - - //########################################## - //######### MEAN SHIFT SYSTEM ########## - //########################################## - - msSystem msSys; // used for function timing and system output - - //########################################## - //######### INPUT DATA PARAMETERS ########## - //########################################## - - int L, N, kp, *P; // length, dimension, subspace number, and subspace dimensions - - - //########################################## - //######### INPUT DATA STORAGE ########## - //########################################## - - ////////Linear Storage (used by lattice and bst)//////// - float *data; // memory allocated for data points stored by tree nodes - // when used by the lattice data structure data does not store - // the lattice information; format of data: - // data = <x11, x12, ..., x1N,...,xL1, xL2, ..., xLN> - // in the case of the lattice the i in data(i,j) corresponds - - //########################################## - //######## LATTICE DATA STRUCTURE ########## - //########################################## - - ////////Lattice Data Structure//////// - int height, width; // Height and width of lattice - - //########################################## - //######### KERNEL DATA STRUCTURE ########## - //########################################## - - float *h; // bandwidth vector - - float *offset; // defines bandwidth offset caused by the use of a Gaussian kernel - // (for example) - - //########################################## - //######### BASIN OF ATTRACTION ########## - //########################################## - - unsigned char *modeTable; // Assigns a marking to each data point specifying whether - // or not it has been assigned a mode. These labels are: - // modeTable[i] = 0 - data point i is not associated with a mode - // modeTable[i] = 1 - data point i is associated with a mode - // modeTable[i] = 2 - data point i is associated with a mode - // however its mode is yet to be determined - - int *pointList; // a list of data points that due to basin of attraction will - // converge to the same mode as the mode that mean shift is - // currently being applied to - - int pointCount; // the number of points stored by the point list - - - //########################################## - //######### WEIGHT MAP USED ########## - //######### WHEN COMPUTING MEAN ########## - //######### SHIFT ON A LATTICE ########## - //########################################## - - float *weightMap; // weight map that may be used to weight the kernel - // upon performing mean shift on a lattice - - bool weightMapDefined; // used to indicate if a lattice weight map has been - // defined - - //########################################## - //####### CLASS STATE ######## - //########################################## - - ClassStateStruct class_state; //specifies the state of the class(i.e if data has been loaded into - //the class, if a kernel has been defined, etc.) - - private: - - //======================== - // *** Private Methods *** - //======================== - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Kernel Creation/Manipulation */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void generateLookupTable ( void ); // Generates Weight Function Lookup Table - - void DestroyKernel ( void ); // Destroys mean shift kernel, re-initializes kernel - - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Input Data Initialization/Destruction */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void CreateBST ( void ); // Upload input into a kd-BST - - void InitializeInput (float*); // Allocates memory for and initializes the input data structure - - void ResetInput ( void ); // de-allocate memory for and re-initialize input data structure - // and mode structure - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* k-dimensional Binary Search Tree */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - ////////Data Search Tree///////// - tree *BuildKDTree (tree*, int, int, tree* ); // Builds a kd tree given a subset of points initialized - // at depth 0 (dimension 0) (for Tree Structure) - - void QuickMedian (tree*, int, int, int ); // Finds the median tree in a forest of trees using - // dimension d, placing the median tree in the array of tree - // nodes at L/2, in which all trees to the left of the median tree - // have values less than that of the median tree in dimension d - // and all trees having values greater than that of the median tree - // in dimension d are placd to the right of this tree - - // This algorithm is used by BuildKDTree to construct a balanced tree - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using kd-Tree */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void uniformSearch (tree*, int, double*, double*); // uses kdbst to perform range search on input data, - // computing the weighted sum of these points using - // a uniform kernel and storing the result into Mh - // (called by uniformMSVector) - - void generalSearch (tree*, int, double*, double*); // uses kdbst to perform range search on input data, - // computing the weighted sum of these points using - // a general kernel and storing the result into Mh - // (called by generalMSVector) - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Mean Shift: Using Lattice */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void uniformLSearch (double *, double *); // given a center location and mean shift vector, a lattice - // search is performed to compute the mean shift vector - // using a uniform kernel - - void optUniformLSearch(double *, double *); // given a center location and mean shift vector, a lattice - // search is performed to compute the mean shift vector - // using a uniform kernel and the basin of attraction - // optimization for better performance - - void generalLSearch (double *, double *); // given a center location and mean shift vector, a lattice - // search is performed to compute the mean shift vector - // using a general kernel - - void optGeneralLSearch(double *, double *); // given a center location and mean shift vector, a lattice - // search is performed to compute the mean shift vector - // using a general kernel and the basin of attraction - // optimization for better performance - - - //============================= - // *** Private Data Members *** - //============================= - - //########################################## - //######### KERNEL DATA STRUCTURE ########## - //########################################## - - kernelType *kernel; // kernel types for each subspace S[i] - - double **w; // weight function lookup table - - double *increment; // increment used by weight hashing function - - bool uniformKernel; // flag used to indicate if the kernel is uniform or not - - userWeightFunct *head, *cur; // user defined weight function linked list - - - //########################################## - //######### INPUT DATA STORAGE ########## - //########################################## - - ////////Range Searching on General Input Data Set//////// - tree *root; // root of kdBST used to store input - - tree *forest; // memory allocated for tree nodes - - float *range; // range vector used to perform range search on kd tree, indexed - // by dimension of input - format: - // range = {Lower_Limit_1, Upper_Limit_1, ..., Lower_Limit_N, Upper_Limit_N} - - //########################################## - //######### MEAN SHIFT PROCESSING ########## - //######### DATA STRUCTURES ########## - //########################################## - - double *uv; // stores normalized distance vector between - // yk and xi - - double wsum; // sum of weights calculated at data points within the sphere - - //########################################## - //######### LATTICE DATA STRUCTURE ######### - //########################################## - - ////////Lattice Data Structure//////// - int LowerBoundX, UpperBoundX; // Upper and lower bounds for lattice search window - // in the x dimension - - int LowerBoundY, UpperBoundY; // Upper and lower bounds for lattice search window - // in the y dimension - -}; - -#endif diff --git a/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.cpp b/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.cpp deleted file mode 100644 index 80951df9ac3f99f651bfea11fa62b244937aacb1..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.cpp +++ /dev/null @@ -1,4673 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Mean Shift Image Processor Class: - ================================ - - The following class inherits from the mean shift library - in order to perform the specialized tasks of image - segmentation and filtering. - - The definition of the Mean Shift Image Processor Class - is provided below. Its prototype is provided in - 'msImageProcessor.h'. - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -//include image processor class prototype -#include "msImageProcessor.h" - -//include needed libraries -#include <math.h> -#include <stdio.h> -#include <assert.h> -#include <string.h> -#include <stdlib.h> - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Constructor/Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Constructor */ -/*******************************************************/ -/*Post: */ -/* The msImageProcessor class has been properly */ -/* initialized. */ -/*******************************************************/ - -msImageProcessor::msImageProcessor( void ) -{ - - //intialize basin of attraction structure - //used by the filtering algorithm - modeTable = NULL; - pointList = NULL; - pointCount = 0; - - //initialize region list - regionList = NULL; - - //initialize output structures... - msRawData = NULL; - labels = NULL; - modes = NULL; - modePointCounts = NULL; - regionCount = 0; - - //intialize temporary buffers used for - //performing connected components - indexTable = NULL; - LUV_data = NULL; - - //initialize region adjacency matrix - raList = NULL; - freeRAList = NULL; - raPool = NULL; - - //intialize visit table to having NULL entries - visitTable = NULL; - - //initialize epsilon such that transitive closure - //does not take edge strength into consideration when - //fusing regions of similar color - epsilon = 1.0; - - //initialize class state to indicate that - //an output data structure has not yet been - //created... - class_state.OUTPUT_DEFINED = false; - - - LUV_treshold = 1.0; -} - -/*******************************************************/ -/*Class Destructor */ -/*******************************************************/ -/*Post: */ -/* The msImageProcessor class has been properly */ -/* destroyed. */ -/*******************************************************/ - -msImageProcessor::~msImageProcessor( void ) -{ - - //de-allocate memory - if(class_state.OUTPUT_DEFINED) DestroyOutput(); - if(regionList) delete regionList; - regionList = NULL; - - //done. - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Input Image Declaration */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Define Image */ -/*******************************************************/ -/*Uploads an image into the image segmenter class to */ -/*be segmented. */ -/*******************************************************/ -/*Pre: */ -/* - data_ is a one dimensional array of unsigned */ -/* char RGB vectors */ -/* - type is the type of the image: COLOR or */ -/* GREYSCALE */ -/* - height_ and width_ define the dimension of */ -/* the image */ -/* - if the image is of type GREYSCALE then */ -/* data containes only one number per pixel */ -/* location, where a pixel location is defined */ -/* by the index into the data array */ -/*Post: */ -/* - the image specified has been uploaded into */ -/* the image segmenter class to be segmented. */ -/*******************************************************/ - -void msImageProcessor::DefineImage(byte *data_, imageType type, int height_, int width_) -{ - - //obtain image dimension from image type - int dim; - if(type == COLOR) - dim = 3; - else - dim = 1; - - //perfor rgb to luv conversion - int i; - float *luv = new float [height_*width_*dim]; - if(dim == 1) - { - for(i = 0; i < height_*width_; i++) - luv[i] = (float)(data_[i]); - } - else - { - for(i = 0; i < height_*width_; i++) - RGBtoLUV(&data_[dim*i], &luv[dim*i]); - } - - //define input defined on a lattice using mean shift base class - DefineLInput(luv, height_, width_, dim); - - //Define a default kernel if it has not been already - //defined by user - if(!h) - { - //define default kernel paramerters... - kernelType k[2] = {Uniform, Uniform}; - int P[2] = {2, N}; - float tempH[2] = {1.0 , 1.0}; - - //define default kernel in mean shift base class - DefineKernel(k, tempH, P, 2); - } - - //de-allocate memory - delete [] luv; - - //done. - return; - -} - -void msImageProcessor::DefineBgImage(byte* data_, imageType type, int height_, int width_) -{ - - //obtain image dimension from image type - int dim; - if(type == COLOR) - dim = 3; - else - dim = 1; - - //perform texton classification - int i; - float *luv = new float [height_*width_*dim]; - if(dim == 1) - { - for(i = 0; i < height_*width_; i++) - luv[i] = (float)(data_[i]); - } - else - { - for(i = 0; i < height_*width_; i++) - RGBtoLUV(&data_[dim*i], &luv[dim*i]); - } - - //define input defined on a lattice using mean shift base class - DefineLInput(luv, height_, width_, dim); - - //Define a default kernel if it has not been already - //defined by user - if(!h) - { - //define default kernel paramerters... - kernelType k[2] = {Uniform, Uniform}; - int P[2] = {2, N}; - float tempH[2] = {1.0 , 1.0}; - - //define default kernel in mean shift base class - DefineKernel(k, tempH, P, 2); - } - - //de-allocate memory - delete [] luv; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\*/ - /* Weight Map */ - /*\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Set Weight Map */ -/*******************************************************/ -/*Populates the weight map with specified edge */ -/*strengths. */ -/*******************************************************/ -/*Pre: */ -/* - wm is a floating point array of size */ -/* (height x width) specifying for each pixel */ -/* edge strength. */ -/* - eps is a threshold used to fuse similar */ -/* regions during transitive closure. */ -/*Post: */ -/* - wm has been used to populate the weight */ -/* map. */ -/* - the threshold used during transitive closure */ -/* is taken as eps. */ -/*******************************************************/ - -void msImageProcessor::SetWeightMap(float *wm, float eps) -{ - - //initlaize confmap using wm - SetLatticeWeightMap(wm); - - //set threshold value - if((epsilon = eps) < 0) - ErrorHandler("msImageProcessor", "SetWeightMap", "Threshold is negative."); - - //done. - return; - -} - -/*******************************************************/ -/*Remove Weight Map */ -/*******************************************************/ -/*Removes the weight map. */ -/*******************************************************/ -/*Post: */ -/* - the weight map has been removed. */ -/* - if a weight map did not exist NO error */ -/* is flagged. */ -/*******************************************************/ - -void msImageProcessor::RemoveWeightMap( void ) -{ - - //remove confmap - RemoveLatticeWeightMap(); - - //set threshold value to zero - epsilon = 0; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\*/ - /* Image Filtering */ - /*\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Filter */ -/*******************************************************/ -/*Performs mean shift filtering on the specified input */ -/*image using a user defined kernel. */ -/*******************************************************/ -/*Pre: */ -/* - the user defined kernel used to apply mean */ -/* shift filtering to the defined input image */ -/* has spatial bandwidth sigmaS and range band- */ -/* width sigmaR */ -/* - speedUpLevel determines whether or not the */ -/* filtering should be optimized for faster */ -/* execution: a value of NO_SPEEDUP turns this */ -/* optimization off and a value SPEEDUP turns */ -/* this optimization on */ -/* - a data set has been defined */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/*Post: */ -/* - mean shift filtering has been applied to the */ -/* input image using a user defined kernel */ -/* - the filtered image is stored in the private */ -/* data members of the msImageProcessor class. */ -/*******************************************************/ - -void msImageProcessor::Filter(int sigmaS, float sigmaR, SpeedUpLevel speedUpLevel) -{ - - //Check Class consistency... - - //check: - // (1) if this operation is consistent - // (2) if kernel was created - // (3) if data set is defined - // (4) if the dimension of the kernel agrees with that - // of the defined data set - // if not ... flag an error! - classConsistencyCheck(N+2, true); - if(ErrorStatus == EL_ERROR) - return; - - //If the algorithm has been halted, then exit - if((ErrorStatus = msSys.Progress((float)(0.0))) == EL_HALT) - { - return; - } - - //If the image has just been read then allocate memory - //for and initialize output data structure used to store - //image modes and their corresponding regions... - if(class_state.OUTPUT_DEFINED == false) - { - InitializeOutput(); - - //check for errors... - if(ErrorStatus == EL_ERROR) - return; - } - - //****************** Allocate Memory ****************** - - //Allocate memory for basin of attraction mode structure... - if((!(modeTable = new unsigned char [L]))||(!(pointList = new int [L]))) - { - ErrorHandler("msImageProcessor", "Allocate", "Not enough memory."); - return; - } - - //start timer -#ifdef PROMPT - double timer; - msSys.StartTimer(); -#endif - - //***************************************************** - - //filter image according to speedup level... - switch(speedUpLevel) - { - //no speedup... - case NO_SPEEDUP: - //NonOptimizedFilter((float)(sigmaS), sigmaR); break; - NewNonOptimizedFilter((float)(sigmaS), sigmaR); break; - //medium speedup - case MED_SPEEDUP: - //OptimizedFilter1((float)(sigmaS), sigmaR); break; - NewOptimizedFilter1((float)(sigmaS), sigmaR); break; - //high speedup - case HIGH_SPEEDUP: - //OptimizedFilter2((float)(sigmaS), sigmaR); break; - NewOptimizedFilter2((float)(sigmaS), sigmaR); break; - // new speedup - } - - //****************** Deallocate Memory ****************** - - //de-allocate memory used by basin of attraction mode structure - delete [] modeTable; - delete [] pointList; - - //re-initialize structure - modeTable = NULL; - pointList = NULL; - pointCount = 0; - - //******************************************************* - - //If the algorithm has been halted, then de-allocate the output - //and exit - if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT) - { - DestroyOutput(); - return; - } - - //Label image regions, also if segmentation is not to be - //performed use the resulting classification structure to - //calculate the image boundaries... - - /* - //copy msRawData into LUV_data, rounding each component of each - //LUV value stored by msRawData to the nearest integer - int i; - for(i = 0; i < L*N; i++) - { - if(msRawData[i] < 0) - LUV_data[i] = (int)(msRawData[i] - 0.5); - else - LUV_data[i] = (int)(msRawData[i] + 0.5); - } - */ - int i; - for (i=0; i<L*N; i++) - { - LUV_data[i] = msRawData[i]; - } - - -#ifdef PROMPT - timer = msSys.ElapsedTime(); - msSys.Prompt("(%6.2f sec)\nConnecting regions ...", timer); - msSys.StartTimer(); -#endif - - //Perform connecting (label image regions) using LUV_data - Connect(); - -#ifdef PROMPT - timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount); - msSys.StartTimer(); -#endif - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Region Fusing */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Fuse Regions */ -/*******************************************************/ -/*Fuses the regions of a filtered image. */ -/*******************************************************/ -/*Pre: */ -/* - the range radius is specified by sigmaR */ -/* - minRegion is the minimum point density that */ -/* a region may have in the resulting segment- */ -/* ed image */ -/* - a data set has been defined */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/*Post: */ -/* - the image regions have been fused. */ -/* - if an result is stored by this class then */ -/* this result is used as input to this method. */ -/* - if no result is stored by this class, */ -/* the input image defined by calling the */ -/* method DefineImage is used. */ -/*******************************************************/ - -void msImageProcessor::FuseRegions(float sigmaS, int minRegion) -{ - - //Check Class consistency... - - //check: - // (1) if this operation is consistent - // (2) if kernel was created - // (3) if data set is defined - // (4) if the dimension of the kernel agrees with that - // of the defined data set - // if not ... flag an error! - classConsistencyCheck(N+2, true); - if(ErrorStatus == EL_ERROR) - return; - - //Check to see if the algorithm is to be halted, if so then - //destroy output and exit - if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT) - { - if(class_state.OUTPUT_DEFINED) DestroyOutput(); - return; - } - - //obtain sigmaS (make sure it is not zero or negative, if not - //flag an error) - if((h[1] = sigmaS) <= 0) - { - ErrorHandler("msImageProcessor", "FuseRegions", "The feature radius must be greater than or equal to zero."); - return; - } - - //if output has not yet been generated then classify the input - //image regions to be fused... - if(!(class_state.OUTPUT_DEFINED)) - { - - //Initialize output data structure used to store - //image modes and their corresponding regions... - InitializeOutput(); - - //check for errors... - if(ErrorStatus == EL_ERROR) - return; - - //copy data into LUV_data used to classify - //image regions - /* - int i; - for(i = 0; i < L*N; i++) - { - if(data[i] < 0) - LUV_data[i] = (int)(data[i] - 0.5); - else - LUV_data[i] = (int)(data[i] + 0.5); - } - */ - int i; - for (i=0; i<L*N; i++) - { - LUV_data[i] = data[i]; - } - -#ifdef PROMPT - msSys.Prompt("Connecting regions ..."); - msSys.StartTimer(); -#endif - - //Perform connecting (label image regions) using LUV_data - Connect(); - - //check for errors - if(ErrorStatus == EL_ERROR) - return; - -#ifdef PROMPT - double timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount); -#endif - - } - - //Check to see if the algorithm is to be halted, if so then - //destroy output and exit - if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT) - { - DestroyOutput(); - return; - } - -#ifdef PROMPT - msSys.Prompt("Applying transitive closure..."); - msSys.StartTimer(); -#endif - - //allocate memory visit table - visitTable = new unsigned char [L]; - - //Apply transitive closure iteratively to the regions classified - //by the RAM updating labels and modes until the color of each neighboring - //region is within sqrt(rR2) of one another. - rR2 = (float)(h[1]*h[1]*0.25); - TransitiveClosure(); - int oldRC = regionCount; - int deltaRC, counter = 0; - do { - TransitiveClosure(); - deltaRC = oldRC-regionCount; - oldRC = regionCount; - counter++; - } while ((deltaRC <= 0)&&(counter < 10)); - - //de-allocate memory for visit table - delete [] visitTable; - visitTable = NULL; - - //Check to see if the algorithm is to be halted, if so then - //destroy output and region adjacency matrix and exit - if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT) - { - DestroyRAM(); - DestroyOutput(); - return; - } - -#ifdef PROMPT - double timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions ...", timer, regionCount); - msSys.StartTimer(); -#endif - - //Prune spurious regions (regions whose area is under - //minRegion) using RAM - Prune(minRegion); - -#ifdef PROMPT - timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount); - msSys.StartTimer(); -#endif - - //Check to see if the algorithm is to be halted, if so then - //destroy output and region adjacency matrix and exit - if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT) - { - DestroyRAM(); - DestroyOutput(); - return; - } - - //de-allocate memory for region adjacency matrix - DestroyRAM(); - - //output to msRawData - int i, j, label; - for(i = 0; i < L; i++) - { - label = labels[i]; - for(j = 0; j < N; j++) - { - msRawData[N*i+j] = modes[N*label+j]; - } - } - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Image Segmentation */ - /*\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Segment */ -/*******************************************************/ -/*Segments the defined image. */ -/*******************************************************/ -/*Pre: */ -/* - sigmaS and sigmaR are the spatial and range */ -/* radii of the search window respectively */ -/* - minRegion is the minimum point density that */ -/* a region may have in the resulting segment- */ -/* ed image */ -/* - speedUpLevel determines whether or not the */ -/* filtering should be optimized for faster */ -/* execution: a value of NO_SPEEDUP turns this */ -/* optimization off and a value SPEEDUP turns */ -/* this optimization on */ -/*Post: */ -/* - the defined image is segmented and the */ -/* resulting segmented image is stored in the */ -/* private data members of the image segmenter */ -/* class. */ -/* - any regions whose point densities are less */ -/* than or equal to minRegion have been pruned */ -/* from the segmented image. */ -/*******************************************************/ - -void msImageProcessor::Segment(int sigmaS, float sigmaR, int minRegion, SpeedUpLevel speedUpLevel) -{ - - //make sure kernel is properly defined... - if((!h)||(kp < 2)) - { - ErrorHandler("msImageProcessor", "Segment", "Kernel corrupt or undefined."); - return; - } - - //Apply mean shift to data set using sigmaS and sigmaR... - Filter(sigmaS, sigmaR, speedUpLevel); - - //check for errors - if(ErrorStatus == EL_ERROR) - return; - - //check to see if the system has been halted, if so exit - if(ErrorStatus == EL_HALT) - return; - - //Check to see if the algorithm is to be halted, if so then - //destroy output and exit - if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT) - { - DestroyOutput(); - return; - } - -#ifdef PROMPT - msSys.Prompt("Applying transitive closure..."); - msSys.StartTimer(); -#endif - - //allocate memory visit table - visitTable = new unsigned char [L]; - - //Apply transitive closure iteratively to the regions classified - //by the RAM updating labels and modes until the color of each neighboring - //region is within sqrt(rR2) of one another. - rR2 = (float)(h[1]*h[1]*0.25); - TransitiveClosure(); - int oldRC = regionCount; - int deltaRC, counter = 0; - do { - TransitiveClosure(); - deltaRC = oldRC-regionCount; - oldRC = regionCount; - counter++; - } while ((deltaRC <= 0)&&(counter < 10)); - - //de-allocate memory for visit table - delete [] visitTable; - visitTable = NULL; - - //Check to see if the algorithm is to be halted, if so then - //destroy output and regions adjacency matrix and exit - if((ErrorStatus = msSys.Progress((float)(0.95))) == EL_HALT) - { - DestroyRAM(); - DestroyOutput(); - return; - } - -#ifdef PROMPT - double timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d).\nPruning spurious regions\t... ", timer, regionCount); - msSys.StartTimer(); -#endif - - //Prune spurious regions (regions whose area is under - //minRegion) using RAM - Prune(minRegion); - -#ifdef PROMPT - timer = msSys.ElapsedTime(); - msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions ...", timer, regionCount); - msSys.StartTimer(); -#endif - - //Check to see if the algorithm is to be halted, if so then - //destroy output and regions adjacency matrix and exit - if((ErrorStatus = msSys.Progress(1.0)) == EL_HALT) - { - DestroyRAM(); - DestroyOutput(); - return; - } - - //de-allocate memory for region adjacency matrix - DestroyRAM(); - - //output to msRawData - int j, i, label; - for(i = 0; i < L; i++) - { - label = labels[i]; - for(j = 0; j < N; j++) - { - msRawData[N*i+j] = modes[N*label+j]; - } - } - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Data Space Conversion */ - /*\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*RGB To LUV */ -/*******************************************************/ -/*Converts an RGB vector to LUV. */ -/* */ -/*See: */ -/* G. Wyszecki and W.S. Stiles: Color Science: */ -/* Concepts and Methods, Quantitative Data and */ -/* Formulae, Wiley, New York, 1982. */ -/*******************************************************/ -/*Pre: */ -/* - rgbVal is an unsigned char array containing */ -/* the RGB vector */ -/* - luvVal is a floating point array containing */ -/* the resulting LUV vector */ -/*Post: */ -/* - rgbVal has been converted to LUV and the */ -/* result has been stored in luvVal. */ -/*******************************************************/ - -void msImageProcessor::RGBtoLUV(byte *rgbVal, float *luvVal) -{ - - //delcare variables - double x, y, z, L0, u_prime, v_prime, constant; - - //convert RGB to XYZ... - x = XYZ[0][0]*rgbVal[0] + XYZ[0][1]*rgbVal[1] + XYZ[0][2]*rgbVal[2]; - y = XYZ[1][0]*rgbVal[0] + XYZ[1][1]*rgbVal[1] + XYZ[1][2]*rgbVal[2]; - z = XYZ[2][0]*rgbVal[0] + XYZ[2][1]*rgbVal[1] + XYZ[2][2]*rgbVal[2]; - - //convert XYZ to LUV... - - //compute L* - L0 = y / (255.0 * Yn); - if(L0 > Lt) - luvVal[0] = (float)(116.0 * (pow(L0, 1.0/3.0)) - 16.0); - else - luvVal[0] = (float)(903.3 * L0); - - //compute u_prime and v_prime - constant = x + 15 * y + 3 * z; - if(constant != 0) - { - u_prime = (4 * x) / constant; - v_prime = (9 * y) / constant; - } - else - { - u_prime = 4.0; - v_prime = 9.0/15.0; - } - - //compute u* and v* - luvVal[1] = (float) (13 * luvVal[0] * (u_prime - Un_prime)); - luvVal[2] = (float) (13 * luvVal[0] * (v_prime - Vn_prime)); - - //done. - return; - -} - -/*******************************************************/ -/*LUV To RGB */ -/*******************************************************/ -/*Converts an LUV vector to RGB. */ -/*******************************************************/ -/*Pre: */ -/* - luvVal is a floating point array containing */ -/* the LUV vector */ -/* - rgbVal is an unsigned char array containing */ -/* the resulting RGB vector */ -/*Post: */ -/* - luvVal has been converted to RGB and the */ -/* result has been stored in rgbVal. */ -/*******************************************************/ - -//define inline rounding function... -inline int my_round(double in_x) -{ - if (in_x < 0) - return (int)(in_x - 0.5); - else - return (int)(in_x + 0.5); -} - -void msImageProcessor::LUVtoRGB(float *luvVal, byte *rgbVal) -{ - - //declare variables... - int r, g, b; - double x, y, z, u_prime, v_prime; - - //perform conversion - if(luvVal[0] < 0.1) - r = g = b = 0; - else - { - //convert luv to xyz... - if(luvVal[0] < 8.0) - y = Yn * luvVal[0] / 903.3; - else - { - y = (luvVal[0] + 16.0) / 116.0; - y *= Yn * y * y; - } - - u_prime = luvVal[1] / (13 * luvVal[0]) + Un_prime; - v_prime = luvVal[2] / (13 * luvVal[0]) + Vn_prime; - - x = 9 * u_prime * y / (4 * v_prime); - z = (12 - 3 * u_prime - 20 * v_prime) * y / (4 * v_prime); - - //convert xyz to rgb... - //[r, g, b] = RGB*[x, y, z]*255.0 - r = my_round((RGB[0][0]*x + RGB[0][1]*y + RGB[0][2]*z)*255.0); - g = my_round((RGB[1][0]*x + RGB[1][1]*y + RGB[1][2]*z)*255.0); - b = my_round((RGB[2][0]*x + RGB[2][1]*y + RGB[2][2]*z)*255.0); - - //check bounds... - if(r < 0) r = 0; if(r > 255) r = 255; - if(g < 0) g = 0; if(g > 255) g = 255; - if(b < 0) b = 0; if(b > 255) b = 255; - - } - - //assign rgb values to rgb vector rgbVal - rgbVal[0] = r; - rgbVal[1] = g; - rgbVal[2] = b; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Filtered and Segmented Image Output */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Get Raw Data */ -/*******************************************************/ -/*The output image data is returned. */ -/*******************************************************/ -/*Pre: */ -/* - outputImageData is a pre-allocated floating */ -/* point array used to store the filtered or */ -/* segmented image pixels. */ -/*Post: */ -/* - the filtered or segmented image data is */ -/* stored by outputImageData. */ -/*******************************************************/ - -void msImageProcessor::GetRawData(float *outputImageData) -{ - //make sure that outputImageData is not NULL - if(!outputImageData) - { - ErrorHandler("msImageProcessor", "GetRawData", "Output image data buffer is NULL."); - return; - } - - //copy msRawData to outputImageData - int i; - for(i = 0; i < L*N; i++) - outputImageData[i] = msRawData[i]; - - //done. - return; -} - -/*******************************************************/ -/*Get Results */ -/*******************************************************/ -/*The output image is returned. */ -/*******************************************************/ -/*Pre: */ -/* - outputImage is a pre-allocated unsinged char */ -/* array used to store the filtered or segment- */ -/* ed image pixels */ -/*Post: */ -/* - the filtered or segmented image is stored by */ -/* outputImage. */ -/*******************************************************/ - -void msImageProcessor::GetResults(byte *outputImage) -{ - - //make sure that outpuImage is not NULL - if(!outputImage) - { - ErrorHandler("msImageProcessor", "GetResults", "Output image buffer is NULL."); - return; - } - - //if the image type is GREYSCALE simply - //copy it over to the segmentedImage - if(N == 1) - { - //copy over msRawData to segmentedImage checking - //bounds - int i, pxValue; - for(i = 0; i < L; i++) - { - - //get value - pxValue = (int)(msRawData[i]+0.5); - - //store into segmented image checking bounds... - if(pxValue < 0) - outputImage[i] = (byte)(0); - else if(pxValue > 255) - outputImage[i] = (byte)(255); - else - outputImage[i] = (byte)(pxValue); - - } - - } - else if (N == 3) - { - - //otherwise convert msRawData from LUV to RGB - //storing the result in segmentedImage - int i; - for(i = 0; i < L; i++) - LUVtoRGB(&msRawData[N*i], &outputImage[N*i]); - - } - else - //Unknown image type: should use MeanShift::GetRawData()... - ErrorHandler("msImageProcessor", "GetResults", "Unknown image type. Try using MeanShift::GetRawData()."); - - //done. - return; - -} - -/*******************************************************/ -/*Get Boundaries */ -/*******************************************************/ -/*A region list containing the boundary locations for */ -/*each region is returned. */ -/*******************************************************/ -/*Post: */ -/* - a region list object containing the boundary */ -/* locations for each region is constructed */ -/* - the region list is returned */ -/* - NULL is returned if the image has not been */ -/* filtered or segmented */ -/*******************************************************/ - -RegionList *msImageProcessor::GetBoundaries( void ) -{ - - //define bounds using label information - if(class_state.OUTPUT_DEFINED) - DefineBoundaries(); - - //return region list structure - return regionList; - -} - -/*******************************************************/ -/*Get Regions */ -/*******************************************************/ -/*Returns the regions of the processed image. */ -/*******************************************************/ -/*Pre: */ -/* - labels_out is an integer array of size */ -/* height*width that stores for each pixel a */ -/* label relating that pixel to a corresponding */ -/* region in the image */ -/* - modes_out is floating point array of size */ -/* regionCount*N storing the feature component */ -/* of each region, and indexed by region label */ -/* - modePointCounts is an integer array of size */ -/* regionCount, indexed by region label, that */ -/* stores the area of each region in pixels. */ -/*Post: */ -/* If an input image was defined and processed, */ -/* - memory has been allocated for labels_out, */ -/* modes_out and MPC_out. */ -/* - labels_out, modes_out, and MPC_out have been */ -/* populated. */ -/* - the number of regions contained by the segm- */ -/* ented image has been returned. */ -/* If the image has not been defined or processed */ -/* or if there is in-sufficient memory, */ -/* - no memory has been allocated for labels_out, */ -/* modes_out, and MPC_out. */ -/* - -1 is returned for regionCount. */ -/*******************************************************/ - -int msImageProcessor::GetRegions(int **labels_out, float **modes_out, int **MPC_out) -{ - //check to see if output has been defined for the given input image... - if(class_state.OUTPUT_DEFINED == false) - return -1; - - //allocate memory for labels_out, modes_out and MPC_out based - //on output storage structure - if(!(*labels_out = new int [L])) - { - ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory."); - return -1; - } - if(!(*modes_out = new float [regionCount*N])) - { - ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory."); - return -1; - } - if(!(*MPC_out = new int [regionCount])) - { - ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory."); - return -1; - } - - - int *labels_ = *labels_out, *MPC_out_ = *MPC_out; - float *modes_ = *modes_out; - - - - //populate labels_out with image labels - int i; - for(i = 0; i < L; i++) - labels_[i] = labels[i]; - - //populate modes_out and MPC_out with the color and point - //count of each region - for(i = 0; i < regionCount*N; i++) - modes_[i] = modes[i]; - for(i = 0; i < regionCount; i++) - MPC_out_[i] = modePointCounts[i]; - - //done. Return the number of regions resulting from filtering or segmentation. - return regionCount; -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PRIVATE METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\*/ - /* Image Filtering */ - /*\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Non Optimized Filter */ -/*******************************************************/ -/*Performs mean shift filtering on the specified input */ -/*image using a user defined kernel. */ -/*******************************************************/ -/*Pre: */ -/* - the user defined kernel used to apply mean */ -/* shift filtering to the defined input image */ -/* has spatial bandwidth sigmaS and range band- */ -/* width sigmaR */ -/* - a data set has been defined */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/*Post: */ -/* - mean shift filtering has been applied to the */ -/* input image using a user defined kernel */ -/* - the filtered image is stored in the private */ -/* data members of the msImageProcessor class. */ -/*******************************************************/ - -void msImageProcessor::NonOptimizedFilter(float sigmaS, float sigmaR) -{ - - // Declare Variables - int iterationCount, i, j; - double mvAbs; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice)... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - for(i = 0; i < L; i++) - { - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - yk[0] = i%width; - yk[1] = i/width; - for(j = 0; j < N; j++) - yk[j+2] = data[N*i+j]; - - // Calculate the mean shift vector using the lattice - LatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // Calculate the mean shift vector at the new - // window location using lattice - LatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Increment interation count - iterationCount++; - - } - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - - // de-allocate memory - delete [] yk; - delete [] Mh; - - // done. - return; - -} - - - -/*******************************************************/ -/*Optimized Filter 1 */ -/*******************************************************/ -/*Performs mean shift filtering on the specified input */ -/*image using a user defined kernel. Previous mode */ -/*information is used to avoid re-applying mean shift */ -/*on certain data points to improve performance. */ -/*******************************************************/ -/*Pre: */ -/* - the user defined kernel used to apply mean */ -/* shift filtering to the defined input image */ -/* has spatial bandwidth sigmaS and range band- */ -/* width sigmaR */ -/* - a data set has been defined */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/*Post: */ -/* - mean shift filtering has been applied to the */ -/* input image using a user defined kernel */ -/* - the filtered image is stored in the private */ -/* data members of the msImageProcessor class. */ -/*******************************************************/ - -void msImageProcessor::OptimizedFilter1(float sigmaS, float sigmaR) -{ - - // Declare Variables - int iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i; - float *modeCandidatePoint; - double mvAbs, diff, el; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // Initialize mode table used for basin of attraction - memset(modeTable, 0, width*height); - - // Allocate memory mode candidate data point... - //floating point version - modeCandidatePoint = new float [N]; - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - - for(i = 0; i < L; i++) - { - // if a mode was already assigned to this data point - // then skip this point, otherwise proceed to - // find its mode by applying mean shift... - if (modeTable[i] == 1) - continue; - - // initialize point list... - pointCount = 0; - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - yk[0] = i%width; - yk[1] = i/width; - for(j = 0; j < N; j++) - yk[j+2] = data[N*i+j]; - - // Calculate the mean shift vector using the lattice - LatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // check to see if the current mode location is in the - // basin of attraction... - - // calculate the location of yk on the lattice - modeCandidateX = (int) (yk[0]+0.5); - modeCandidateY = (int) (yk[1]+0.5); - modeCandidate_i = modeCandidateY*width + modeCandidateX; - - // if mvAbs != 0 (yk did indeed move) then check - // location basin_i in the mode table to see if - // this data point either: - - // (1) has not been associated with a mode yet - // (modeTable[basin_i] = 0), so associate - // it with this one - // - // (2) it has been associated with a mode other - // than the one that this data point is converging - // to (modeTable[basin_i] = 1), so assign to - // this data point the same mode as that of basin_i - - if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i)) - { - // obtain the data point at basin_i to - // see if it is within h*TC_DIST_FACTOR of - // of yk - for (j = 0; j < N; j++) - modeCandidatePoint[j] = data[N*modeCandidate_i + j]; - - // check basin on non-spatial data spaces only - k = 1; - s = 0; - diff = 0; - while ((diff < TC_DIST_FACTOR) && (k<kp)) - { - diff = 0; - for (p=0; p<P[k]; p++) - { - el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k]; - diff += el*el; - } - s+=P[k]; - k++; - } - - // if the data point at basin_i is within - // a distance of h*TC_DIST_FACTOR of yk - // then depending on modeTable[basin_i] perform - // either (1) or (2) - if (diff < TC_DIST_FACTOR) - { - // if the data point at basin_i has not - // been associated to a mode then associate - // it with the mode that this one will converge - // to - if (modeTable[modeCandidate_i] == 0) - { - // no mode associated yet so associate - // it with this one... - pointList[pointCount++] = modeCandidate_i; - modeTable[modeCandidate_i] = 2; - - } else - { - - // the mode has already been associated with - // another mode, thererfore associate this one - // mode and the modes in the point list with - // the mode associated with data[basin_i]... - - // store the mode info into yk using msRawData... - for (j = 0; j < N; j++) - yk[j+2] = msRawData[modeCandidate_i*N+j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - // indicate that a mode has been associated - // to this data point (data[i]) - mvAbs = -1; - - // stop mean shift calculation... - break; - } - } - } - - // Calculate the mean shift vector at the new - // window location using lattice - LatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Increment iteration count - iterationCount++; - - } - - // if a mode was not associated with this data point - // yet associate it with yk... - if (mvAbs >= 0) - { - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - } - - // associate the data point indexed by - // the point list with the mode stored - // by yk - for (j = 0; j < pointCount; j++) - { - // obtain the point location from the - // point list - modeCandidate_i = pointList[j]; - - // update the mode table for this point - modeTable[modeCandidate_i] = 1; - - //store result into msRawData... - for(k = 0; k < N; k++) - msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]); - } - - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - - // de-allocate memory - delete [] modeCandidatePoint; - delete [] yk; - delete [] Mh; - - // done. - return; - -} - -/*******************************************************/ -/*Optimized Filter 2 */ -/*******************************************************/ -/*Performs mean shift filtering on the specified input */ -/*image using a user defined kernel. Previous mode */ -/*information is used to avoid re-applying mean shift */ -/*on certain data points to improve performance. To */ -/*further improve perfmance (during segmentation) poi- */ -/*nts within h of a window center during the window */ -/*center's traversal to a mode are associated with the */ -/*mode that the window converges to. */ -/*******************************************************/ -/*Pre: */ -/* - the user defined kernel used to apply mean */ -/* shift filtering to the defined input image */ -/* has spatial bandwidth sigmaS and range band- */ -/* width sigmaR */ -/* - a data set has been defined */ -/* - the height and width of the lattice has been */ -/* specified using method DefineLattice() */ -/*Post: */ -/* - mean shift filtering has been applied to the */ -/* input image using a user defined kernel */ -/* - the filtered image is stored in the private */ -/* data members of the msImageProcessor class. */ -/*******************************************************/ - -void msImageProcessor::OptimizedFilter2(float sigmaS, float sigmaR) -{ - - //if confidence map is null set it to zero - if(!weightMap) - { - weightMap = new float [L]; - int i; - for(i = 0; i < L; i++) - weightMap[i] = 0; - } - - // Declare Variables - int iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i; - float *modeCandidatePoint; - double mvAbs, diff, el; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // Initialize mode table used for basin of attraction - memset(modeTable, 0, width*height); - - // Allocate memory mode candidate data point... - //floating point version - modeCandidatePoint = new float [N]; - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice)... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - for(i = 0; i < L; i++) - { - // if a mode was already assigned to this data point - // then skip this point, otherwise proceed to - // find its mode by applying mean shift... - if (modeTable[i] == 1) - continue; - - // initialize point list... - pointCount = 0; - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - yk[0] = i%width; - yk[1] = i/width; - for(j = 0; j < N; j++) - yk[j+2] = data[N*i+j]; - - // Calculate the mean shift vector using the lattice - OptLatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // check to see if the current mode location is in the - // basin of attraction... - - // calculate the location of yk on the lattice - modeCandidateX = (int) (yk[0]+0.5); - modeCandidateY = (int) (yk[1]+0.5); - modeCandidate_i = modeCandidateY*width + modeCandidateX; - - // if mvAbs != 0 (yk did indeed move) then check - // location basin_i in the mode table to see if - // this data point either: - - // (1) has not been associated with a mode yet - // (modeTable[basin_i] = 0), so associate - // it with this one - // - // (2) it has been associated with a mode other - // than the one that this data point is converging - // to (modeTable[basin_i] = 1), so assign to - // this data point the same mode as that of basin_i - - if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i)) - { - // obtain the data point at basin_i to - // see if it is within h*TC_DIST_FACTOR of - // of yk - for (j = 0; j < N; j++) - modeCandidatePoint[j] = data[N*modeCandidate_i + j]; - - // check basin on non-spatial data spaces only - k = 1; - s = 0; - diff = 0; - while ((diff < TC_DIST_FACTOR) && (k<kp)) - { - diff = 0; - for (p=0; p<P[k]; p++) - { - el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k]; - diff += el*el; - } - s+=P[k]; - k++; - } - - // if the data point at basin_i is within - // a distance of h*TC_DIST_FACTOR of yk - // then depending on modeTable[basin_i] perform - // either (1) or (2) - if (diff < TC_DIST_FACTOR) - { - // if the data point at basin_i has not - // been associated to a mode then associate - // it with the mode that this one will converge - // to - if (modeTable[modeCandidate_i] == 0) - { - // no mode associated yet so associate - // it with this one... - pointList[pointCount++] = modeCandidate_i; - modeTable[modeCandidate_i] = 2; - - } else - { - - // the mode has already been associated with - // another mode, thererfore associate this one - // mode and the modes in the point list with - // the mode associated with data[basin_i]... - - // store the mode infor int yk using msRawData... - for (j = 0; j < N; j++) - yk[j+2] = msRawData[modeCandidate_i*N+j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - // indicate that a mode has been associated - // to this data point (data[i]) - mvAbs = -1; - - // stop mean shift calculation... - break; - } - } - } - - // Calculate the mean shift vector at the new - // window location using lattice - OptLatticeMSVector(Mh, yk); - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Increment interation count - iterationCount++; - - } - - // if a mode was not associated with this data point - // yet then perform a shift the window center yk one - // last time using the mean shift vector... - if (mvAbs >= 0) - { - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - } - - // associate the data point indexed by - // the point list with the mode stored - // by yk - for (j = 0; j < pointCount; j++) - { - // obtain the point location from the - // point list - modeCandidate_i = pointList[j]; - - // update the mode table for this point - modeTable[modeCandidate_i] = 1; - - //store result into msRawData... - for(k = 0; k < N; k++) - msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]); - } - - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - - // de-allocate memory - delete [] modeCandidatePoint; - delete [] yk; - delete [] Mh; - - // done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Classification */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Connect */ -/*******************************************************/ -/*Classifies the regions of the mean shift filtered */ -/*image. */ -/*******************************************************/ -/*Post: */ -/* - the regions of the mean shift image have been*/ -/* classified using the private classification */ -/* structure of the msImageProcessor Class. */ -/* Namely, each region uniquely identified by */ -/* its LUV color (stored by LUV_data) and loc- */ -/* ation has been labeled and its area computed */ -/* via an eight-connected fill. */ -/*******************************************************/ - -void msImageProcessor::Connect( void ) -{ - - //define eight connected neighbors - neigh[0] = 1; - neigh[1] = 1-width; - neigh[2] = -width; - neigh[3] = -(1+width); - neigh[4] = -1; - neigh[5] = width-1; - neigh[6] = width; - neigh[7] = width+1; - - //initialize labels and modePointCounts - int i; - for(i = 0; i < width*height; i++) - { - labels[i] = -1; - modePointCounts[i] = 0; - } - - //Traverse the image labeling each new region encountered - int k, label = -1; - for(i = 0; i < height*width; i++) - { - //if this region has not yet been labeled - label it - if(labels[i] < 0) - { - //assign new label to this region - labels[i] = ++label; - - //copy region color into modes - for(k = 0; k < N; k++) - modes[(N*label)+k] = LUV_data[(N*i)+k]; -// modes[(N*label)+k] = (float)(LUV_data[(N*i)+k]); - - //populate labels with label for this specified region - //calculating modePointCounts[label]... - Fill(i, label); - } - } - - //calculate region count using label - regionCount = label+1; - - //done. - return; -} - -/*******************************************************/ -/*Fill */ -/*******************************************************/ -/*Given a region seed and a region label, Fill uses */ -/*the region seed to perform an eight-connected fill */ -/*for the specified region, labeling all pixels con- */ -/*tained by the region with the specified label: */ -/*label. */ -/*******************************************************/ -/*Pre: */ -/* - regionLoc is a region seed - a pixel that is */ -/* identified as being part of the region */ -/* labled using the label, label. */ -/*Post: */ -/* - all pixels belonging to the region specified */ -/* by regionLoc (having the same integer LUV */ -/* value specified by LUV_data) are classified */ -/* as one region by labeling each pixel in the */ -/* image clasification structure using label */ -/* via an eight-connected fill. */ -/*******************************************************/ - -void msImageProcessor::Fill(int regionLoc, int label) -{ - - //declare variables - int i, k, neighLoc, neighborsFound, imageSize = width*height; - - //Fill region starting at region location - //using labels... - - //initialzie indexTable - int index = 0; - indexTable[0] = regionLoc; - - //increment mode point counts for this region to - //indicate that one pixel belongs to this region - modePointCounts[label]++; - - while(true) - { - - //assume no neighbors will be found - neighborsFound = 0; - - //check the eight connected neighbors at regionLoc - - //if a pixel has similar color to that located at - //regionLoc then declare it as part of this region - for(i = 0; i < 8; i++) - { - // no need - /* - //if at boundary do not check certain neighbors because - //they do not exist... - if((regionLoc%width == 0)&&((i == 3)||(i == 4)||(i == 5))) - continue; - if((regionLoc%(width-1) == 0)&&((i == 0)||(i == 1)||(i == 7))) - continue; - */ - - //check bounds and if neighbor has been already labeled - neighLoc = regionLoc + neigh[i]; - if((neighLoc >= 0)&&(neighLoc < imageSize)&&(labels[neighLoc] < 0)) - { - for(k = 0; k < N; k++) - { -// if(LUV_data[(regionLoc*N)+k] != LUV_data[(neighLoc*N)+k]) - if (fabs(LUV_data[(regionLoc*N)+k]-LUV_data[(neighLoc*N)+k])>=LUV_treshold) - break; - } - - //neighbor i belongs to this region so label it and - //place it onto the index table buffer for further - //processing - if(k == N) - { - //assign label to neighbor i - labels[neighLoc] = label; - - //increment region point count - modePointCounts[label]++; - - //place index of neighbor i onto the index tabel buffer - indexTable[++index] = neighLoc; - - //indicate that a neighboring region pixel was - //identified - neighborsFound = 1; - } - } - } - - //check the indexTable to see if there are any more - //entries to be explored - if so explore them, otherwise - //exit the loop - we are finished - if(neighborsFound) - regionLoc = indexTable[index]; - else if (index > 1) - regionLoc = indexTable[--index]; - else - break; //fill complete - } - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\*/ - /* Image Pruning */ - /*\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Build Region Adjacency Matrix */ -/*******************************************************/ -/*Constructs a region adjacency matrix. */ -/*******************************************************/ -/*Pre: */ -/* - the classification data structure has been */ -/* constructed. */ -/*Post: */ -/* - a region adjacency matrix has been built */ -/* using the classification data structure. */ -/*******************************************************/ - -void msImageProcessor::BuildRAM( void ) -{ - - //Allocate memory for region adjacency matrix if it hasn't already been allocated - if((!raList)&&((!(raList = new RAList [regionCount]))||(!(raPool = new RAList [NODE_MULTIPLE*regionCount])))) - { - ErrorHandler("msImageProcessor", "Allocate", "Not enough memory."); - return; - } - - //initialize the region adjacency list - int i; - for(i = 0; i < regionCount; i++) - { - raList[i].edgeStrength = 0; - raList[i].edgePixelCount = 0; - raList[i].label = i; - raList[i].next = NULL; - } - - //initialize RAM free list - freeRAList = raPool; - for(i = 0; i < NODE_MULTIPLE*regionCount-1; i++) - { - raPool[i].edgeStrength = 0; - raPool[i].edgePixelCount = 0; - raPool[i].next = &raPool[i+1]; - } - raPool[NODE_MULTIPLE*regionCount-1].next = NULL; - - //traverse the labeled image building - //the RAM by looking to the right of - //and below the current pixel location thus - //determining if a given region is adjacent - //to another - int j, curLabel, rightLabel, bottomLabel, exists; - RAList *raNode1, *raNode2, *oldRAFreeList; - for(i = 0; i < height - 1; i++) - { - //check the right and below neighbors - //for pixel locations whose x < width - 1 - for(j = 0; j < width - 1; j++) - { - //calculate pixel labels - curLabel = labels[i*width+j ]; //current pixel - rightLabel = labels[i*width+j+1 ]; //right pixel - bottomLabel = labels[(i+1)*width+j]; //bottom pixel - - //check to the right, if the label of - //the right pixel is not the same as that - //of the current one then region[j] and region[j+1] - //are adjacent to one another - update the RAM - if(curLabel != rightLabel) - { - //obtain RAList object from region adjacency free - //list - raNode1 = freeRAList; - raNode2 = freeRAList->next; - - //keep a pointer to the old region adj. free - //list just in case nodes already exist in respective - //region lists - oldRAFreeList = freeRAList; - - //update region adjacency free list - freeRAList = freeRAList->next->next; - - //populate RAList nodes - raNode1->label = curLabel; - raNode2->label = rightLabel; - - //insert nodes into the RAM - exists = 0; - raList[curLabel ].Insert(raNode2); - exists = raList[rightLabel].Insert(raNode1); - - //if the node already exists then place - //nodes back onto the region adjacency - //free list - if(exists) - freeRAList = oldRAFreeList; - - } - - //check below, if the label of - //the bottom pixel is not the same as that - //of the current one then region[j] and region[j+width] - //are adjacent to one another - update the RAM - if(curLabel != bottomLabel) - { - //obtain RAList object from region adjacency free - //list - raNode1 = freeRAList; - raNode2 = freeRAList->next; - - //keep a pointer to the old region adj. free - //list just in case nodes already exist in respective - //region lists - oldRAFreeList = freeRAList; - - //update region adjacency free list - freeRAList = freeRAList->next->next; - - //populate RAList nodes - raNode1->label = curLabel; - raNode2->label = bottomLabel; - - //insert nodes into the RAM - exists = 0; - raList[curLabel ].Insert(raNode2); - exists = raList[bottomLabel].Insert(raNode1); - - //if the node already exists then place - //nodes back onto the region adjacency - //free list - if(exists) - freeRAList = oldRAFreeList; - - } - - } - - //check only to the bottom neighbors of the right boundary - //pixels... - - //calculate pixel locations (j = width-1) - curLabel = labels[i*width+j ]; //current pixel - bottomLabel = labels[(i+1)*width+j]; //bottom pixel - - //check below, if the label of - //the bottom pixel is not the same as that - //of the current one then region[j] and region[j+width] - //are adjacent to one another - update the RAM - if(curLabel != bottomLabel) - { - //obtain RAList object from region adjacency free - //list - raNode1 = freeRAList; - raNode2 = freeRAList->next; - - //keep a pointer to the old region adj. free - //list just in case nodes already exist in respective - //region lists - oldRAFreeList = freeRAList; - - //update region adjacency free list - freeRAList = freeRAList->next->next; - - //populate RAList nodes - raNode1->label = curLabel; - raNode2->label = bottomLabel; - - //insert nodes into the RAM - exists = 0; - raList[curLabel ].Insert(raNode2); - exists = raList[bottomLabel].Insert(raNode1); - - //if the node already exists then place - //nodes back onto the region adjacency - //free list - if(exists) - freeRAList = oldRAFreeList; - - } - } - - //check only to the right neighbors of the bottom boundary - //pixels... - - //check the right for pixel locations whose x < width - 1 - for(j = 0; j < width - 1; j++) - { - //calculate pixel labels (i = height-1) - curLabel = labels[i*width+j ]; //current pixel - rightLabel = labels[i*width+j+1 ]; //right pixel - - //check to the right, if the label of - //the right pixel is not the same as that - //of the current one then region[j] and region[j+1] - //are adjacent to one another - update the RAM - if(curLabel != rightLabel) - { - //obtain RAList object from region adjacency free - //list - raNode1 = freeRAList; - raNode2 = freeRAList->next; - - //keep a pointer to the old region adj. free - //list just in case nodes already exist in respective - //region lists - oldRAFreeList = freeRAList; - - //update region adjacency free list - freeRAList = freeRAList->next->next; - - //populate RAList nodes - raNode1->label = curLabel; - raNode2->label = rightLabel; - - //insert nodes into the RAM - exists = 0; - raList[curLabel ].Insert(raNode2); - exists = raList[rightLabel].Insert(raNode1); - - //if the node already exists then place - //nodes back onto the region adjacency - //free list - if(exists) - freeRAList = oldRAFreeList; - - } - - } - - //done. - return; - -} - -/*******************************************************/ -/*Destroy Region Adjacency Matrix */ -/*******************************************************/ -/*Destroy a region adjacency matrix. */ -/*******************************************************/ -/*Post: */ -/* - the region adjacency matrix has been destr- */ -/* oyed: (1) its memory has been de-allocated, */ -/* (2) the RAM structure has been initialize */ -/* for re-use. */ -/*******************************************************/ - -void msImageProcessor::DestroyRAM( void ) -{ - - //de-allocate memory for region adjaceny list - if (raList) delete [] raList; - if (raPool) delete [] raPool; - - //initialize region adjacency matrix - raList = NULL; - freeRAList = NULL; - raPool = NULL; - - //done. - return; - -} - -/*******************************************************/ -/*Transitive Closure */ -/*******************************************************/ -/*Applies transitive closure to the RAM updating */ -/*labels, modes and modePointCounts to reflect the new */ -/*set of merged regions resulting from transitive clo- */ -/*sure. */ -/*******************************************************/ -/*Post: */ -/* - transitive closure has been applied to the */ -/* regions classified by the RAM and labels, */ -/* modes and modePointCounts have been updated */ -/* to reflect the new set of mergd regions res- */ -/* ulting from transitive closure. */ -/*******************************************************/ - -void msImageProcessor::TransitiveClosure( void ) -{ - - //Step (1): - - // Build RAM using classifiction structure originally - // generated by the method GridTable::Connect() - BuildRAM(); - - //Step (1a): - //Compute weights of weight graph using confidence map - //(if defined) - if(weightMapDefined) ComputeEdgeStrengths(); - - //Step (2): - - //Treat each region Ri as a disjoint set: - - // - attempt to join Ri and Rj for all i != j that are neighbors and - // whose associated modes are a normalized distance of < 0.5 from one - // another - - // - the label of each region in the raList is treated as a pointer to the - // canonical element of that region (e.g. raList[i], initially has raList[i].label = i, - // namely each region is initialized to have itself as its canonical element). - - //Traverse RAM attempting to join raList[i] with its neighbors... - int i, iCanEl, neighCanEl; - float threshold; - RAList *neighbor; - for(i = 0; i < regionCount; i++) - { - //aquire first neighbor in region adjacency list pointed to - //by raList[i] - neighbor = raList[i].next; - - //compute edge strenght threshold using global and local - //epsilon - if(epsilon > raList[i].edgeStrength) - threshold = epsilon; - else - threshold = raList[i].edgeStrength; - - //traverse region adjacency list of region i, attempting to join - //it with regions whose mode is a normalized distance < 0.5 from - //that of region i... - while(neighbor) - { - //attempt to join region and neighbor... - if((InWindow(i, neighbor->label))&&(neighbor->edgeStrength < epsilon)) - { - //region i and neighbor belong together so join them - //by: - - // (1) find the canonical element of region i - iCanEl = i; - while(raList[iCanEl].label != iCanEl) - iCanEl = raList[iCanEl].label; - - // (2) find the canonical element of neighboring region - neighCanEl = neighbor->label; - while(raList[neighCanEl].label != neighCanEl) - neighCanEl = raList[neighCanEl].label; - - // if the canonical elements of are not the same then assign - // the canonical element having the smaller label to be the parent - // of the other region... - if(iCanEl < neighCanEl) - raList[neighCanEl].label = iCanEl; - else - { - //must replace the canonical element of previous - //parent as well - raList[raList[iCanEl].label].label = neighCanEl; - - //re-assign canonical element - raList[iCanEl].label = neighCanEl; - } - } - - //check the next neighbor... - neighbor = neighbor->next; - - } - } - - // Step (3): - - // Level binary trees formed by canonical elements - for(i = 0; i < regionCount; i++) - { - iCanEl = i; - while(raList[iCanEl].label != iCanEl) - iCanEl = raList[iCanEl].label; - raList[i].label = iCanEl; - } - - // Step (4): - - //Traverse joint sets, relabeling image. - - // (a) - - // Accumulate modes and re-compute point counts using canonical - // elements generated by step 2. - - //allocate memory for mode and point count temporary buffers... - float *modes_buffer = new float [N*regionCount]; - int *MPC_buffer = new int [regionCount]; - - //initialize buffers to zero - for(i = 0; i < regionCount; i++) - MPC_buffer[i] = 0; - for(i = 0; i < N*regionCount; i++) - modes_buffer[i] = 0; - - //traverse raList accumulating modes and point counts - //using canoncial element information... - int k, iMPC; - for(i = 0; i < regionCount; i++) - { - - //obtain canonical element of region i - iCanEl = raList[i].label; - - //obtain mode point count of region i - iMPC = modePointCounts[i]; - - //accumulate modes_buffer[iCanEl] - for(k = 0; k < N; k++) - modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k]; - - //accumulate MPC_buffer[iCanEl] - MPC_buffer[iCanEl] += iMPC; - - } - - // (b) - - // Re-label new regions of the image using the canonical - // element information generated by step (2) - - // Also use this information to compute the modes of the newly - // defined regions, and to assign new region point counts in - // a consecute manner to the modePointCounts array - - //allocate memory for label buffer - int *label_buffer = new int [regionCount]; - - //initialize label buffer to -1 - for(i = 0; i < regionCount; i++) - label_buffer[i] = -1; - - //traverse raList re-labeling the regions - int label = -1; - for(i = 0; i < regionCount; i++) - { - //obtain canonical element of region i - iCanEl = raList[i].label; - if(label_buffer[iCanEl] < 0) - { - //assign a label to the new region indicated by canonical - //element of i - label_buffer[iCanEl] = ++label; - - //recompute mode storing the result in modes[label]... - iMPC = MPC_buffer[iCanEl]; - for(k = 0; k < N; k++) - modes[(N*label)+k] = (modes_buffer[(N*iCanEl)+k])/(iMPC); - - //assign a corresponding mode point count for this region into - //the mode point counts array using the MPC buffer... - modePointCounts[label] = MPC_buffer[iCanEl]; - } - } - - //re-assign region count using label counter - int oldRegionCount = regionCount; - regionCount = label+1; - - // (c) - - // Use the label buffer to reconstruct the label map, which specified - // the new image given its new regions calculated above - - for(i = 0; i < height*width; i++) - labels[i] = label_buffer[raList[labels[i]].label]; - - //de-allocate memory - delete [] modes_buffer; - delete [] MPC_buffer; - delete [] label_buffer; - - //done. - return; - -} - -/*******************************************************/ -/*Compute Edge Strengths */ -/*******************************************************/ -/*Computes the a weight for each link in the region */ -/*graph maintined by the RAM, resulting in a weighted */ -/*graph in which the weights consist of a confidence */ -/*between zero and one indicating if the regions are */ -/*separated by a strong or weak edge. */ -/*******************************************************/ -/*Post: */ -/* - an edge strength has been computed between */ -/* each region of the image and placed as a */ -/* weight in the RAM to be used during transi- */ -/* tive closure. */ -/*******************************************************/ - -void msImageProcessor::ComputeEdgeStrengths( void ) -{ - - //initialize visit table - used to keep track - //of which pixels have already been visited such - //as not to contribute their strength value to - //a boundary sum multiple times... - memset(visitTable, 0, L*sizeof(unsigned char)); - - //traverse labeled image computing edge strengths - //(excluding image boundary)... - int x, y, dp, curLabel, rightLabel, bottomLabel; - RAList *curRegion; - for(y = 1; y < height-1; y++) - { - for(x = 1; x < width-1; x++) - { - //compute data point location using x and y - dp = y*width + x; - - //obtain labels at different pixel locations - curLabel = labels[dp ]; //current pixel - rightLabel = labels[dp+1 ]; //right pixel - bottomLabel = labels[dp+width]; //bottom pixel - - //check right and bottom neighbor to see if there is a - //change in label then we are at an edge therefore record - //the edge strength at this edge accumulating its value - //in the RAM... - if(curLabel != rightLabel) - { - //traverse into RAM... - curRegion = &raList[curLabel]; - while((curRegion)&&(curRegion->label != rightLabel)) - curRegion = curRegion->next; - - //this should not occur... - assert(curRegion); - - //accumulate edge strength - curRegion->edgeStrength += weightMap[dp] + weightMap[dp+1]; - curRegion->edgePixelCount += 2; - } - - if(curLabel != bottomLabel) - { - //traverse into RAM... - curRegion = &raList[curLabel]; - while((curRegion)&&(curRegion->label != bottomLabel)) - curRegion = curRegion->next; - - //this should not occur... - assert(curRegion); - - //accumulate edge strength - if(curLabel == rightLabel) - { - curRegion->edgeStrength += weightMap[dp] + weightMap[dp+width]; - curRegion->edgePixelCount += 2; - } - else - { - curRegion->edgeStrength += weightMap[dp+width]; - curRegion->edgePixelCount += 1; - } - - } - } - } - - //compute strengths using accumulated strengths obtained above... - RAList *neighborRegion; - float edgeStrength; - int edgePixelCount; - for(x = 0; x < regionCount; x++) - { - //traverse the region list of the current region - curRegion = &raList[x]; - curRegion = curRegion->next; - while(curRegion) - { - //with the assumption that regions having a smaller - //label in the current region list have already - //had their edge strengths computed, only compute - //edge strengths for the regions whose label is greater - //than x, the current region (region list) under - //consideration... - curLabel = curRegion->label; - if(curLabel > x) - { - //obtain pointer to the element identifying the - //current region in the neighbors region list... - neighborRegion = &raList[curLabel]; - while((neighborRegion)&&(neighborRegion->label != x)) - neighborRegion = neighborRegion->next; - - //this should not occur... - assert(neighborRegion); - - //compute edge strengths using accumulated confidence - //value and pixel count - if((edgePixelCount = curRegion->edgePixelCount + neighborRegion->edgePixelCount) != 0) - { - //compute edge strength - edgeStrength = curRegion->edgeStrength + neighborRegion->edgeStrength; - edgeStrength /= edgePixelCount; - - //store edge strength and pixel count for corresponding regions - curRegion->edgeStrength = neighborRegion->edgeStrength = edgeStrength; - curRegion->edgePixelCount = neighborRegion->edgePixelCount = edgePixelCount; - } - } - - //traverse to the next region in the region adjacency list - //of the current region x - curRegion = curRegion->next; - - } - } - - //compute average edge strength amongst the edges connecting - //it to each of its neighbors - int numNeighbors; - for(x = 0; x < regionCount; x++) - { - //traverse the region list of the current region - //accumulating weights - curRegion = &raList[x]; - curRegion = curRegion->next; - edgeStrength = 0; - numNeighbors = 0; - while(curRegion) - { - numNeighbors++; - edgeStrength += curRegion->edgeStrength; - curRegion = curRegion->next; - } - - //divide by the number of regions connected - //to the current region - if(numNeighbors) edgeStrength /= numNeighbors; - - //store the result in the raList for region - //x - raList[x].edgeStrength = edgeStrength; - } - - //traverse raList and output the resulting list - //to a file - - //done. - return; - -} - -/*******************************************************/ -/*Prune */ -/*******************************************************/ -/*Prunes regions from the image whose pixel density */ -/*is less than a specified threshold. */ -/*******************************************************/ -/*Pre: */ -/* - minRegion is the minimum allowable pixel de- */ -/* nsity a region may have without being pruned */ -/* from the image */ -/*Post: */ -/* - regions whose pixel density is less than */ -/* or equal to minRegion have been pruned from */ -/* the image. */ -/*******************************************************/ - -void msImageProcessor::Prune(int minRegion) -{ - - //Allocate Memory for temporary buffers... - - //allocate memory for mode and point count temporary buffers... - float *modes_buffer = new float [N*regionCount]; - int *MPC_buffer = new int [regionCount]; - - //allocate memory for label buffer - int *label_buffer = new int [regionCount]; - - //Declare variables - int i, k, candidate, iCanEl, neighCanEl, iMPC, label, oldRegionCount, minRegionCount; - double minSqDistance, neighborDistance; - RAList *neighbor; - - //Apply pruning algorithm to classification structure, removing all regions whose area - //is under the threshold area minRegion (pixels) - do - { - //Assume that no region has area under threshold area of - minRegionCount = 0; - - //Step (1): - - // Build RAM using classifiction structure originally - // generated by the method GridTable::Connect() - BuildRAM(); - - // Step (2): - - // Traverse the RAM joining regions whose area is less than minRegion (pixels) - // with its respective candidate region. - - // A candidate region is a region that displays the following properties: - - // - it is adjacent to the region being pruned - - // - the distance of its mode is a minimum to that of the region being pruned - // such that or it is the only adjacent region having an area greater than - // minRegion - - for(i = 0; i < regionCount; i++) - { - //if the area of the ith region is less than minRegion - //join it with its candidate region... - - //******************************************************************************* - - //Note: Adjust this if statement if a more sophisticated pruning criterion - // is desired. Basically in this step a region whose area is less than - // minRegion is pruned by joining it with its "closest" neighbor (in color). - // Therefore, by placing a different criterion for fusing a region the - // pruning method may be altered to implement a more sophisticated algorithm. - - //******************************************************************************* - - if(modePointCounts[i] < minRegion && raList[i].next != NULL) - { - //update minRegionCount to indicate that a region - //having area less than minRegion was found - minRegionCount++; - - //obtain a pointer to the first region in the - //region adjacency list of the ith region... - neighbor = raList[i].next; - - //calculate the distance between the mode of the ith - //region and that of the neighboring region... - candidate = neighbor->label; - minSqDistance = SqDistance(i, candidate); - - //traverse region adjacency list of region i and select - //a candidate region - neighbor = neighbor->next; - while(neighbor) - { - - //calculate the square distance between region i - //and current neighbor... - neighborDistance = SqDistance(i, neighbor->label); - - //if this neighbors square distance to region i is less - //than minSqDistance, then select this neighbor as the - //candidate region for region i - if(neighborDistance < minSqDistance) - { - minSqDistance = neighborDistance; - candidate = neighbor->label; - } - - //traverse region list of region i - neighbor = neighbor->next; - - } - - //join region i with its candidate region: - - // (1) find the canonical element of region i - iCanEl = i; - while(raList[iCanEl].label != iCanEl) - iCanEl = raList[iCanEl].label; - - // (2) find the canonical element of neighboring region - neighCanEl = candidate; - while(raList[neighCanEl].label != neighCanEl) - neighCanEl = raList[neighCanEl].label; - - // if the canonical elements of are not the same then assign - // the canonical element having the smaller label to be the parent - // of the other region... - if(iCanEl < neighCanEl) - raList[neighCanEl].label = iCanEl; - else - { - //must replace the canonical element of previous - //parent as well - raList[raList[iCanEl].label].label = neighCanEl; - - //re-assign canonical element - raList[iCanEl].label = neighCanEl; - } - } - } - - // Step (3): - - // Level binary trees formed by canonical elements - for(i = 0; i < regionCount; i++) - { - iCanEl = i; - while(raList[iCanEl].label != iCanEl) - iCanEl = raList[iCanEl].label; - raList[i].label = iCanEl; - } - - // Step (4): - - //Traverse joint sets, relabeling image. - - // Accumulate modes and re-compute point counts using canonical - // elements generated by step 2. - - //initialize buffers to zero - for(i = 0; i < regionCount; i++) - MPC_buffer[i] = 0; - for(i = 0; i < N*regionCount; i++) - modes_buffer[i] = 0; - - //traverse raList accumulating modes and point counts - //using canoncial element information... - for(i = 0; i < regionCount; i++) - { - - //obtain canonical element of region i - iCanEl = raList[i].label; - - //obtain mode point count of region i - iMPC = modePointCounts[i]; - - //accumulate modes_buffer[iCanEl] - for(k = 0; k < N; k++) - modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k]; - - //accumulate MPC_buffer[iCanEl] - MPC_buffer[iCanEl] += iMPC; - - } - - // (b) - - // Re-label new regions of the image using the canonical - // element information generated by step (2) - - // Also use this information to compute the modes of the newly - // defined regions, and to assign new region point counts in - // a consecute manner to the modePointCounts array - - //initialize label buffer to -1 - for(i = 0; i < regionCount; i++) - label_buffer[i] = -1; - - //traverse raList re-labeling the regions - label = -1; - for(i = 0; i < regionCount; i++) - { - //obtain canonical element of region i - iCanEl = raList[i].label; - if(label_buffer[iCanEl] < 0) - { - //assign a label to the new region indicated by canonical - //element of i - label_buffer[iCanEl] = ++label; - - //recompute mode storing the result in modes[label]... - iMPC = MPC_buffer[iCanEl]; - for(k = 0; k < N; k++) - modes[(N*label)+k] = (modes_buffer[(N*iCanEl)+k])/(iMPC); - - //assign a corresponding mode point count for this region into - //the mode point counts array using the MPC buffer... - modePointCounts[label] = MPC_buffer[iCanEl]; - } - } - - //re-assign region count using label counter - oldRegionCount = regionCount; - regionCount = label+1; - - // (c) - - // Use the label buffer to reconstruct the label map, which specified - // the new image given its new regions calculated above - - for(i = 0; i < height*width; i++) - labels[i] = label_buffer[raList[labels[i]].label]; - - - } while(minRegionCount > 0); - - //de-allocate memory - delete [] modes_buffer; - delete [] MPC_buffer; - delete [] label_buffer; - - //done. - return; - -} - -/*******************************************************/ -/*Define Boundaries */ -/*******************************************************/ -/*Defines the boundaries for each region of the segm- */ -/*ented image storing the result into a region list */ -/*object. */ -/*******************************************************/ -/*Pre: */ -/* - the image has been segmented and a classifi- */ -/* cation structure has been created for this */ -/* image */ -/*Post: */ -/* - the boundaries of the segmented image have */ -/* been defined and the boundaries of each reg- */ -/* ion has been stored into a region list obj- */ -/* ect. */ -/*******************************************************/ - -void msImageProcessor::DefineBoundaries( void ) -{ - - //declare and allocate memory for boundary map and count - int *boundaryMap, *boundaryCount; - if((!(boundaryMap = new int [L]))||(!(boundaryCount = new int [regionCount]))) - ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory."); - - //initialize boundary map and count - int i; - for(i = 0; i < L; i++) - boundaryMap[i] = -1; - for(i = 0; i < regionCount; i++) - boundaryCount[i] = 0; - - //initialize and declare total boundary count - - //the total number of boundary pixels present in - //the segmented image - int totalBoundaryCount = 0; - - //traverse the image checking the right and bottom - //four connected neighbors of each pixel marking - //boundary map with the boundaries of each region and - //incrementing boundaryCount using the label information - - //*********************************************************************** - //*********************************************************************** - - int j, label, dataPoint; - - //first row (every pixel is a boundary pixel) - for(i = 0; i < width; i++) - { - boundaryMap[i] = label = labels[i]; - boundaryCount[label]++; - totalBoundaryCount++; - } - - //define boundaries for all rows except for the first - //and last one... - for(i = 1; i < height - 1; i++) - { - //mark the first pixel in an image row as an image boundary... - dataPoint = i*width; - boundaryMap[dataPoint] = label = labels[dataPoint]; - boundaryCount[label]++; - totalBoundaryCount++; - - for(j = 1; j < width - 1; j++) - { - //define datapoint and its right and bottom - //four connected neighbors - dataPoint = i*width+j; - - //check four connected neighbors if they are - //different this pixel is a boundary pixel - label = labels[dataPoint]; - if((label != labels[dataPoint-1]) ||(label != labels[dataPoint+1])|| - (label != labels[dataPoint-width])||(label != labels[dataPoint+width])) - { - boundaryMap[dataPoint] = label = labels[dataPoint]; - boundaryCount[label]++; - totalBoundaryCount++; - } - } - - //mark the last pixel in an image row as an image boundary... - dataPoint = (i+1)*width-1; - boundaryMap[dataPoint] = label = labels[dataPoint]; - boundaryCount[label]++; - totalBoundaryCount++; - - } - - //last row (every pixel is a boundary pixel) (i = height-1) - register int start = (height-1)*width, stop = height*width; - for(i = start; i < stop; i++) - { - boundaryMap[i] = label = labels[i]; - boundaryCount[label]++; - totalBoundaryCount++; - } - - //*********************************************************************** - //*********************************************************************** - - //store boundary locations into a boundary buffer using - //boundary map and count - - //*********************************************************************** - //*********************************************************************** - - int *boundaryBuffer = new int [totalBoundaryCount], *boundaryIndex = new int [regionCount]; - - //use boundary count to initialize boundary index... - int counter = 0; - for(i = 0; i < regionCount; i++) - { - boundaryIndex[i] = counter; - counter += boundaryCount[i]; - } - - //traverse boundary map placing the boundary pixel - //locations into the boundaryBuffer - for(i = 0; i < L; i++) - { - //if its a boundary pixel store it into - //the boundary buffer - if((label = boundaryMap[i]) >= 0) - { - boundaryBuffer[boundaryIndex[label]] = i; - boundaryIndex[label]++; - } - } - - //*********************************************************************** - //*********************************************************************** - - //store the boundary locations stored by boundaryBuffer into - //the region list for each region - - //*********************************************************************** - //*********************************************************************** - - //destroy the old region list - if(regionList) delete regionList; - - //create a new region list - if(!(regionList = new RegionList(regionCount, totalBoundaryCount, N))) - ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory."); - - //add boundary locations for each region using the boundary - //buffer and boundary counts - counter = 0; - for(i = 0; i < regionCount; i++) - { - regionList->AddRegion(i, boundaryCount[i], &boundaryBuffer[counter]); - counter += boundaryCount[i]; - } - - //*********************************************************************** - //*********************************************************************** - - // dealocate local used memory - delete [] boundaryMap; - delete [] boundaryCount; - delete [] boundaryBuffer; - delete [] boundaryIndex; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Data Searching/Distance Calculation */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*In Window */ -/*******************************************************/ -/*Returns true if the two specified data points are */ -/*within rR of each other. */ -/*******************************************************/ -/*Pre: */ -/* - mode1 and mode2 are indeces into msRawData */ -/* specifying the modes of the pixels having */ -/* these indeces. */ -/*Post: */ -/* - true is returned if mode1 and mode2 are wi- */ -/* thin rR of one another, false is returned */ -/* otherwise. */ -/*******************************************************/ - -bool msImageProcessor::InWindow(int mode1, int mode2) -{ - int k = 1, s = 0, p; - double diff = 0, el; - while((diff < 0.25)&&(k != kp)) // Partial Distortion Search - { - //Calculate distance squared of sub-space s - diff = 0; - for(p = 0; p < P[k]; p++) - { - el = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]); - if((!p)&&(k == 1)&&(modes[mode1*N] > 80)) - diff += 4*el*el; - else - diff += el*el; - } - - //next subspace - s += P[k]; - k++; - } - return (bool)(diff < 0.25); -} - -/*******************************************************/ -/*Square Distance */ -/*******************************************************/ -/*Computs the normalized square distance between two */ -/*modes. */ -/*******************************************************/ -/*Pre: */ -/* - mode1 and mode2 are indeces into the modes */ -/* array specifying two modes of the image */ -/*Post: */ -/* - the normalized square distance between modes */ -/* indexed by mode1 and mode2 has been calc- */ -/* ulated and the result has been returned. */ -/*******************************************************/ - -float msImageProcessor::SqDistance(int mode1, int mode2) -{ - - int k = 1, s = 0, p; - float dist = 0, el; - for(k = 1; k < kp; k++) - { - //Calculate distance squared of sub-space s - for(p = 0; p < P[k]; p++) - { - el = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]); - dist += el*el; - } - - //next subspace - s += P[k]; - k++; - } - - //return normalized square distance between modes - //1 and 2 - return dist; - -} - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Memory Management */ - /*\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Initialize Output */ -/*******************************************************/ -/*Allocates memory needed by the mean shift image pro- */ -/*cessor class output storage data structure. */ -/*******************************************************/ -/*Post: */ -/* - the memory needed by the output storage */ -/* structure of this class has been (re-)allo- */ -/* cated. */ -/*******************************************************/ - -void msImageProcessor::InitializeOutput( void ) -{ - - //De-allocate memory if output was defined for previous image - DestroyOutput(); - - //Allocate memory for msRawData (filtered image output) - if(!(msRawData = new float [L*N])) - { - ErrorHandler("msImageProcessor", "Allocate", "Not enough memory."); - return; - } - - //Allocate memory used to store image modes and their corresponding regions... - if((!(modes = new float [L*(N+2)]))||(!(labels = new int [L]))||(!(modePointCounts = new int [L]))||(!(indexTable = new int [L]))) - { - ErrorHandler("msImageProcessor", "Allocate", "Not enough memory"); - return; - } - - //Allocate memory for integer modes used to perform connected components - //(image labeling)... -// if(!(LUV_data = new int [N*L])) - if (!(LUV_data = new float[N*L])) - { - ErrorHandler("msImageProcessor", "Allocate", "Not enough memory"); - return; - } - - //indicate that the class output storage structure has been defined - class_state.OUTPUT_DEFINED = true; - -} - -/*******************************************************/ -/*Destroy Output */ -/*******************************************************/ -/*De-allocates memory needed by the mean shift image */ -/*processor class output storage data structure. */ -/*******************************************************/ -/*Post: */ -/* - the memory needed by the output storage */ -/* structure of this class has been de-alloc- */ -/* ated. */ -/* - the output storage structure has been init- */ -/* ialized for re-use. */ -/*******************************************************/ - -void msImageProcessor::DestroyOutput( void ) -{ - - //de-allocate memory for msRawData (filtered image output) - if (msRawData) delete [] msRawData; - - //de-allocate memory used by output storage and image - //classification structure - if (modes) delete [] modes; - if (labels) delete [] labels; - if (modePointCounts) delete [] modePointCounts; - if (indexTable) delete [] indexTable; - - //de-allocate memory for LUV_data - if (LUV_data) delete [] LUV_data; - - //initialize data members for re-use... - - //initialize output structures... - msRawData = NULL; - - //re-initialize classification structure - modes = NULL; - labels = NULL; - modePointCounts = NULL; - regionCount = 0; - - //indicate that the output has been destroyed - class_state.OUTPUT_DEFINED = false; - - //done. - return; - -} - -// NEW -void msImageProcessor::NewOptimizedFilter1(float sigmaS, float sigmaR) -{ - // Declare Variables - int iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i; - double mvAbs, diff, el; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // let's use some temporary data - float* sdata; - sdata = new float[lN*L]; - - // copy the scaled data - int idxs, idxd; - idxs = idxd = 0; - if (N==3) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else if (N==1) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - for (j=0; j<N; j++) - sdata[idxs++] = data[idxd++]/sigmaR; - } - } - // index the data in the 3d buckets (x, y, L) - int* buckets; - int* slist; - slist = new int[L]; - int bucNeigh[27]; - - float sMins; // just for L - float sMaxs[3]; // for all - sMaxs[0] = width/sigmaS; - sMaxs[1] = height/sigmaS; - sMins = sMaxs[2] = sdata[2]; - idxs = 2; - float cval; - for(i=0; i<L; i++) - { - cval = sdata[idxs]; - if (cval < sMins) - sMins = cval; - else if (cval > sMaxs[2]) - sMaxs[2] = cval; - - idxs += lN; - } - - int nBuck1, nBuck2, nBuck3; - int cBuck1, cBuck2, cBuck3, cBuck; - nBuck1 = (int) (sMaxs[0] + 3); - nBuck2 = (int) (sMaxs[1] + 3); - nBuck3 = (int) (sMaxs[2] - sMins + 3); - buckets = new int[nBuck1*nBuck2*nBuck3]; - for(i=0; i<(nBuck1*nBuck2*nBuck3); i++) - buckets[i] = -1; - - idxs = 0; - for(i=0; i<L; i++) - { - // find bucket for current data and add it to the list - cBuck1 = (int) sdata[idxs] + 1; - cBuck2 = (int) sdata[idxs+1] + 1; - cBuck3 = (int) (sdata[idxs+2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - - slist[i] = buckets[cBuck]; - buckets[cBuck] = i; - - idxs += lN; - } - // init bucNeigh - idxd = 0; - for (cBuck1=-1; cBuck1<=1; cBuck1++) - { - for (cBuck2=-1; cBuck2<=1; cBuck2++) - { - for (cBuck3=-1; cBuck3<=1; cBuck3++) - { - bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - } - } - } - double wsuml, weight; - double hiLTr = 80.0/sigmaR; - // done indexing/hashing - - - // Initialize mode table used for basin of attraction - memset(modeTable, 0, width*height); - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - - for(i = 0; i < L; i++) - { - // if a mode was already assigned to this data point - // then skip this point, otherwise proceed to - // find its mode by applying mean shift... - if (modeTable[i] == 1) - continue; - - // initialize point list... - pointCount = 0; - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - idxs = i*lN; - for (j=0; j<lN; j++) - yk[j] = sdata[idxs+j]; - - // Calculate the mean shift vector using the lattice - // LatticeMSVector(Mh, yk); // modify to new - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - // Calculate its magnitude squared - //mvAbs = 0; - //for(j = 0; j < lN; j++) - // mvAbs += Mh[j]*Mh[j]; - mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS; - if (N==3) - mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR; - else - mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR; - - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // check to see if the current mode location is in the - // basin of attraction... - - // calculate the location of yk on the lattice - modeCandidateX = (int) (sigmaS*yk[0]+0.5); - modeCandidateY = (int) (sigmaS*yk[1]+0.5); - modeCandidate_i = modeCandidateY*width + modeCandidateX; - - // if mvAbs != 0 (yk did indeed move) then check - // location basin_i in the mode table to see if - // this data point either: - - // (1) has not been associated with a mode yet - // (modeTable[basin_i] = 0), so associate - // it with this one - // - // (2) it has been associated with a mode other - // than the one that this data point is converging - // to (modeTable[basin_i] = 1), so assign to - // this data point the same mode as that of basin_i - - if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i)) - { - // obtain the data point at basin_i to - // see if it is within h*TC_DIST_FACTOR of - // of yk - diff = 0; - idxs = lN*modeCandidate_i; - for (k=2; k<lN; k++) - { - el = sdata[idxs+k] - yk[k]; - diff += el*el; - } - - // if the data point at basin_i is within - // a distance of h*TC_DIST_FACTOR of yk - // then depending on modeTable[basin_i] perform - // either (1) or (2) - if (diff < TC_DIST_FACTOR) - { - // if the data point at basin_i has not - // been associated to a mode then associate - // it with the mode that this one will converge - // to - if (modeTable[modeCandidate_i] == 0) - { - // no mode associated yet so associate - // it with this one... - pointList[pointCount++] = modeCandidate_i; - modeTable[modeCandidate_i] = 2; - - } else - { - - // the mode has already been associated with - // another mode, thererfore associate this one - // mode and the modes in the point list with - // the mode associated with data[basin_i]... - - // store the mode info into yk using msRawData... - for (j = 0; j < N; j++) - yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - // indicate that a mode has been associated - // to this data point (data[i]) - mvAbs = -1; - - // stop mean shift calculation... - break; - } - } - } - - // Calculate the mean shift vector at the new - // window location using lattice - // Calculate the mean shift vector using the lattice - // LatticeMSVector(Mh, yk); // modify to new - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - - // Calculate its magnitude squared - //mvAbs = 0; - //for(j = 0; j < lN; j++) - // mvAbs += Mh[j]*Mh[j]; - mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS; - if (N==3) - mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR; - else - mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR; - - // Increment iteration count - iterationCount++; - - } - - // if a mode was not associated with this data point - // yet associate it with yk... - if (mvAbs >= 0) - { - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - } - - for (k=0; k<N; k++) - yk[k+2] *= sigmaR; - - // associate the data point indexed by - // the point list with the mode stored - // by yk - for (j = 0; j < pointCount; j++) - { - // obtain the point location from the - // point list - modeCandidate_i = pointList[j]; - - // update the mode table for this point - modeTable[modeCandidate_i] = 1; - - //store result into msRawData... - for(k = 0; k < N; k++) - msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]); - } - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - // de-allocate memory - delete [] buckets; - delete [] slist; - delete [] sdata; - - delete [] yk; - delete [] Mh; - - // done. - return; - -} - -// NEW -void msImageProcessor::NewOptimizedFilter2(float sigmaS, float sigmaR) -{ - // Declare Variables - int iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i; - double mvAbs, diff, el; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // let's use some temporary data - float* sdata; - sdata = new float[lN*L]; - - // copy the scaled data - int idxs, idxd; - idxs = idxd = 0; - if (N==3) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else if (N==1) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - for (j=0; j<N; j++) - sdata[idxs++] = data[idxd++]/sigmaR; - } - } - // index the data in the 3d buckets (x, y, L) - int* buckets; - int* slist; - slist = new int[L]; - int bucNeigh[27]; - - float sMins; // just for L - float sMaxs[3]; // for all - sMaxs[0] = width/sigmaS; - sMaxs[1] = height/sigmaS; - sMins = sMaxs[2] = sdata[2]; - idxs = 2; - float cval; - for(i=0; i<L; i++) - { - cval = sdata[idxs]; - if (cval < sMins) - sMins = cval; - else if (cval > sMaxs[2]) - sMaxs[2] = cval; - - idxs += lN; - } - - int nBuck1, nBuck2, nBuck3; - int cBuck1, cBuck2, cBuck3, cBuck; - nBuck1 = (int) (sMaxs[0] + 3); - nBuck2 = (int) (sMaxs[1] + 3); - nBuck3 = (int) (sMaxs[2] - sMins + 3); - buckets = new int[nBuck1*nBuck2*nBuck3]; - for(i=0; i<(nBuck1*nBuck2*nBuck3); i++) - buckets[i] = -1; - - idxs = 0; - for(i=0; i<L; i++) - { - // find bucket for current data and add it to the list - cBuck1 = (int) sdata[idxs] + 1; - cBuck2 = (int) sdata[idxs+1] + 1; - cBuck3 = (int) (sdata[idxs+2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - - slist[i] = buckets[cBuck]; - buckets[cBuck] = i; - - idxs += lN; - } - // init bucNeigh - idxd = 0; - for (cBuck1=-1; cBuck1<=1; cBuck1++) - { - for (cBuck2=-1; cBuck2<=1; cBuck2++) - { - for (cBuck3=-1; cBuck3<=1; cBuck3++) - { - bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - } - } - } - double wsuml, weight; - double hiLTr = 80.0/sigmaR; - // done indexing/hashing - - - // Initialize mode table used for basin of attraction - memset(modeTable, 0, width*height); - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - - for(i = 0; i < L; i++) - { - // if a mode was already assigned to this data point - // then skip this point, otherwise proceed to - // find its mode by applying mean shift... - if (modeTable[i] == 1) - continue; - - // initialize point list... - pointCount = 0; - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - idxs = i*lN; - for (j=0; j<lN; j++) - yk[j] = sdata[idxs+j]; - - // Calculate the mean shift vector using the lattice - // LatticeMSVector(Mh, yk); // modify to new - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - - //set basin of attraction mode table - if (diff < speedThreshold) - { - if(modeTable[idxd] == 0) - { - pointList[pointCount++] = idxd; - modeTable[idxd] = 2; - } - } - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - // Calculate its magnitude squared - //mvAbs = 0; - //for(j = 0; j < lN; j++) - // mvAbs += Mh[j]*Mh[j]; - mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS; - if (N==3) - mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR; - else - mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR; - - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // check to see if the current mode location is in the - // basin of attraction... - - // calculate the location of yk on the lattice - modeCandidateX = (int) (sigmaS*yk[0]+0.5); - modeCandidateY = (int) (sigmaS*yk[1]+0.5); - modeCandidate_i = modeCandidateY*width + modeCandidateX; - - // if mvAbs != 0 (yk did indeed move) then check - // location basin_i in the mode table to see if - // this data point either: - - // (1) has not been associated with a mode yet - // (modeTable[basin_i] = 0), so associate - // it with this one - // - // (2) it has been associated with a mode other - // than the one that this data point is converging - // to (modeTable[basin_i] = 1), so assign to - // this data point the same mode as that of basin_i - - if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i)) - { - // obtain the data point at basin_i to - // see if it is within h*TC_DIST_FACTOR of - // of yk - diff = 0; - idxs = lN*modeCandidate_i; - for (k=2; k<lN; k++) - { - el = sdata[idxs+k] - yk[k]; - diff += el*el; - } - - // if the data point at basin_i is within - // a distance of h*TC_DIST_FACTOR of yk - // then depending on modeTable[basin_i] perform - // either (1) or (2) - if (diff < speedThreshold) - { - // if the data point at basin_i has not - // been associated to a mode then associate - // it with the mode that this one will converge - // to - if (modeTable[modeCandidate_i] == 0) - { - // no mode associated yet so associate - // it with this one... - pointList[pointCount++] = modeCandidate_i; - modeTable[modeCandidate_i] = 2; - - } else - { - - // the mode has already been associated with - // another mode, thererfore associate this one - // mode and the modes in the point list with - // the mode associated with data[basin_i]... - - // store the mode info into yk using msRawData... - for (j = 0; j < N; j++) - yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - // indicate that a mode has been associated - // to this data point (data[i]) - mvAbs = -1; - - // stop mean shift calculation... - break; - } - } - } - - // Calculate the mean shift vector at the new - // window location using lattice - // Calculate the mean shift vector using the lattice - // LatticeMSVector(Mh, yk); // modify to new - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - - //set basin of attraction mode table - if (diff < speedThreshold) - { - if(modeTable[idxd] == 0) - { - pointList[pointCount++] = idxd; - modeTable[idxd] = 2; - } - } - - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - - // Calculate its magnitude squared - //mvAbs = 0; - //for(j = 0; j < lN; j++) - // mvAbs += Mh[j]*Mh[j]; - mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS; - if (N==3) - mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR; - else - mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR; - - // Increment iteration count - iterationCount++; - - } - - // if a mode was not associated with this data point - // yet associate it with yk... - if (mvAbs >= 0) - { - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // update mode table for this data point - // indicating that a mode has been associated - // with it - modeTable[i] = 1; - - } - - for (k=0; k<N; k++) - yk[k+2] *= sigmaR; - - // associate the data point indexed by - // the point list with the mode stored - // by yk - for (j = 0; j < pointCount; j++) - { - // obtain the point location from the - // point list - modeCandidate_i = pointList[j]; - - // update the mode table for this point - modeTable[modeCandidate_i] = 1; - - //store result into msRawData... - for(k = 0; k < N; k++) - msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]); - } - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - // de-allocate memory - delete [] buckets; - delete [] slist; - delete [] sdata; - - delete [] yk; - delete [] Mh; - - // done. - return; - -} - -void msImageProcessor::NewNonOptimizedFilter(float sigmaS, float sigmaR) -{ - - // Declare Variables - int iterationCount, i, j, k; - double mvAbs, diff, el; - - //make sure that a lattice height and width have - //been defined... - if(!height) - { - ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined."); - return; - } - - //re-assign bandwidths to sigmaS and sigmaR - if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0)) - { - ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative."); - return; - } - - //define input data dimension with lattice - int lN = N + 2; - - // Traverse each data point applying mean shift - // to each data point - - // Allcocate memory for yk - double *yk = new double [lN]; - - // Allocate memory for Mh - double *Mh = new double [lN]; - - // let's use some temporary data - double* sdata; - sdata = new double[lN*L]; - - // copy the scaled data - int idxs, idxd; - idxs = idxd = 0; - if (N==3) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else if (N==1) - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i/width)/sigmaS; - sdata[idxs++] = data[idxd++]/sigmaR; - } - } else - { - for(i=0; i<L; i++) - { - sdata[idxs++] = (i%width)/sigmaS; - sdata[idxs++] = (i%width)/sigmaS; - for (j=0; j<N; j++) - sdata[idxs++] = data[idxd++]/sigmaR; - } - } - // index the data in the 3d buckets (x, y, L) - int* buckets; - int* slist; - slist = new int[L]; - int bucNeigh[27]; - - double sMins; // just for L - double sMaxs[3]; // for all - sMaxs[0] = width/sigmaS; - sMaxs[1] = height/sigmaS; - sMins = sMaxs[2] = sdata[2]; - idxs = 2; - double cval; - for(i=0; i<L; i++) - { - cval = sdata[idxs]; - if (cval < sMins) - sMins = cval; - else if (cval > sMaxs[2]) - sMaxs[2] = cval; - - idxs += lN; - } - - int nBuck1, nBuck2, nBuck3; - int cBuck1, cBuck2, cBuck3, cBuck; - nBuck1 = (int) (sMaxs[0] + 3); - nBuck2 = (int) (sMaxs[1] + 3); - nBuck3 = (int) (sMaxs[2] - sMins + 3); - buckets = new int[nBuck1*nBuck2*nBuck3]; - for(i=0; i<(nBuck1*nBuck2*nBuck3); i++) - buckets[i] = -1; - - idxs = 0; - for(i=0; i<L; i++) - { - // find bucket for current data and add it to the list - cBuck1 = (int) sdata[idxs] + 1; - cBuck2 = (int) sdata[idxs+1] + 1; - cBuck3 = (int) (sdata[idxs+2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - - slist[i] = buckets[cBuck]; - buckets[cBuck] = i; - - idxs += lN; - } - // init bucNeigh - idxd = 0; - for (cBuck1=-1; cBuck1<=1; cBuck1++) - { - for (cBuck2=-1; cBuck2<=1; cBuck2++) - { - for (cBuck3=-1; cBuck3<=1; cBuck3++) - { - bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - } - } - } - double wsuml, weight; - double hiLTr = 80.0/sigmaR; - // done indexing/hashing - - // proceed ... -#ifdef PROMPT - msSys.Prompt("done.\nApplying mean shift (Using Lattice)... "); -#ifdef SHOW_PROGRESS - msSys.Prompt("\n 0%%"); -#endif -#endif - - for(i = 0; i < L; i++) - { - - // Assign window center (window centers are - // initialized by createLattice to be the point - // data[i]) - idxs = i*lN; - for (j=0; j<lN; j++) - yk[j] = sdata[idxs+j]; - - // Calculate the mean shift vector using the lattice - // LatticeMSVector(Mh, yk); - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - - // Calculate its magnitude squared - mvAbs = 0; - for(j = 0; j < lN; j++) - mvAbs += Mh[j]*Mh[j]; - - // Keep shifting window center until the magnitude squared of the - // mean shift vector calculated at the window center location is - // under a specified threshold (Epsilon) - - // NOTE: iteration count is for speed up purposes only - it - // does not have any theoretical importance - iterationCount = 1; - while((mvAbs >= EPSILON)&&(iterationCount < LIMIT)) - { - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - // Calculate the mean shift vector at the new - // window location using lattice - // LatticeMSVector(Mh, yk); - /*****************************************************/ - // Initialize mean shift vector - for(j = 0; j < lN; j++) - Mh[j] = 0; - wsuml = 0; - // uniformLSearch(Mh, yk_ptr); // modify to new - // find bucket of yk - cBuck1 = (int) yk[0] + 1; - cBuck2 = (int) yk[1] + 1; - cBuck3 = (int) (yk[2] - sMins) + 1; - cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3); - for (j=0; j<27; j++) - { - idxd = buckets[cBuck+bucNeigh[j]]; - // list parse, crt point is cHeadList - while (idxd>=0) - { - idxs = lN*idxd; - // determine if inside search window - el = sdata[idxs+0]-yk[0]; - diff = el*el; - el = sdata[idxs+1]-yk[1]; - diff += el*el; - - if (diff < 1.0) - { - el = sdata[idxs+2]-yk[2]; - if (yk[2] > hiLTr) - diff = 4*el*el; - else - diff = el*el; - - if (N>1) - { - el = sdata[idxs+3]-yk[3]; - diff += el*el; - el = sdata[idxs+4]-yk[4]; - diff += el*el; - } - - if (diff < 1.0) - { - weight = 1-weightMap[idxd]; - for (k=0; k<lN; k++) - Mh[k] += weight*sdata[idxs+k]; - wsuml += weight; - } - } - idxd = slist[idxd]; - } - } - if (wsuml > 0) - { - for(j = 0; j < lN; j++) - Mh[j] = Mh[j]/wsuml - yk[j]; - } - else - { - for(j = 0; j < lN; j++) - Mh[j] = 0; - } - /*****************************************************/ - - // Calculate its magnitude squared - //mvAbs = 0; - //for(j = 0; j < lN; j++) - // mvAbs += Mh[j]*Mh[j]; - mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS; - if (N==3) - mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR; - else - mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR; - - // Increment interation count - iterationCount++; - } - - // Shift window location - for(j = 0; j < lN; j++) - yk[j] += Mh[j]; - - //store result into msRawData... - for(j = 0; j < N; j++) - msRawData[N*i+j] = (float)(yk[j+2]*sigmaR); - - // Prompt user on progress -#ifdef SHOW_PROGRESS - percent_complete = (float)(i/(float)(L))*100; - msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5)); -#endif - - // Check to see if the algorithm has been halted - if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT) - break; - } - - // Prompt user that filtering is completed -#ifdef PROMPT -#ifdef SHOW_PROGRESS - msSys.Prompt("\r"); -#endif - msSys.Prompt("done."); -#endif - - // de-allocate memory - delete [] buckets; - delete [] slist; - delete [] sdata; - - delete [] yk; - delete [] Mh; - - // done. - return; - -} - -void msImageProcessor::SetSpeedThreshold(float speedUpThreshold) -{ - speedThreshold = speedUpThreshold; -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - diff --git a/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.h b/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.h deleted file mode 100644 index 62095c90fb10059cee35235faddfcf5e255e0e29..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/msImageProcessor.h +++ /dev/null @@ -1,798 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Mean Shift Image Processor Class: - ================================ - - The following class inherits from the mean shift library - in order to perform the specialized tasks of image - segmentation and filtering. - - The prototype of the Mean Shift Image Processor Class - is provided below. Its definition is provided in - 'msImageProcessor.cc'. - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -#ifndef msImageProcessor_H -#define msImageProcessor_H - -//include mean shift library -#include "ms.h" - -//include prototypes of additional strucuters -//used for image segmentation... - -//include region list used to store boundary pixel -//indeces for each region -#include "rlist.h" - -//include region adjacency list class used for -//region pruning and transitive closure -#include "RAList.h" - -//define constants - - //image pruning -#define TOTAL_ITERATIONS 14 -#define BIG_NUM 0xffffffff //BIG_NUM = 2^32-1 -#define NODE_MULTIPLE 10 - - //data space conversion... -const double Xn = 0.95050; -const double Yn = 1.00000; -const double Zn = 1.08870; -//const double Un_prime = 0.19780; -//const double Vn_prime = 0.46830; -const double Un_prime = 0.19784977571475; -const double Vn_prime = 0.46834507665248; -const double Lt = 0.008856; - - //RGB to LUV conversion -const double XYZ[3][3] = { { 0.4125, 0.3576, 0.1804 }, - { 0.2125, 0.7154, 0.0721 }, - { 0.0193, 0.1192, 0.9502 } }; - - //LUV to RGB conversion -const double RGB[3][3] = { { 3.2405, -1.5371, -0.4985 }, - { -0.9693, 1.8760, 0.0416 }, - { 0.0556, -0.2040, 1.0573 } }; - -//define data types -typedef unsigned char byte; - -//define enumerations -enum imageType {GRAYSCALE, COLOR}; - -//define prototype -class msImageProcessor: public MeanShift { - -public: - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - msImageProcessor( void ); //Default Constructor - ~msImageProcessor( void ); //Class Destructor - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Input Image Declaration */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Define Image * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Uploads an image to be segmented by the image |// - //| segmenter class. |// - //| |// - //| An image is defined by specifying the folloing: |// - //| |// - //| <* data *> |// - //| A one dimensional unsigned char array of RGB |// - //| vectors. |// - //| |// - //| <* type *> |// - //| Specifies the image type: COLOR or GREYSCALE. |// - //| |// - //| <* height *> |// - //| The image height. |// - //| |// - //| <* width *> |// - //| The image width. |// - //| |// - //| This method uploads the image and converts its |// - //| data into the LUV space. If another conversion |// - //| is desired data may be uploaded into this class |// - //| via the procedure MeanShift::UploadInput(). |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| DefineImage(data, type, height, width) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void DefineImage(byte*,imageType, int, int); - void DefineBgImage(byte*, imageType , int , int ); - - - /*/\/\/\/\/\/\*/ - /* Weight Map */ - /*\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Set Weight Map * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Uploads weight map specifying for each pixel |// - //| in the image a value between 0 and 1 - 1 indica- |// - //| ting the presence of an edge and 0 the absense |// - //| of an edge. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* weightMap *> |// - //| A floating point array of size (height x width) |// - //| specifying at location (i,j) the edge strength |// - //| of pixel (i,j). (e.g. pixel (i,j) has an edge |// - //| strength of weightMap[j*width+i]). |// - //| |// - //| <* epsilon *> |// - //| A floating point number specifying the threshold |// - //| used to fuse regions during transitive closure. |// - //| |// - //| Note: DefineImage must be called prior to call- |// - //| ing this method. DefineImage is used to |// - //| define the dimensions of the image. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| SetWeightMap(weightMap, epsilon) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void SetWeightMap(float*, float); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Remove Weight Map * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Removes weight map. An error is NOT flagged |// - //| if a weight map was not defined prior to calling |// - //| this method. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| RemoveWeightMap(void) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void RemoveWeightMap(void); - - /*/\/\/\/\/\/\/\/\/\*/ - /* Image Filtering */ - /*\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Filter * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Apply mean shift filter to the defined image, |// - //| defined either via MeanShift::DefineLInput or |// - //| msImageProcessor::DefineImage. The resulting |// - //| segmented image is stored in the private data |// - //| members of the image segmenter class which can |// - //| be obtained by calling image msImageProcessor:: |// - //| GetResults(). |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* sigmaS *> |// - //| The spatial radius of the mean shift window. |// - //| |// - //| <* sigmaR *> |// - //| The range radius of the mean shift window. |// - //| |// - //| <* speedUpLevel *> |// - //| Determines if a speed up optimization should be |// - //| used to perform image filtering. A value of |// - //| NO_SPEEDUP turns this optimization off and a |// - //| value of SPEEDUP turns this optimization on. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| Filter(sigmaS, sigmaR, speedUpLevel) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void Filter(int, float, SpeedUpLevel); - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Region Fusing */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Fuse Regions * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Fuses the regions of a filtered image, |// - //| defined either via MeanShift::DefineLInput or |// - //| msImageProcessor::DefineImage. The resulting |// - //| segmented image is stored in the private data |// - //| members of the image segmenter class which can |// - //| be obtained by calling image msImageProcessor:: |// - //| GetResults(). |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* sigmaR *> |// - //| The range radius that defines similar color |// - //| amongst image regions. |// - //| |// - //| <* minRegion *> |// - //| The minimum density a region may have in the |// - //| resulting segmented image. All regions have |// - //| point density < minRegion are pruned from the |// - //| image. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| FuseRegions(sigmaR, minRegion) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void FuseRegions(float, int); - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Image Segmentation */ - /*\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Segment * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Segments the defined image, defined either via |// - //| MeanShift::DefineLInput or msImageProcessor::De- |// - //| fineImage. The resulting segmented image is |// - //| stored in the private data members of the image |// - //| processor class which can be obtained by calling |// - //| ImageSegmenter::GetResults(). |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* sigmaS *> |// - //| The spatial radius of the mean shift window. |// - //| |// - //| <* sigmaR *> |// - //| The range radius of the mean shift window. |// - //| |// - //| <* minRegion *> |// - //| The minimum density a region may have in the |// - //| resulting segmented image. All regions have |// - //| point density < minRegion are pruned from the |// - //| image. |// - //| |// - //| <* speedUpLevel *> |// - //| Determines if a speed up optimization should be |// - //| used to perform image filtering. A value of |// - //| NO_SPEEDUP turns this optimization off and a |// - //| value of SPEEDUP turns this optimization on. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| Segment(sigmaS, sigmaR, minRegion, |// - //| speedUpLevel) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void Segment(int, float, int, SpeedUpLevel); - - /*/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Data Space Conversion */ - /*\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * RGB To LUV * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Converts an RGB vector to LUV. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* rgbVal *> |// - //| An unsigned char array containing the RGB |// - //| vector. |// - //| |// - //| <* luvVal *> |// - //| A floating point array containing the LUV |// - //| vector. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| RGBtoLUV(rgbVal, luvVal) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void RGBtoLUV(byte*, float*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * LUV To RGB * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Converts an LUV vector to RGB. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* luvVal *> |// - //| A floating point array containing the LUV |// - //| vector. |// - //| |// - //| <* rgbVal *> |// - //| An unsigned char array containing the RGB |// - //| vector. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| LUVtoRGB(luvVal, rgbVal) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void LUVtoRGB(float*, byte*); - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Filtered and Segmented Image Output */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Raw Data * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the resulting filtered or segmented im- |// - //| age data after calling Filter() or Segment(). |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* outputImageData *> |// - //| A floating point array containing the vector |// - //| data of the filtered or segmented image. |// - //| |// - //| NOTE: If DefineImage was used to specify the |// - //| the input to this class, outputImageData |// - //| is in the LUV data space. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| GetResults(outputImageData) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void GetRawData(float*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Results * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the resulting filtered or segmented im- |// - //| age after calling Filter() or Segment(). |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* outputImage *> |// - //| An unsigned char array containing the RGB |// - //| vector data of the output image. |// - //| |// - //| To obtain the un-converted (LUV) data space |// - //| output one may use |// - //| msImageProcessor::GetRawData(). |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| GetResults(outputImage) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void GetResults(byte*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Boundaries * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the boundaries of each region of the |// - //| segmented image using a region list object, |// - //| available after filtering or segmenting the |// - //| defined image. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| regionList = GetBoundaries() |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - RegionList *GetBoundaries( void ); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Regions * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the regions of the processed image. |// - //| Each region in the image is uniquely character- |// - //| ized by its location and color (e.g. RGB). |// - //| GetRegions() therefore returns the following |// - //| information about the regions of the processed |// - //| image: |// - //| |// - //| <* regionCount *> |// - //| An integer that specifies the number of regions |// - //| contained in the processed image. |// - //| |// - //| <* modes *> |// - //| A floating point array of length regionCount*N |// - //| containing the feature space component of each |// - //| region (e.g. LUV), and indexed by region label. |// - //| |// - //| <* labels *> |// - //| An integer array of length (height*width) which |// - //| contains at every pixel location (x,y) a label |// - //| relating that pixel to a region whose mode is |// - //| specified by modes and whose area is specified |// - //| by modePointCounts. |// - //| |// - //| <* modePointCounts *> |// - //| An integer array of length regionCount and ind- |// - //| exed by region label, that specifies the region |// - //| area (in pixels) for each segmented image reg- |// - //| ion. (e.g. Area of region having label specif- |// - //| ified by l, has area modePointCounts[l] (pix- |// - //| els).) |// - //| |// - //| NOTE: Memory for the above integer and floating |// - //| point arrays is allocated inside this |// - //| method. |// - //| |// - //| Also modes stored by the modes array are |// - //| not in the RGB space. Instead if the |// - //| method DefineImage was used, these data |// - //| points are in the LUV space, and if the |// - //| method DefineLInput was used these data |// - //| points are in whatever space you specified |// - //| them to be in when calling DefineLInput. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| regionCount = GetRegions(labels, modes |// - //| modePointCounts) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - int GetRegions(int**, float**, int**); - - - void SetSpeedThreshold(float); -private: - - //======================== - // *** Private Methods *** - //======================== - - /*/\/\/\/\/\/\/\/\/\*/ - /* Image Filtering */ - /*\/\/\/\/\/\/\/\/\/*/ - - void NonOptimizedFilter(float, float); // filters the image applying mean shift to each point - // Advantage : most accurate - // Disadvantage : time expensive - void NewNonOptimizedFilter(float, float); - - void OptimizedFilter1(float, float); // filters the image using previous mode information - // to avoid re-applying mean shift to some data points - // Advantage : maintains high level of accuracy, - // large speed up compared to non-optimized - // version - // Disadvantage : POSSIBLY not as accurate as non-optimized - // version - void NewOptimizedFilter1(float, float); - - - void OptimizedFilter2(float, float); //filter the image using previous mode information - //and window traversals to avoid re-applying mean shift to - //some data points - // Advantage : huge speed up - maintains accuracy good enough - // for segmentation - // Disadvantage : not as accurate as previous filters - void NewOptimizedFilter2(float, float); - - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Classification */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - - void Connect( void ); // classifies mean shift filtered image regions using - // private classification structure of this class - - void Fill(int, int); // used by Connect to perform label each region in the - // mean shift filtered image using an eight-connected - // fill - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Transitive Closure and Image Pruning */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void BuildRAM( void ); // build a region adjacency matrix using the region list - // object - - void DestroyRAM( void ); // destroy the region adjacency matrix: de-allocate its memory - // initialize it for re-use - - void TransitiveClosure( void ); // use the RAM to apply transitive closure to the image modes - - void ComputeEdgeStrengths( void ); // computes the weights of the weighted graph using the weight - // map - - //Usage: Prune(minRegion) - void Prune(int); // use the RAM to prune the image of spurious regions (regions - // whose area is less than minRegion pixels, where minRegion is - // an argument of this method) - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Region Boundary Detection */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - void DefineBoundaries( void ); // defines the boundaries of each region using the classified segmented - // image storing the resulting boundary locations for each region using - // a region list object - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Image Data Searching/Distance Calculation */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //Usage: InWindow(modeIndex1, modeIndex2) - bool InWindow(int, int); //returns true if the range data of the specified data points - //are within the defined search window (defined by kernel - //bandwidth h[1]) - - float SqDistance(int, int); // computes the normalized square distance between two modes - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Memory Management */ - /*\/\/\/\/\/\/\/\/\/\/*/ - - void InitializeOutput( void ); //Allocates memory needed by this class to perform image - //filtering and segmentation - - void DestroyOutput( void ); //De-allocates memory needed by this class to perform image - //filtering and segmentation - - //============================= - // *** Private Data Members *** - //============================= - - //########################################## - //####### IMAGE CLASSIFICATION ######## - //########################################## - - /////////Image Boundaries///////// - RegionList *regionList; // stores the boundary locations for each region - - /////////Image Regions//////// - int regionCount; // stores the number of connected regions contained by the - // image - - /////////8 Connected Neighbors///////// - int neigh[8]; - - /////////Index Table///////////////// - int *indexTable; //used during fill algorithm - - /////////LUV_data///////////////// - //int *LUV_data; //stores modes in integer format on lattice - float *LUV_data; //stores modes in float format on lattice - float LUV_treshold; //in float mode this determines what "close" means between modes - - - //########################################## - //####### OUTPUT DATA STORAGE ######## - //########################################## - - ////////Raw Data (1 to 1 correlation with input)//////// - float *msRawData; // Raw data output of mean shift algorithm - // to the location of the data point on the lattice - - ////////Data Modes//////// - int *labels; // assigns a label to each data point associating it to - // a mode in modes (e.g. a data point having label l has - // mode modes[l]) - - float *modes; // stores the mode data of the input data set, indexed by labels - - int *modePointCounts; // stores for each mode the number of point mapped to that mode, - // indexed by labels - - //########################################## - //####### REGION ADJACENCY MATRIX ######## - //########################################## - - //////////Region Adjacency List///////// - RAList *raList; // an array of RAList objects containing an entry for each - // region of the image - - //////////RAMatrix Free List/////////// - RAList *freeRAList; // a pointer to the head of a region adjacency list object - // free list - - RAList *raPool; // a pool of RAList objects used in the construction of the - // RAM - - //############################################## - //####### COMPUTATION OF EDGE STRENGTHS ####### - //############################################## - - //////////Epsilon/////////// - float epsilon; //Epsilon used for transitive closure - - //////Visit Table////// - unsigned char *visitTable; //Table used to keep track of which pixels have been - //already visited upon computing the boundary edge strengths - - //########################################## - //####### IMAGE PRUNING ######## - //########################################## - - ////////Transitive Closure///////// - float rR2; //defines square range radius used when clustering pixels - //together, thus defining image regions - - float speedThreshold; // the % of window radius used in new optimized filter 2. -}; - -#endif diff --git a/Modules/ThirdParty/Edison/src/otbedison/msSys.cpp b/Modules/ThirdParty/Edison/src/otbedison/msSys.cpp deleted file mode 100644 index 4523170e75fb38b8fa21470e3c2ce8d3e0823403..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/msSys.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Mean Shift System: - ================== - - The Mean Shift System class provides a mechanism for the - mean shift library classes to prompt progress and to - time its computations. When porting the mean shift library - to an application the methods of this class may be changed - such that the output of the mean shift class prompts - will be given to whatever hardware or software device that - is desired. - - The definition for the mean shift system class is provided - below. Its prototype is provided in "msSys.cc". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -//include the msSystem class prototype -#include "msSys.h" - -//include needed system libraries -#include <time.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Class Constructor and Destructor ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Constructor */ -/*******************************************************/ -/*Constructs a mean shift system object. */ -/*******************************************************/ -/*Post: */ -/* - an msSystem object has been properly init- */ -/* ialized. */ -/*******************************************************/ - -msSystem::msSystem( void ) -{ - - //initialize currentTime - currentTime = clock(); - - //done. - -} - -/*******************************************************/ -/*Class Destructor */ -/*******************************************************/ -/*Destroys a mean shift system object. */ -/*******************************************************/ -/*Post: */ -/* - an msSystem object has been properly dest- */ -/* royed. */ -/*******************************************************/ - -msSystem::~msSystem( void ) -{ - /* do nothing */ -} - - /*/\/\/\/\/\/\/\/\/\*/ - /*** System Timer ***/ - /*\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Start Timer */ -/*******************************************************/ -/*Sets the mean shift system time to the current */ -/*system time. */ -/*******************************************************/ -/*Post: */ -/* - the mean shift system time has been set to */ -/* the current system time. */ -/*******************************************************/ - -void msSystem::StartTimer( void ) -{ - - //set msSystem time to system time - currentTime = clock(); - - //done. - return; - -} - -/*******************************************************/ -/*Elapsed Time */ -/*******************************************************/ -/*Returns the amount of time in seconds since the */ -/*mean shift system time was last set. */ -/*******************************************************/ -/*Post: */ -/* - the amount of time in seconds since the mean */ -/* shift system time was last set is returned. */ -/*******************************************************/ - -double msSystem::ElapsedTime( void ) -{ - - //return the amount of time elapsed in seconds - //since the msSystem time was last set... - return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC); - -} - - /*/\/\/\/\/\/\/\/\/\/\*/ - /*** System Output ***/ - /*\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Prompt */ -/*******************************************************/ -/*Output a text message to the user. */ -/*******************************************************/ -/*Pre: */ -/* - PromptStr is a string containing delimeters */ -/* that is to be output to the user. */ -/* - a variable set of arguments is also passed */ -/* to this method that are used to replace */ -/* the delimeters contained by PromptStr */ -/*Post: */ -/* - the delimeters of PromptStr have been */ -/* replaced accordingly using the variable */ -/* set of arguments and the resulting string */ -/* has been output to the user. */ -/*******************************************************/ - -extern void bgLogVar(const char *, va_list); - -void msSystem::Prompt(const char *PromptStr, ...) -{ - - //obtain argument list using ANSI standard... - va_list argList; - va_start(argList, PromptStr); - - //print the output string to stderr using - //vfprintf - bgLogVar(PromptStr, argList); - va_end(argList); - - //done. - return; - -} - -/*******************************************************/ -/*Progress */ -/*******************************************************/ -/*The progress of a specific algorithm of the mean */ -/*shift library is output to the user. */ -/*******************************************************/ -/*Pre: */ -/* - percentComplete indicates the percentage */ -/* of the algorithm that has executed and is */ -/* a floating point number from zero to one */ -/*Post: */ -/* - the percentComplete has been noted by the */ -/* interface (possibly to update a progress */ -/* bar). */ -/* - if the thread executing the mean shift code */ -/* must halt execution msSYS_HALT is returned, */ -/* msSYS_OK is returned otherwise */ -/*******************************************************/ - -/////////////////////////////////////////////////////////////////// -//NOTE: This implementation is specific to EDISON. In order -// for one to port the mean shift class to another project -// or program one must re-implement this method. -/////////////////////////////////////////////////////////////////// - -//is set by the GUI when the user presses the Cancel button -//on the wxWindows progress modal window; this flag indicates -//to the mean shift library that it is to halt execution. -//This parameter is used and checked in the method -//BgMdiSegmentChild::OnSegment. -extern bool stop_flag; - -//is updated in the msSystem::Progress method and indicates to -//the wxWindows progress modal window the percent complete, such -//that it may update its progress bar accordingly; This parameter -//is used and checked in the method BgMdiSegmentChild::OnSegment. -extern int percentDone; - -ErrorLevel msSystem::Progress(float percentComplete) -{ - percentDone = (int)(percentComplete*100); - - //check stop flag and return appropriate system state - ErrorLevel myState = EL_OKAY; - if(stop_flag) myState = EL_HALT; - - //done. - return myState; - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ diff --git a/Modules/ThirdParty/Edison/src/otbedison/msSys.h b/Modules/ThirdParty/Edison/src/otbedison/msSys.h deleted file mode 100644 index d7411b0941661bcc318a9bc5516facf7483e5a0b..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/msSys.h +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Mean Shift System: - ================== - - The Mean Shift System class provides a mechanism for the - mean shift library classes to prompt progress and to - time its computations. When porting the mean shift library - to an application the methods of this class may be changed - such that the output of the mean shift class prompts - will be given to whatever hardware or software device that - is desired. - - The prototype for the mean shift system class is provided - below. Its defition is provided in "msSys.cc". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - - -#ifndef MSSYS_H -#define MSSYS_H - -//Include standard mean shift library type definitions -#include "tdef.h" - -//Include standard libraries needed for msSystem prototype -#include <time.h> - -extern void bgLogFile(const char*, ...); - -//Mean Shify System class prototype -class msSystem { - - public: - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - msSystem( void ); //Default Constructor - ~msSystem( void ); //Class Destructor - - /*/\/\/\/\/\/\/\*/ - /* System Timer */ - /*\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Start Timer * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Initializes the system timer. The timer object |// - //| synthesized by this class is initialized during |// - //| construction of the msSystem class to be the |// - //| current time during construction. |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void StartTimer( void ); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Elapsed Time * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the amount of time elapsed in seconds |// - //| from when StartTimer() was called. If |// - //| StartTimer() was not called, the time returned |// - //| is the time elapsed from the construction of the |// - //| msSystem object. |// - //| |// - //| In order to create a valid kernel the following |// - //| argumens must be provided this method: |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| TimeInSeconds = ElapsedTime() |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - double ElapsedTime( void ); - - /*/\/\/\/\/\/\/\/\*/ - /* System Output */ - /*\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Prompt * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Outputs to a device a character message contain- |// - //| ing delimeters. These delimeters are replaced by |// - //| the variable input parameters passed to prompt. |// - //| (Like printf.) |// - //| |// - //| This method should be altered if a special |// - //| device either than stderr is desired to be used |// - //| as an output prompt. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* PromptStr *> |// - //| A string possibly containing delimeters that |// - //| is to be output to the user. |// - //| |// - //| <* varArgs *> |// - //| A variable set of arguments to be placed into |// - //| the prompt string. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| Prompt(PromptStr, varArgs) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void Prompt(const char*, ...); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Progress * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| This method is called by the mean shift library |// - //| methods during the application of a specific |// - //| algorithm in which the progress of the algorithm |// - //| is indicated. Its main use is for a multi-thre- |// - //| aded programming envioronment. Namely, it is |// - //| called fairly frequently by the mean shift |// - //| library methods. It then can be used to grace- |// - //| fully halt the algorithm, or to simply update |// - //| a progress bar. |// - //| |// - //| This method depends strongly on the interface |// - //| and therefore must be re-implemented to accom- |// - //| odate ones needs. |// - //| |// - //| To facilitate a multi-threaded enviornment |// - //| the prompt function returns a value that |// - //| indicates to the mean shift method whether |// - //| to continue execution. EL_HALT is returned |// - //| when the mean shift procedure is to stop |// - //| execution and EL_OKAY is returned otherwise. |// - //| |// - //| The arguments to this method are: |// - //| |// - //| <* PercentComplete *> |// - //| A floating point number that indicates the perc- |// - //| ent complete of the algorithm. PercentComplete |// - //| takes a value between zero and one. |// - //| |// - //| <* SystemState *> |// - //| Indicates the system state. It is EL_HALT |// - //| when the mean shift method is to halt execution |// - //| and it is EL_OKAY otherwise. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| SystemState = Progress(PercentComplete) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - ErrorLevel Progress(float); - - private: - - //Timer object... - time_t currentTime; - -}; - -#endif diff --git a/Modules/ThirdParty/Edison/src/otbedison/msSysPrompt.cpp b/Modules/ThirdParty/Edison/src/otbedison/msSysPrompt.cpp deleted file mode 100644 index c3cabf78502400f22553c25c788e67032e052569..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/msSysPrompt.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Mean Shift System: - ================== - - The Mean Shift System class provides a mechanism for the - mean shift library classes to prompt progress and to - time its computations. When porting the mean shift library - to an application the methods of this class may be changed - such that the output of the mean shift class prompts - will be given to whatever hardware or software device that - is desired. - - The definition for the mean shift system class is provided - below. Its prototype is provided in "msSys.cc". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -//////////////////////////////////////////////////////////////////////// -// Command Line Version: -// This version of mean shift system is written for the command -// line version of EDISON. -//////////////////////////////////////////////////////////////////////// - -//include the msSystem class prototype -#include "msSys.h" - -//include needed system libraries -#include <time.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -//define bgLog - -/* - * OrfeoToolbox removed to avoid dependency over CmCDisplayProgress - * -extern bool CmCDisplayProgress; -void bgLog(const char *PromptStr, ...) -{ - //obtain argument list using ANSI standard... - va_list argList; - va_start(argList, PromptStr); - - //print the output string to stderr using - if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList); - va_end(argList); - - //done. - return; -} -*/ - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Class Constructor and Destructor ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Class Constructor */ -/*******************************************************/ -/*Constructs a mean shift system object. */ -/*******************************************************/ -/*Post: */ -/* - an msSystem object has been properly init- */ -/* ialized. */ -/*******************************************************/ - -msSystem::msSystem( void ) -{ - - //initialize currentTime - currentTime = clock(); - - //done. - -} - -/*******************************************************/ -/*Class Destructor */ -/*******************************************************/ -/*Destroys a mean shift system object. */ -/*******************************************************/ -/*Post: */ -/* - an msSystem object has been properly dest- */ -/* royed. */ -/*******************************************************/ - -msSystem::~msSystem( void ) -{ - /* do nothing */ -} - - /*/\/\/\/\/\/\/\/\/\*/ - /*** System Timer ***/ - /*\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Start Timer */ -/*******************************************************/ -/*Sets the mean shift system time to the current */ -/*system time. */ -/*******************************************************/ -/*Post: */ -/* - the mean shift system time has been set to */ -/* the current system time. */ -/*******************************************************/ - -void msSystem::StartTimer( void ) -{ - - //set msSystem time to system time - currentTime = clock(); - - //done. - return; - -} - -/*******************************************************/ -/*Elapsed Time */ -/*******************************************************/ -/*Returns the amount of time in seconds since the */ -/*mean shift system time was last set. */ -/*******************************************************/ -/*Post: */ -/* - the amount of time in seconds since the mean */ -/* shift system time was last set is returned. */ -/*******************************************************/ - -double msSystem::ElapsedTime( void ) -{ - - //return the amount of time elapsed in seconds - //since the msSystem time was last set... - return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC); - -} - - /*/\/\/\/\/\/\/\/\/\/\*/ - /*** System Output ***/ - /*\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Prompt */ -/*******************************************************/ -/*Output a text message to the user. */ -/*******************************************************/ -/*Pre: */ -/* - PromptStr is a string containing delimeters */ -/* that is to be output to the user. */ -/* - a variable set of arguments is also passed */ -/* to this method that are used to replace */ -/* the delimeters contained by PromptStr */ -/*Post: */ -/* - the delimeters of PromptStr have been */ -/* replaced accordingly using the variable */ -/* set of arguments and the resulting string */ -/* has been output to the user. */ -/*******************************************************/ - -void msSystem::Prompt(const char *PromptStr, ...) -{ - /* - * OrfeoToolbox removed to avoid dependency over CmCDisplayProgress - * - - //obtain argument list using ANSI standard... - va_list argList; - va_start(argList, PromptStr); - - //print the output string to stderr using - if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList); - va_end(argList); - - //done. - - */ - return; - -} - -/*******************************************************/ -/*Progress */ -/*******************************************************/ -/*The progress of a specific algorithm of the mean */ -/*shift library is output to the user. */ -/*******************************************************/ -/*Pre: */ -/* - percentComplete indicates the percentage */ -/* of the algorithm that has executed and is */ -/* a floating point number from zero to one */ -/*Post: */ -/* - the percentComplete has been noted by the */ -/* interface (possibly to update a progress */ -/* bar). */ -/* - if the thread executing the mean shift code */ -/* must halt execution msSYS_HALT is returned, */ -/* msSYS_OK is returned otherwise */ -/*******************************************************/ - -/////////////////////////////////////////////////////////////////// -//NOTE: This implementation is specific to EDISON. In order -// for one to port the mean shift class to another project -// or program one must re-implement this method. -/////////////////////////////////////////////////////////////////// - -ErrorLevel msSystem::Progress(float percentComplete) -{ - return EL_OKAY; -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ diff --git a/Modules/ThirdParty/Edison/src/otbedison/rlist.cpp b/Modules/ThirdParty/Edison/src/otbedison/rlist.cpp deleted file mode 100644 index 3b0da9dae1d8781efd757c37e0764198717a9276..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/rlist.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Region List Class: - ================= - - During segmentation, data regions are defined. The - RegionList class provides a mechanism for doing so, as - well as defines some basic operations, such as region - growing or small region pruning, on the defined regions. - It is defined below. Its prototype is given in "region.h". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - - -#include "rlist.h" -#include <stdio.h> -#include <stdlib.h> - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Class Constructor and Destructor ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Constructor */ -/*******************************************************/ -/*Constructor */ -/*******************************************************/ -/*Pre: */ -/* - modesPtr is a pointer to an array of modes */ -/* - maxRegions_ is the maximum number of regions */ -/* that can be defined */ -/* - L_ is the number of data points being class- */ -/* ified by the region list class */ -/* - N is the dimension of the data set being cl- */ -/* assified by the region list class */ -/*Post: */ -/* - a region list object has been properly init- */ -/* ialized. */ -/*******************************************************/ - -RegionList::RegionList(int maxRegions_, int L_, int N_) -{ - - //Obtain maximum number of regions that can be - //defined by user - if((maxRegions = maxRegions_) <= 0) - ErrorHandler("RegionList", "Maximum number of regions is zero or negative.", FATAL); - - //Obtain dimension of data set being classified by - //region list class - if((N = N_) <= 0) - ErrorHandler("RegionList", "Dimension is zero or negative.", FATAL); - - //Obtain length of input data set... - if((L = L_) <= 0) - ErrorHandler("RegionList", "Length of data set is zero or negative.", FATAL); - - //Allocate memory for index table - if(!(indexTable = new int [L])) - ErrorHandler("RegionList", "Not enough memory.", FATAL); - - //Allocate memory for region list array - if(!(regionList = new REGION [maxRegions])) - ErrorHandler("RegionList", "Not enough memory.", FATAL); - - //Initialize region list... - numRegions = freeRegion = 0; - - //Initialize indexTable - freeBlockLoc = 0; - - //done. - return; - -} - -/*******************************************************/ -/*Destructor */ -/*******************************************************/ -/*Destroys region list object. */ -/*******************************************************/ -/*Post: */ -/* - region list object has been properly dest- */ -/* oyed. */ -/*******************************************************/ - -RegionList::~RegionList( void ) -{ - //de-allocate memory... - delete [] regionList; - delete [] indexTable; - - //done. - return; -} - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /*** Region List Manipulation ***/ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Add Region */ -/*******************************************************/ -/*Adds a region to the region list. */ -/*******************************************************/ -/*Pre: */ -/* - label is a positive integer used to uniquely */ -/* identify a region */ -/* - pointCount is the number of N-dimensional */ -/* data points that exist in the region being */ -/* classified. */ -/* - indeces is a set of indeces specifying the */ -/* data points contained within this region */ -/* - pointCount must be > 0 */ -/*Post: */ -/* - a new region labeled using label and contai- */ -/* ning pointCount number of points has been */ -/* added to the region list. */ -/*******************************************************/ - -void RegionList::AddRegion(int label, int pointCount, int *indeces) -{ - - //make sure that there is enough room for this new region - //in the region list array... - if(numRegions >= maxRegions) - ErrorHandler("AddRegion", "Not enough memory allocated.", FATAL); - - //make sure that label is positive and point Count > 0... - if((label < 0)||(pointCount <= 0)) - ErrorHandler("AddRegion", "Label is negative or number of points in region is invalid.", FATAL); - - //make sure that there is enough memory in the indexTable - //for this region... - if((freeBlockLoc + pointCount) > L) - ErrorHandler("AddRegion", "Adding more points than what is contained in data set.", FATAL); - - //place new region into region list array using - //freeRegion index - regionList[freeRegion].label = label; - regionList[freeRegion].pointCount = pointCount; - regionList[freeRegion].region = freeBlockLoc; - - //copy indeces into indexTable using freeBlock... - int i; - for(i = 0; i < pointCount; i++) - indexTable[freeBlockLoc+i] = indeces[i]; - - //increment freeBlock to point to the next free - //block - freeBlockLoc += pointCount; - - //increment freeRegion to point to the next free region - //also, increment numRegions to indicate that another - //region has been added to the region list - freeRegion++; - numRegions++; - - //done. - return; - -} - -/*******************************************************/ -/*Reset */ -/*******************************************************/ -/*Resets the region list. */ -/*******************************************************/ -/*Post: */ -/* - the region list has been reset. */ -/*******************************************************/ - -void RegionList::Reset( void ) -{ - - //reset region list - freeRegion = numRegions = freeBlockLoc = 0; - - //done. - return; - -} - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Query Region List */ - /*\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Get Number Regions */ -/*******************************************************/ -/*Returns the number of regions stored by region list. */ -/*******************************************************/ -/*Post: */ -/* - the number of regions stored by the region */ -/* list is returned. */ -/*******************************************************/ - -int RegionList::GetNumRegions( void ) -{ - // return region count - return numRegions; -} - -/*******************************************************/ -/*Get Label */ -/*******************************************************/ -/*Returns the label of a specified region. */ -/*******************************************************/ -/*Pre: */ -/* - regionNum is an index into the region list */ -/* array. */ -/*Post: */ -/* - the label of the region having region index */ -/* specified by regionNum has been returned. */ -/*******************************************************/ - -int RegionList::GetLabel(int regionNum) -{ - //return the label of a specified region - return regionList[regionNum].label; -} - -/*******************************************************/ -/*Get Region Count */ -/*******************************************************/ -/*Returns the point count of a specified region. */ -/*******************************************************/ -/*Pre: */ -/* - regionNum is an index into the region list */ -/* array. */ -/*Post: */ -/* - the number of points that classify the */ -/* region whose index is specified by regionNum */ -/* is returned. */ -/*******************************************************/ - -int RegionList::GetRegionCount(int regionNum) -{ - //return the region count of a specified region - return regionList[regionNum].pointCount; -} - -/*******************************************************/ -/*Get Region Indeces */ -/*******************************************************/ -/*Returns the point indeces specifying a region. */ -/*******************************************************/ -/*Pre: */ -/* - regionNum is an index into the region list */ -/* array. */ -/*Post: */ -/* - the region indeces specifying the points */ -/* contained by the region specified by region- */ -/* Num are returned. */ -/*******************************************************/ - -int *RegionList::GetRegionIndeces(int regionNum) -{ - //return point indeces using regionNum - return &indexTable[regionList[regionNum].region]; -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PRIVATE METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Error Handler */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - -/*******************************************************/ -/*Error Handler */ -/*******************************************************/ -/*Class error handler. */ -/*******************************************************/ -/*Pre: */ -/* - functName is the name of the function that */ -/* caused an error */ -/* - errmsg is the error message given by the */ -/* calling function */ -/* - status is the error status: FATAL or NON- */ -/* FATAL */ -/*Post: */ -/* - the error message errmsg is flagged on beh- */ -/* ave of function functName. */ -/* - if the error status is FATAL then the program*/ -/* is halted, otherwise execution is continued, */ -/* error recovery is assumed to be handled by */ -/* the calling function. */ -/*******************************************************/ - -void RegionList::ErrorHandler(char *functName, char* errmsg, ErrorType status) -{ - - //flag error message on behalf of calling function, error format - //specified by the error status... - if(status == NONFATAL) - fprintf(stderr, "\n%s Error: %s\n", functName, errmsg); - else - { - fprintf(stderr, "\n%s Fatal Error: %s\n\nAborting Program.\n\n", functName, errmsg); - exit(1); - } - -} - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ diff --git a/Modules/ThirdParty/Edison/src/otbedison/rlist.h b/Modules/ThirdParty/Edison/src/otbedison/rlist.h deleted file mode 100644 index 55bb67ce2353b9f42fc29656491ccea18b6fc7ff..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/rlist.h +++ /dev/null @@ -1,337 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Region List Class: - ================= - - During segmentation, data regions are defined. The - RegionList class provides a mechanism for doing so, as - well as defines some basic operations, such as region - growing or small region pruning, on the defined regions. - The prototype for the RegionList class is provided below. It - is defined in "region.cc". - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -#ifndef RLIST_H -#define RLIST_H - -//include global type definitions -#include "tdef.h" - -//define region structure -struct REGION { - int label; - int pointCount; - int region; - -}; - -//region class prototype... -class RegionList { - -public: - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Constructor and Destructor */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Class Constructor * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Constructs a region list object. |// - //| |// - //| Its arguments are: |// - //| |// - //| <* maxRegions *> |// - //| The maximum amount of regions that can be class- |// - //| ified by the region list. |// - //| |// - //| <* L *> |// - //| The length of the input data set being class- |// - //| ified by the region list object. |// - //| |// - //| <* N *> |// - //| The dimension of the input data set being class- |// - //| ified by the region list object. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| RegionList(maxRegions, L, N) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - RegionList(int, int, int); - - // Class Destructor - ~RegionList( void ); - - /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ - /* Region List Manipulation */ - /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Add Region * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Adds a region to the region list. |// - //| |// - //| Its arguments are: |// - //| |// - //| <* label *> |// - //| |// - //| A positive integer used to uniquely identify |// - //| a region. |// - //| |// - //| <* pointCount *> |// - //| A positive integer that specifies the number of |// - //| N-dimensional data points that exist in the re- |// - //| gion being classified. |// - //| |// - //| <* indeces *> |// - //| An integer array that specifies the set of ind- |// - //| eces of the data points that are contianed with- |// - //| in this region. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| AddRegion(label, pointCount, indeces) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void AddRegion(int, int, int*); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Reset * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Resets the region list for re-use (for new |// - //| classification). |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - void Reset( void ); - - /*/\/\/\/\/\/\/\/\/\/\*/ - /* Query Region List */ - /*\/\/\/\/\/\/\/\/\/\/*/ - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Number of Regions * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the number of regions stored by the |// - //| region list. |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - int GetNumRegions ( void ); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Label * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns the label of a specified region. |// - //| |// - //| Its arguments are: |// - //| |// - //| <* regionNumber *> |// - //| The index of the region in the region list |// - //| array. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| label = GetLabel(regionNumber) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - int GetLabel(int); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Region Count * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns number of data points contained by a sp- |// - //| ecified region. |// - //| |// - //| Its arguments are: |// - //| |// - //| <* regionNumber *> |// - //| The index of the region in the region list |// - //| array. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| pointCount = GetRegionCount(regionNumber) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - int GetRegionCount(int); - - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - //<--------------------------------------------------->|// - //| |// - //| Method Name: |// - //| ============ |// - //| * Get Region Indeces * |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Description: |// - //| ============ |// - //| |// - //| Returns a pointer to a set of grid location ind- |// - //| eces specifying the data points belonging to a |// - //| specified region. |// - //| |// - //| Its arguments are: |// - //| |// - //| <* regionNumber *> |// - //| The index of the region in the region list |// - //| array. |// - //| |// - //<--------------------------------------------------->|// - //| |// - //| Usage: |// - //| ====== |// - //| indeces = GetRegionIndeces(regionNumber) |// - //| |// - //<--------------------------------------------------->|// - //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// - - int*GetRegionIndeces(int); - -private: - - /*/\/\/\/\/\/\/\/\/\/\/\*/ - /* Class Error Handler */ - /*\/\/\/\/\/\/\/\/\/\/\/*/ - - void ErrorHandler(char*, char*, ErrorType); - - //============================= - // *** Private Data Members *** - //============================= - - //##################################### - //### REGION LIST PARTITIONED ARRAY ### - //##################################### - - REGION *regionList; //array of maxRegions regions - int minRegion; - - int maxRegions; //defines the number maximum number of regions - //allowed (determined by user during class construction) - int numRegions; //the number of regions currently stored by the - //region list - int freeRegion; //an index into the regionList pointing to the next - //available region in the regionList - - //##################################### - //### INDEX TABLE ### - //##################################### - - int *indexTable; //an array of indexes that point into an external structure - //specifying which points belong to a region - int freeBlockLoc; //points to the next free block of memory in the indexTable - - //##################################### - //### INPUT DATA PARAMETERS ### - //##################################### - - //Dimension of data set - int N; //dimension of data set being classified by region list - //class - - //Length of the data set - int L; //number of points contained by the data set being classified by - //region list class - -}; - -#endif - - - diff --git a/Modules/ThirdParty/Edison/src/otbedison/tdef.h b/Modules/ThirdParty/Edison/src/otbedison/tdef.h deleted file mode 100644 index 9b225b3b84a5fae9504701c5a77e5cf9069d3c91..0000000000000000000000000000000000000000 --- a/Modules/ThirdParty/Edison/src/otbedison/tdef.h +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************* - - Mean Shift Analysis Library - ============================================= - - The mean shift library is a collection of routines - that use the mean shift algorithm. Using this algorithm, - the necessary output will be generated needed - to analyze a given input set of data. - - Type Defintions: - =============== - - This header file contains the type defintions and - enumerations shared among the various classes of the mean - shift library. - -The theory is described in the papers: - - D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature - space analysis. - - C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. - -and they are is available at: - http://www.caip.rutgers.edu/riul/research/papers/ - -Implemented by Chris M. Christoudias, Bogdan Georgescu -********************************************************/ - -#ifndef TDEF_H -#define TDEF_H - -/*/\/\/\/\/\/\/\/\/\/\/\*/ -/* Define Enumerations */ -/*\/\/\/\/\/\/\/\/\/\/\/*/ - -//Kernel -enum kernelType {Uniform, Gaussian, UserDefined}; - -// kd-Tree -enum childType {LEFT, RIGHT}; - -// Speed Up Level -enum SpeedUpLevel {NO_SPEEDUP, MED_SPEEDUP, HIGH_SPEEDUP}; - -// Error Handler -enum ErrorLevel {EL_OKAY, EL_ERROR, EL_HALT}; -enum ErrorType {NONFATAL, FATAL}; - -#endif