diff --git a/CMake/FindShark.cmake b/CMake/FindShark.cmake index 59bef138f730718a535ef984deace363cf4f8a47..523f1ee7dcc4498927118bd6427ca906ffac9f11 100644 --- a/CMake/FindShark.cmake +++ b/CMake/FindShark.cmake @@ -97,25 +97,43 @@ if(SHARK_CONFIG_FILE) "${SHARK_VERSION_MAJOR}.${SHARK_VERSION_MINOR}.${SHARK_VERSION_PATCH}") endif() -set(SHARK_USE_OPENMP_matched) -#define SHARK_USE_OPENMP +# Check if Shark was built with OpenMP, CBLAS, DYNLIB, ... file(STRINGS "${SHARK_INCLUDE_DIR}/shark/Core/Shark.h" SHARK_H_CONTENTS) -string(REGEX MATCH - "#define.SHARK_USE_OPENMP" - SHARK_USE_OPENMP_matched "${SHARK_H_CONTENTS}") -if(SHARK_USE_OPENMP_matched) - if(NOT OTB_USE_OPENMP) - message(WARNING "Shark library is built with OpenMP and you have OTB_USE_OPENMP set to OFF.") - endif() +if(SHARK_H_CONTENTS MATCHES "#define.SHARK_USE_OPENMP") + set(SHARK_USE_OPENMP 1) +else() + set(SHARK_USE_OPENMP 0) +endif() + +if(SHARK_H_CONTENTS MATCHES "#define.SHARK_USE_CBLAS") + set(SHARK_USE_CBLAS 1) +else() + set(SHARK_USE_CBLAS 0) +endif() + +if(SHARK_H_CONTENTS MATCHES "#define.SHARK_USE_DYNLIB") + set(SHARK_USE_DYNLIB 1) +else() + set(SHARK_USE_DYNLIB 0) +endif() + +if(SHARK_USE_CBLAS AND SHARK_USE_DYNLIB) + set(REQUIRED_CBLAS_LIB CBLAS_LIBRARY) + find_library(CBLAS_LIBRARY NAMES cblas) +else() + set(REQUIRED_CBLAS_LIB) endif() INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Shark - REQUIRED_VARS SHARK_LIBRARY SHARK_INCLUDE_DIR + REQUIRED_VARS SHARK_LIBRARY SHARK_INCLUDE_DIR ${REQUIRED_CBLAS_LIB} VERSION_VAR SHARK_VERSION_STRING) if(SHARK_FOUND) set(SHARK_INCLUDE_DIRS ${SHARK_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ) set(SHARK_LIBRARIES ${SHARK_LIBRARY} ${Boost_LIBRARIES} ) + if(REQUIRED_CBLAS_LIB) + set(SHARK_LIBRARIES ${SHARK_LIBRARIES} ${CBLAS_LIBRARY}) + endif() endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index c5e1130921996b6eae49b4e01b1304fa4edda13a..dc4875285f1b32fc88dde006ea577391777444b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,10 +231,6 @@ mark_as_advanced(OTB_USE_DEPRECATED) option(OTB_USE_OPENMP "Add openmp compiler and linker flags" OFF) option(OTB_USE_SSE_FLAGS "Enable SIMD optimizations (hardware dependent)." ON) -#----------------------------------------------------------------------------- -# SHOW_ALL_MSG_DEBUG option -option(OTB_SHOW_ALL_MSG_DEBUG "Show all debug messages (very verbose)" OFF) -#mark_as_advanced(OTB_SHOW_ALL_MSG_DEBUG) include(OTBSetStandardCompilerFlags) #--------------------------------------------------------------- diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py index 70d55ce7c9490d4998b7db595130d0f917bf5576..7f0606992f8e5c461a1b53d6f1e4460f88141125 100755 --- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py +++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py @@ -95,7 +95,8 @@ def GenerateChoice(app,param,paramlist, count = 0): return output def GenerateParameterType(app,param): - if app.GetParameterType(param) == otbApplication.ParameterType_Empty: + if app.GetParameterType(param) == otbApplication.ParameterType_Empty \ + or app.GetParameterType(param) == otbApplication.ParameterType_Bool: return "Boolean" if app.GetParameterType(param) == otbApplication.ParameterType_Int \ or app.GetParameterType(param) == otbApplication.ParameterType_Radius \ @@ -346,6 +347,8 @@ def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outp if paramtype == otbApplication.ParameterType_Empty: app.EnableParameter(param) output+= "\t" + appname + ".EnableParameter("+EncloseString(param)+")" + linesep + if paramtype == otbApplication.ParameterType_Bool: + output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+","+EncloseString(value)+")" + linesep if paramtype == otbApplication.ParameterType_Int \ or paramtype == otbApplication.ParameterType_Radius \ or paramtype == otbApplication.ParameterType_RAM: diff --git a/Documentation/Cookbook/rst/ExtendedFilenames.rst b/Documentation/Cookbook/rst/AdvancedUse.rst similarity index 87% rename from Documentation/Cookbook/rst/ExtendedFilenames.rst rename to Documentation/Cookbook/rst/AdvancedUse.rst index 02b5512351958d0b5ae88f1de831e9c5c2f823cc..604380e57a96fd41d45411e905f6380256f6c21c 100644 --- a/Documentation/Cookbook/rst/ExtendedFilenames.rst +++ b/Documentation/Cookbook/rst/AdvancedUse.rst @@ -1,7 +1,24 @@ -.. _extended-filenames: +Advanced Use +============ + +This section describes advanced configuration options and tricks. + +Environment variables that affects Orfeo ToolBox +------------------------------------------------ + +The following environment variables are parsed by Orfeo ToolBox. Note +that they only affect default values, and that settings in extended +filenames, applications, monteverdi or custom C++ code might override +those values. + +* ``OTB_DEM_DIRECTORY``: Default directory were DEM tiles are stored. It should only contain ```.hgt`` or or georeferenced ``.tif`` files. Empty if not set (no directory set) +* ``OTB_GEOID_FILE``: Default path to the geoid file that will be used to retrieve height of DEM above ellipsoid. Empty if not set (no geoid set) +* ``OTB_MAX_RAM_HINT``: Default maximum memory that OTB should use for processing, in MB. If not set, default value is 128 MB. +* ``OTB_LOGGER_LEVEL``: Default level of logging for OTB. Should be one of ``DEBUG``, ``INFO``, ``WARNING``, ``CRITICAL`` or ``FATAL``, by increasing order of priority. Only messages with a higher priority than the level of logging will be displayed. If not set, default level is ``INFO``. Extended filenames -================================ +------------------ +.. _extended-filenames: Extended filenames is an interesting feature of OTB. With it, you can control several aspects of the beahvior of the OTB in the OTB-Applications or in our @@ -42,7 +59,6 @@ applications from the bash command line.** Reader options ^^^^^^^^^^^^^^ - :: &geom=<path/filename.geom> diff --git a/Documentation/Cookbook/rst/index_TOC.rst b/Documentation/Cookbook/rst/index_TOC.rst index 12565d1577bd6a9211449e2c9e71b2cf0ca291e6..126fc8debfbd713cdd752205ee33f49ba9b60dfd 100644 --- a/Documentation/Cookbook/rst/index_TOC.rst +++ b/Documentation/Cookbook/rst/index_TOC.rst @@ -8,7 +8,7 @@ Table of Contents Installation OTB-Applications Monteverdi - ExtendedFilenames + AdvancedUse Recipes Applications FAQ diff --git a/Documentation/Cookbook/rst/recipes/python.rst b/Documentation/Cookbook/rst/recipes/python.rst index cbb119372dab87e687c015f08f467ad9ac62f69a..f0b2e95f251d5e642a6eb6a1e6ad4c82328e703d 100644 --- a/Documentation/Cookbook/rst/recipes/python.rst +++ b/Documentation/Cookbook/rst/recipes/python.rst @@ -32,10 +32,10 @@ application, changing the algorithm at each iteration. print "Available applications: " print str( otbApplication.Registry.GetAvailableApplications() ) - # Let's create the application with codename "Smoothing" + # Let's create the application "Smoothing" app = otbApplication.Registry.CreateApplication("Smoothing") - # We print the keys of all its parameter + # We print the keys of all its parameters print app.GetParametersKeys() # First, we set the input image filename @@ -47,35 +47,45 @@ application, changing the algorithm at each iteration. print 'Running with ' + type + ' smoothing type' - # Here we configure the smoothing algorithm + # Now we configure the smoothing algorithm app.SetParameterString("type", type) - # Set the output filename, using the algorithm to differentiate the outputs + # Set the output filename, using the algorithm type to differentiate the outputs app.SetParameterString("out", argv[2] + type + ".tif") - # This will execute the application and save the output file + # This will execute the application and save the output to argv[2] app.ExecuteAndWriteOutput() +If you want to handle the parameters from a Python dictionary, you can use the +functions *SetParameters()* and *GetParameters()*. + +.. code-block:: python + + params = {"in":"myInput.tif", "type.mean.radius":4} + app.SetParameters(params) + params2 = app.GetParameters() + Numpy array processing ---------------------- -Input and output images to any OTB application in the form of numpy array is now possible in OTB python wrapping. -The python wrapping only exposes OTB ApplicationEngine module which allow to access existing C++ applications. +Input and output images to any OTB application in the form of NumPy array is now possible in OTB Python wrapping. +The Python wrapping only exposes OTB Application engine module (called *ApplicationEngine*) which allows to access existing C++ applications. Due to blissful nature of ApplicationEngine's loading mechanism no specific wrapping is required for each application. -Numpy extension to Python wrapping allows data exchange to application as an array rather than a disk file. -Ofcourse, it is possible to load an image from file and then convert to numpy array or just provide a file as earlier via +NumPy extension to Python wrapping allows data exchange to application as an array rather than a disk file. +Of course, it is possible to load an image from file and then convert it to NumPy +array or just provide a file as explained in the previous section via Application.SetParameterString(...). -This bridge that completes numpy and OTB makes it easy to plug OTB into any image processing chain via python code that uses -GIS/Image processing tools such as GDAL, GRASS GIS, OSSIM that can deal with numpy. - +The bridge between NumPy and OTB makes it easy to plug OTB into any image processing chain via Python code that uses +GIS/Image processing tools such as GDAL, GRASS GIS, OSSIM that can deal with NumPy. -Below code reads an input image using python pillow (PIL) and convert it to numpy array. This numpy array is -used an input to the application via *SetImageFromNumpyArray(...)* method. -The application used in this example is ExtractROI. After extracting -a small area the output image is taken as numpy array with *GetImageFromNumpyArray(...)* method thus avoid wiriting -output to a temporary file. +Below code reads an input image using Python Pillow library (fork of PIL) and convert it to +NumPy array. The NumPy array is used as an input to the application via +*SetImageFromNumpyArray(...)* method. The application used in this example is +ExtractROI. After extracting a small area the output image is taken as NumPy +array with *GetImageFromNumpyArray(...)* method thus avoid writing output to a +temporary file. :: @@ -105,7 +115,7 @@ In-memory connection -------------------- Applications are often use as parts of larger processing -chains. Chaining applications currently requires to write/read back +workflow. Chaining applications currently requires to write/read back images between applications, resulting in heavy I/O operations and a significant amount of time dedicated to writing temporary files. @@ -118,9 +128,9 @@ images. The last application of the processing chain is responsible for writing the final result images. In-memory connection between applications is available both at the C++ -API level and using the python bindings. +API level and using the Python bindings. -Here is a Python code sample connecting several applications together: +Here is a Python code sample which connects several applications together: .. code-block:: python @@ -167,7 +177,7 @@ Corner cases ------------ There are a few corner cases to be aware of when using Python wrappers. They are -often limitations, that one day may be solved by future developments. If it +often limitations, that one day may be solved in future versions. If it happens, this documentation will report the OTB version that fixes the issue. Calling UpdateParameters() @@ -211,30 +221,34 @@ setting the ``field`` parameter: app.UpdateParameters() app.SetParameterString("field", "label") -No metadata in Numpy arrays +No metadata in NumPy arrays ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -With the Numpy module, it is possible to convert images between OTB and Numpy -arrays. For instance, when converting from OTB to Numpy array: +With the NumPy module, it is possible to convert images between OTB and NumPy +arrays. For instance, when converting from OTB to NumPy array: * An ``Update()`` of the underlying ``otb::VectorImage`` is requested. Be aware that the full image is generated. * The pixel buffer is copied into a ``numpy.array`` As you can see, there is no export of the metadata, such as origin, spacing, -projection WKT. It means that if you want to import back a Numpy array into OTB, +geographic projection. It means that if you want to import back a NumPy array into OTB, the image won't have any of these metadata. It can be a problem for applications doing geometry, projections, and also calibration. Future developments will probably offer a more adapted structure to import and -export images between OTB and Python world. +export images between OTB and the Python world. + +Setting of EmptyParameter +^^^^^^^^^^^^^^^^^^^^^^^^^ -Setting of boolean parameters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Most of the parameters are set using functions ``SetParameterXXX()``, except for +one type of parameter: the ``EmptyParameter``. This class was the first +implementation of a boolean. It is now **deprecated**, you should use ``BoolParameter`` +instead. -Most of the parameters are set using functions ``SetParameterXXX()``. The boolean -parameters are handled differently (also called Empty parameter). Let's take an example with the application -``ReadImageInfo``: +Let's take an example with the application ``ReadImageInfo`` when it was still +using an ``EmptyParameter`` for parameter ``keywordlist``: .. code-block:: python @@ -247,7 +261,7 @@ If you want the get the state of parameter ``keywordlist``, a boolean, use: app.IsParameterEnabled("keywordlist") -To set this parameter ON / OFF, use the functions: +To set this parameter ON/OFF, use the functions: .. code-block:: python diff --git a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx index 6063915cfb4996895de1371735454092f81368d7..0294d5f74408c9828958a2aab1b679d6c6ca1fe2 100644 --- a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx +++ b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx @@ -241,8 +241,6 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag) if (projection) { - otbMsgDevMacro(<< "OSSIM plugin projection instantiated ! "); - hasMetaData = projection->saveState(geom_kwl); otb_kwl.SetKeywordlist(geom_kwl); } @@ -257,7 +255,6 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag) ->open(ossimFilename(filename.c_str()))); if (handler) { - otbMsgDevMacro(<< "OSSIM Open Image SUCCESS ! "); // Add ossimPlugins model ossimProjectionFactoryRegistry::instance()->registerFactory(ossimplugins::ossimPluginProjectionFactory::instance()); @@ -273,7 +270,6 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag) // if the handler has found a sensor model, copy the tags found if (hasMetaData && dynamic_cast<ossimSensorModel const*>(projection)) { - otbMsgDevMacro(<<"OSSIM sensor projection instantiated ! "); otb_kwl.SetKeywordlist(geom_kwl); // geom_kwl.print(std::cout); } @@ -317,16 +313,6 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag) // which uses ossimSensorModelFactory and ossimPluginProjectionFactory internally, // thus by-passing the need for a valid ossimImageHandler. - if (!hasMetaData) - { - otbMsgDevMacro(<< "OSSIM MetaData not present ! "); - } - else - { - otbMsgDevMacro(<< "OSSIM MetaData present ! "); - //otbMsgDevMacro(<< geom_kwl); - } - return otb_kwl; } @@ -479,7 +465,6 @@ WriteGeometry(const ImageKeywordlist& otb_kwl, const std::string& filename) if (geom_kwl.getSize() > 0) { - otbMsgDevMacro(<< "Exporting keywordlist ..."); ossimFilename geomFileName(filename); geomFileName.setExtension(".geom"); geom_kwl.write(geomFileName.chars()); diff --git a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx index c5b0262be43c83ff560ec97ea3a418411ef5d17f..269a6f5bf5b7f9525380233d3a5414f6c9a82948 100644 --- a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx +++ b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx @@ -92,7 +92,7 @@ private: SetParameterDescription("ip.radius", "The radius of the ball shaped structuring element (expressed in pixels). By default, 'ip.radius = 1 pixel'."); SetDefaultParameterInt("ip.radius", 1.0); - AddParameter(ParameterType_Empty, "ip.suvbool", "Multiple majority: Undecided(X)/Original"); + AddParameter(ParameterType_Bool, "ip.suvbool", "Multiple majority: Undecided(X)/Original"); SetParameterDescription("ip.suvbool", "Pixels with more than 1 majority class are marked as Undecided if this parameter is checked (true), or keep their Original labels otherwise (false). Please note that the Undecided value must be different from existing labels in the input labeled image. By default, 'ip.suvbool = false'."); AddParameter(ParameterType_Int, "ip.nodatalabel", "Label for the NoData class"); @@ -103,7 +103,7 @@ private: SetParameterDescription("ip.undecidedlabel", "Label for the Undecided class. By default, 'ip.undecidedlabel = 0'."); SetDefaultParameterInt("ip.undecidedlabel", 0.0); - AddParameter(ParameterType_Empty, "ip.onlyisolatedpixels", "Process isolated pixels only"); + AddParameter(ParameterType_Bool, "ip.onlyisolatedpixels", "Process isolated pixels only"); SetParameterDescription("ip.onlyisolatedpixels", "Only pixels whose label is unique in the neighbordhood will be processed. By default, 'ip.onlyisolatedpixels = false'."); AddParameter(ParameterType_Int, "ip.isolatedthreshold", "Threshold for isolated pixels"); @@ -153,7 +153,7 @@ private: m_NeighMajVotingFilter->SetLabelForUndecidedPixels(GetParameterInt("ip.undecidedlabel")); // Set to Undecided label if NOT unique Majority Voting - if (IsParameterEnabled("ip.suvbool")) + if (GetParameterInt("ip.suvbool")) { m_NeighMajVotingFilter->SetKeepOriginalLabelBool(false); } @@ -164,7 +164,7 @@ private: } // Process isolated pixels only - if (IsParameterEnabled("ip.onlyisolatedpixels")) + if (GetParameterInt("ip.onlyisolatedpixels")) { m_NeighMajVotingFilter->SetOnlyIsolatedPixels(true); m_NeighMajVotingFilter->SetIsolatedThreshold(GetParameterInt("ip.isolatedthreshold")); diff --git a/Modules/Applications/AppClassification/app/otbDSFuzzyModelEstimation.cxx b/Modules/Applications/AppClassification/app/otbDSFuzzyModelEstimation.cxx index e6343bf4b9654a41b82317f7c8d6412b87e2e940..336c447c2a2a3214f185a765b0344b5f0d0fb021 100644 --- a/Modules/Applications/AppClassification/app/otbDSFuzzyModelEstimation.cxx +++ b/Modules/Applications/AppClassification/app/otbDSFuzzyModelEstimation.cxx @@ -143,12 +143,12 @@ private: AddParameter(ParameterType_String, "cri", "Criterion"); SetParameterDescription("cri", "Dempster Shafer criterion (by default (belief+plausibility)/2)"); MandatoryOff("cri"); - SetParameterString("cri","((Belief + Plausibility)/2.)", false); + SetParameterString("cri","((Belief + Plausibility)/2.)"); AddParameter(ParameterType_Float,"wgt","Weighting"); SetParameterDescription("wgt","Coefficient between 0 and 1 to promote undetection or false detections (default 0.5)"); MandatoryOff("wgt"); - SetParameterFloat("wgt",0.5, false); + SetParameterFloat("wgt",0.5); AddParameter(ParameterType_InputFilename,"initmod","initialization model"); SetParameterDescription("initmod","Initialization model (xml file) to be used. If the xml initialization model is set, the descriptor list is not used (specified using the option -desclist)"); @@ -157,16 +157,15 @@ private: AddParameter(ParameterType_StringList, "desclist","Descriptor list"); SetParameterDescription("desclist","List of the descriptors to be used in the model (must be specified to perform an automatic initialization)"); MandatoryOff("desclist"); - SetParameterString("desclist","", false); + SetParameterString("desclist",""); AddParameter(ParameterType_Int,"maxnbit","Maximum number of iterations"); MandatoryOff("maxnbit"); SetParameterDescription("maxnbit","Maximum number of optimizer iteration (default 200)"); - SetParameterInt("maxnbit",200, false); + SetParameterInt("maxnbit",200); - AddParameter(ParameterType_Empty,"optobs","Optimizer Observer"); + AddParameter(ParameterType_Bool,"optobs","Optimizer Observer"); SetParameterDescription("optobs","Activate the optimizer observer"); - MandatoryOff("optobs"); AddParameter(ParameterType_OutputFilename,"out","Output filename"); SetParameterDescription("out","Output model file name (xml file) contains the optimal model to perform information fusion."); @@ -405,7 +404,7 @@ private: // Create the Command observer and register it with the optimizer. CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - if (IsParameterEnabled("optobs")) + if (GetParameterInt("optobs")) { m_Optimizer->AddObserver(itk::IterationEvent(), observer); } diff --git a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx index a5067bf9cdb782b5dd2d70e25a43c23f7d41baa8..a5a44e6b4e1ad0f62248d0f879096657c3a6199c 100644 --- a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx +++ b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx @@ -59,11 +59,10 @@ protected: InitKMClassification(); // init at the end cleanup - AddParameter( ParameterType_Empty, "cleanup", "Temporary files cleaning" ); - EnableParameter( "cleanup" ); + AddParameter( ParameterType_Bool, "cleanup", "Temporary files cleaning" ); SetParameterDescription( "cleanup", "If activated, the application will try to clean all temporary files it created" ); - MandatoryOff( "cleanup" ); + SetParameterInt("cleanup", 1); } void InitKMSampling() @@ -148,7 +147,7 @@ protected: void ComputeImageEnvelope(const std::string &vectorFileName) { - GetInternalApplication("imgenvelop")->SetParameterString("out", vectorFileName, false); + GetInternalApplication("imgenvelop")->SetParameterString("out", vectorFileName); GetInternalApplication("imgenvelop")->ExecuteAndWriteOutput(); } @@ -187,8 +186,8 @@ protected: { std::vector<std::string> fieldList = {fieldName}; - GetInternalApplication("polystats")->SetParameterStringList("field", fieldList, false); - GetInternalApplication("polystats")->SetParameterString("out", statisticsFileName, false); + GetInternalApplication("polystats")->SetParameterStringList("field", fieldList); + GetInternalApplication("polystats")->SetParameterString("out", statisticsFileName); ExecuteInternal("polystats"); } @@ -199,17 +198,17 @@ protected: int NBSamples) { /* SampleSelection */ - GetInternalApplication("select")->SetParameterString("out", sampleFileName, false); + GetInternalApplication("select")->SetParameterString("out", sampleFileName); UpdateInternalParameters("select"); - GetInternalApplication("select")->SetParameterString("instats", statisticsFileName, false); - GetInternalApplication("select")->SetParameterString("field", fieldName, false); + GetInternalApplication("select")->SetParameterString("instats", statisticsFileName); + GetInternalApplication("select")->SetParameterString("field", fieldName); - GetInternalApplication("select")->SetParameterString("strategy", "constant", false); - GetInternalApplication("select")->SetParameterInt("strategy.constant.nb", NBSamples, false); + GetInternalApplication("select")->SetParameterString("strategy", "constant"); + GetInternalApplication("select")->SetParameterInt("strategy.constant.nb", NBSamples); if( IsParameterEnabled("rand")) - GetInternalApplication("select")->SetParameterInt("rand", GetParameterInt("rand"), false); + GetInternalApplication("select")->SetParameterInt("rand", GetParameterInt("rand")); // select sample positions ExecuteInternal("select"); @@ -217,8 +216,8 @@ protected: /* SampleExtraction */ UpdateInternalParameters("extraction"); - GetInternalApplication("extraction")->SetParameterString("outfield", "prefix", false); - GetInternalApplication("extraction")->SetParameterString("outfield.prefix.name", "value_", false); + GetInternalApplication("extraction")->SetParameterString("outfield", "prefix"); + GetInternalApplication("extraction")->SetParameterString("outfield.prefix.name", "value_"); // extract sample descriptors GetInternalApplication("extraction")->ExecuteAndWriteOutput(); @@ -229,7 +228,7 @@ protected: const std::string &modelFileName) { std::vector<std::string> extractOutputList = {sampleTrainFileName}; - GetInternalApplication("training")->SetParameterStringList("io.vd", extractOutputList, false); + GetInternalApplication("training")->SetParameterStringList("io.vd", extractOutputList); UpdateInternalParameters("training"); // set field names @@ -242,19 +241,19 @@ protected: oss << i; selectedNames.push_back( selectPrefix + oss.str() ); } - GetInternalApplication("training")->SetParameterStringList("feat", selectedNames, false); + GetInternalApplication("training")->SetParameterStringList("feat", selectedNames); - GetInternalApplication("training")->SetParameterString("classifier", "sharkkm", false); + GetInternalApplication("training")->SetParameterString("classifier", "sharkkm"); GetInternalApplication("training")->SetParameterInt("classifier.sharkkm.maxiter", - GetParameterInt("maxit"), false); + GetParameterInt("maxit")); GetInternalApplication("training")->SetParameterInt("classifier.sharkkm.k", - GetParameterInt("nc"), false); + GetParameterInt("nc")); if( IsParameterEnabled("rand")) - GetInternalApplication("training")->SetParameterInt("rand", GetParameterInt("rand"), false); + GetInternalApplication("training")->SetParameterInt("rand", GetParameterInt("rand")); GetInternalApplication("training")->GetParameterByKey("v")->SetActive(false); - GetInternalApplication("training")->SetParameterString("io.out", modelFileName, false); + GetInternalApplication("training")->SetParameterString("io.out", modelFileName); ExecuteInternal( "training" ); otbAppLogINFO("output model : " << GetInternalApplication("training")->GetParameterString("io.out")); @@ -264,8 +263,8 @@ protected: const std::string &imagesStatsFileName) { std::vector<std::string> imageFileNameList = {imageFileName}; - GetInternalApplication("imgstats")->SetParameterStringList("il", imageFileNameList, false); - GetInternalApplication("imgstats")->SetParameterString("out", imagesStatsFileName, false); + GetInternalApplication("imgstats")->SetParameterStringList("il", imageFileNameList); + GetInternalApplication("imgstats")->SetParameterString("out", imagesStatsFileName); ExecuteInternal( "imgstats" ); otbAppLogINFO("image statistics file : " << GetInternalApplication("imgstats")->GetParameterString("out")); @@ -497,7 +496,7 @@ private: Superclass::CreateOutMeansFile(GetParameterImage("in"), fileNames.modelFile, GetParameterInt("nc")); // Remove all tempory files - if( IsParameterEnabled( "cleanup" ) ) + if( GetParameterInt( "cleanup" ) ) { otbAppLogINFO( <<"Final clean-up ..." ); fileNames.clear(); @@ -506,7 +505,7 @@ private: void UpdateKMPolygonClassStatisticsParameters(const std::string &vectorFileName) { - GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName, false ); + GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName); UpdateInternalParameters( "polystats" ); } diff --git a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx index 889e909cc54301fb53eeb952783e9d1f4325fa20..85bed4e53ba73895d2619c590ed6b474718acac6 100644 --- a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx +++ b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx @@ -164,7 +164,7 @@ private: SetParameterDescription("strategy.all","Take all samples"); // Default strategy : smallest - SetParameterString("strategy","smallest", false); + SetParameterString("strategy","smallest"); AddParameter(ParameterType_Choice, "mim", "Multi-Image Mode"); diff --git a/Modules/Applications/AppClassification/app/otbOGRLayerClassifier.cxx b/Modules/Applications/AppClassification/app/otbOGRLayerClassifier.cxx index eb58a7e0ac4371d6c0fa4830f457bf36c11d426f..a29b0bc527a1d280f596177323e66bbfcfcd2140 100644 --- a/Modules/Applications/AppClassification/app/otbOGRLayerClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbOGRLayerClassifier.cxx @@ -82,7 +82,7 @@ private: AddParameter(ParameterType_String,"cfield","Field containing the predicted class."); SetParameterDescription("cfield","Field containing the predicted class"); - SetParameterString("cfield","predicted", false); + SetParameterString("cfield","predicted"); // Doc example parameter settings SetDocExampleParameterValue("inshp", "vectorData.shp"); diff --git a/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx b/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx index a9c2b07fbde06f288706a67fb9b7b999cb7de076..4c3d40b56077b7ad605758e92c59a76c9919ff74 100644 --- a/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx +++ b/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx @@ -89,7 +89,7 @@ private: AddParameter(ParameterType_String, "outfield.prefix.name", "Output field prefix"); SetParameterDescription("outfield.prefix.name","Prefix used to form the field names that" "will contain the extracted values."); - SetParameterString("outfield.prefix.name", "value_", false); + SetParameterString("outfield.prefix.name", "value_"); AddChoice("outfield.list","Use the given name list"); SetParameterDescription("outfield.list","Use the given name list"); diff --git a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx index b41f20470f2ac4fe5d2321011cc6c806a66ebb03..cd3542db8e2db78a0c8e0f4cf624e88ab62575ed 100644 --- a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx +++ b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx @@ -200,7 +200,7 @@ private: SetParameterDescription("strategy.all","Take all samples"); // Default strategy : smallest - SetParameterString("strategy","smallest", false); + SetParameterString("strategy","smallest"); AddParameter(ParameterType_ListView, "field", "Field Name"); SetParameterDescription("field","Name of the field carrying the class name in the input vectors."); diff --git a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx index a76f81dce73870d4d6820f4931999d5253e9fed5..7bdb39044373e59b0dadb11c84b64853181c438d 100644 --- a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx @@ -205,7 +205,7 @@ public: TrainModel( imageList, fileNames.sampleTrainOutputs, fileNames.sampleValidOutputs ); // cleanup - if( IsParameterEnabled( "cleanup" ) ) + if( GetParameterInt( "cleanup" ) ) { otbAppLogINFO( <<"Final clean-up ..." ); fileNames.clear(); @@ -217,7 +217,7 @@ private : void UpdatePolygonClassStatisticsParameters() { std::vector<std::string> vectorFileList = GetParameterStringList( "io.vd" ); - GetInternalApplication( "polystat" )->SetParameterString( "vec", vectorFileList[0], false ); + GetInternalApplication( "polystat" )->SetParameterString( "vec", vectorFileList[0]); UpdateInternalParameters( "polystat" ); } diff --git a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx index 690d03da1de8ad2a9388f36f11e1775d5ce9ce8f..9d22eb9d1afd45fe82224e62e57d6e7267f06e35 100644 --- a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx @@ -183,7 +183,7 @@ void DoInit() ITK_OVERRIDE SetParameterDescription( "sample.vtr" , "Ratio between training and validation samples (0.0 = all training, " "1.0 = all validation) (default = 0.5)."); - SetParameterFloat( "sample.vtr" , 0.5 , false ); + SetParameterFloat( "sample.vtr" , 0.5); Superclass::DoInit(); diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx index f37eb3020f4934146d3ad4cfa9d402c19d058026..c1f6a9456ddf2ad5c419464d3fb557a6c75ca470 100644 --- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx @@ -112,7 +112,7 @@ protected: contingencyTableCalculator->Compute(performanceLabeledListSample->Begin(), performanceLabeledListSample->End(),predictedListSample->Begin(), predictedListSample->End()); - if(IsParameterEnabled("v")) + if(GetParameterInt("v")) { otbAppLogINFO( "Training performances:" ); otbAppLogINFO(<<"Contingency table: reference labels (rows) vs. produced labels (cols)\n" diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index b8ecd88713eb985b25f935741268a17f8f955edf..df1aef66be62d2c57c3178fa9141122d21f55c5f 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -124,13 +124,13 @@ private: "Only geometries with this field available will be taken into account.\n" "The field is added either in the input file (if 'out' off) or in the output file.\n" "Caution, the 'cfield' must not exist in the input file if you are updating the file."); - SetParameterString("cfield","predicted", false); + SetParameterString("cfield","predicted"); AddParameter(ParameterType_ListView, "feat", "Field names to be calculated."); SetParameterDescription("feat","List of field names in the input vector data used as features for training. " "Put the same field names as the TrainVectorClassifier application."); - AddParameter(ParameterType_Empty, "confmap", "Confidence map"); + AddParameter(ParameterType_Bool, "confmap", "Confidence map"); SetParameterDescription( "confmap", "Confidence map of the produced classification. " "The confidence index depends on the model : \n" " - LibSVM : difference between the two highest probabilities " @@ -145,7 +145,6 @@ private: " * RandomForest : Confidence (proportion of votes for the majority class). " "Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n" " * SVM : distance to margin (only works for 2-class models).\n"); - MandatoryOff("confmap"); AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels"); SetParameterDescription("out","Output vector data file storing sample values (OGR format)." @@ -271,10 +270,10 @@ private: ConfidenceListSampleType::Pointer quality; - bool computeConfidenceMap(IsParameterEnabled("confmap") && m_Model->HasConfidenceIndex() + bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() && !m_Model->GetRegressionMode()); - if (!m_Model->HasConfidenceIndex() && IsParameterEnabled("confmap")) + if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) { otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); } diff --git a/Modules/Applications/AppClassification/app/otbVectorDataDSValidation.cxx b/Modules/Applications/AppClassification/app/otbVectorDataDSValidation.cxx index 11e75421ae78dee6bd5e17de99aefa91fe660ee4..05ddb93a0582162c20dbfe1ff3d4d2e009287798 100644 --- a/Modules/Applications/AppClassification/app/otbVectorDataDSValidation.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorDataDSValidation.cxx @@ -87,12 +87,12 @@ private: AddParameter(ParameterType_String, "cri", "Criterion"); SetParameterDescription("cri", "Dempster Shafer criterion (by default (belief+plausibility)/2)"); MandatoryOff("cri"); - SetParameterString("cri", "((Belief + Plausibility)/2.)", false); + SetParameterString("cri", "((Belief + Plausibility)/2.)"); AddParameter(ParameterType_Float, "thd", "Criterion threshold"); SetParameterDescription("thd", "Criterion threshold (default 0.5)"); MandatoryOff("thd"); - SetParameterFloat("thd",0.5, false); + SetParameterFloat("thd",0.5); AddParameter(ParameterType_OutputVectorData, "out", "Output Vector Data"); SetParameterDescription("out", "Output VectorData containing only the validated samples"); diff --git a/Modules/Applications/AppClassification/include/otbTrainBoost.txx b/Modules/Applications/AppClassification/include/otbTrainBoost.txx index 46cbbbd12560b459c95a3264116ac189b75398fc..f971a2a6294bf42561db2bd799c895877482f254 100644 --- a/Modules/Applications/AppClassification/include/otbTrainBoost.txx +++ b/Modules/Applications/AppClassification/include/otbTrainBoost.txx @@ -61,16 +61,16 @@ namespace Wrapper SetParameterDescription("classifier.boost.t.gentle", "A modified version of the Real Adaboost algorithm, using Newton stepping " "rather than exact optimization at each step."); - SetParameterString("classifier.boost.t", "real", false); + SetParameterString("classifier.boost.t", "real"); SetParameterDescription("classifier.boost.t", "Type of Boosting algorithm."); //Do not expose SplitCriteria //WeakCount AddParameter(ParameterType_Int, "classifier.boost.w", "Weak count"); - SetParameterInt("classifier.boost.w",100, false); + SetParameterInt("classifier.boost.w",100); SetParameterDescription("classifier.boost.w","The number of weak classifiers."); //WeightTrimRate AddParameter(ParameterType_Float, "classifier.boost.r", "Weight Trim Rate"); - SetParameterFloat("classifier.boost.r",0.95, false); + SetParameterFloat("classifier.boost.r",0.95); SetParameterDescription("classifier.boost.r", "A threshold between 0 and 1 used to save computational time. " "Samples with summary weight <= (1 - weight_trim_rate) do not participate in" @@ -78,7 +78,7 @@ namespace Wrapper "functionality."); //MaxDepth : Not sure that this parameter has to be exposed. AddParameter(ParameterType_Int, "classifier.boost.m", "Maximum depth of the tree"); - SetParameterInt("classifier.boost.m",1, false); + SetParameterInt("classifier.boost.m",1); SetParameterDescription("classifier.boost.m","Maximum depth of the tree."); } diff --git a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx index 9803a91a7a8a03f46f9b5bd8443d3d12a112926a..01284b5826247a8f07aaabe429d3bd06034e95ed 100644 --- a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx +++ b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx @@ -40,9 +40,9 @@ LearningApplicationBase<TInputValue,TOutputValue> //MaxDepth AddParameter(ParameterType_Int, "classifier.dt.max", "Maximum depth of the tree"); #ifdef OTB_OPENCV_3 - SetParameterInt("classifier.dt.max",10, false); + SetParameterInt("classifier.dt.max",10); #else - SetParameterInt("classifier.dt.max",65535, false); + SetParameterInt("classifier.dt.max",65535); #endif SetParameterDescription("classifier.dt.max", "The training algorithm attempts to split each node while its depth is smaller " @@ -51,14 +51,14 @@ LearningApplicationBase<TInputValue,TOutputValue> //MinSampleCount AddParameter(ParameterType_Int, "classifier.dt.min", "Minimum number of samples in each node"); - SetParameterInt("classifier.dt.min",10, false); + SetParameterInt("classifier.dt.min",10); SetParameterDescription("classifier.dt.min", "If the number of samples in a node is smaller " "than this parameter, then this node will not be split."); //RegressionAccuracy AddParameter(ParameterType_Float, "classifier.dt.ra", "Termination criteria for regression tree"); - SetParameterFloat("classifier.dt.ra",0.01, false); + SetParameterFloat("classifier.dt.ra",0.01); SetParameterDescription("classifier.dt.ra", "If all absolute differences between an estimated value in a node " "and the values of the train samples in this node are smaller than this " @@ -72,7 +72,7 @@ LearningApplicationBase<TInputValue,TOutputValue> AddParameter(ParameterType_Int, "classifier.dt.cat", "Cluster possible values of a categorical variable into K <= cat clusters to find a " "suboptimal split"); - SetParameterInt("classifier.dt.cat",10, false); + SetParameterInt("classifier.dt.cat",10); SetParameterDescription("classifier.dt.cat", "Cluster possible values of a categorical variable into K <= cat clusters to find a " "suboptimal split."); @@ -81,22 +81,22 @@ LearningApplicationBase<TInputValue,TOutputValue> AddParameter(ParameterType_Int, "classifier.dt.f", "K-fold cross-validations"); #ifdef OTB_OPENCV_3 // disable cross validation by default (crash in opencv 3.2) - SetParameterInt("classifier.dt.f",0, false); + SetParameterInt("classifier.dt.f",0); #else - SetParameterInt("classifier.dt.f",10, false); + SetParameterInt("classifier.dt.f",10); #endif SetParameterDescription("classifier.dt.f", "If cv_folds > 1, then it prunes a tree with K-fold cross-validation where K " "is equal to cv_folds."); //Use1seRule - AddParameter(ParameterType_Empty, "classifier.dt.r", "Set Use1seRule flag to false"); + AddParameter(ParameterType_Bool, "classifier.dt.r", "Set Use1seRule flag to false"); SetParameterDescription("classifier.dt.r", "If true, then a pruning will be harsher. This will make a tree more compact and more " "resistant to the training data noise but a bit less accurate."); //TruncatePrunedTree - AddParameter(ParameterType_Empty, "classifier.dt.t", "Set TruncatePrunedTree flag to false"); + AddParameter(ParameterType_Bool, "classifier.dt.t", "Set TruncatePrunedTree flag to false"); SetParameterDescription("classifier.dt.t", "If true, then pruned branches are physically removed from the tree."); @@ -121,11 +121,11 @@ LearningApplicationBase<TInputValue,TOutputValue> classifier->SetRegressionAccuracy(GetParameterFloat("classifier.dt.ra")); classifier->SetMaxCategories(GetParameterInt("classifier.dt.cat")); classifier->SetCVFolds(GetParameterInt("classifier.dt.f")); - if (IsParameterEnabled("classifier.dt.r")) + if (GetParameterInt("classifier.dt.r")) { classifier->SetUse1seRule(false); } - if (IsParameterEnabled("classifier.dt.t")) + if (GetParameterInt("classifier.dt.t")) { classifier->SetTruncatePrunedTree(false); } diff --git a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.txx b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.txx index 7f69ac9338011c00f3c11164f3a4a1a362a65c65..30a3fde157d6bc04ca60524373333d088254b549 100644 --- a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.txx +++ b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.txx @@ -52,7 +52,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //WeakCount AddParameter(ParameterType_Int, "classifier.gbt.w", "Number of boosting algorithm iterations"); - SetParameterInt("classifier.gbt.w",200, false); + SetParameterInt("classifier.gbt.w",200); SetParameterDescription( "classifier.gbt.w", "Number \"w\" of boosting algorithm iterations, with w*K being the total number of trees in " @@ -60,20 +60,20 @@ LearningApplicationBase<TInputValue,TOutputValue> //Shrinkage AddParameter(ParameterType_Float, "classifier.gbt.s", "Regularization parameter"); - SetParameterFloat("classifier.gbt.s",0.01, false); + SetParameterFloat("classifier.gbt.s",0.01); SetParameterDescription("classifier.gbt.s", "Regularization parameter."); //SubSamplePortion AddParameter(ParameterType_Float, "classifier.gbt.p", "Portion of the whole training set used for each algorithm iteration"); - SetParameterFloat("classifier.gbt.p",0.8, false); + SetParameterFloat("classifier.gbt.p",0.8); SetParameterDescription( "classifier.gbt.p", "Portion of the whole training set used for each algorithm iteration. The subset is generated randomly."); //MaxDepth AddParameter(ParameterType_Int, "classifier.gbt.max", "Maximum depth of the tree"); - SetParameterInt("classifier.gbt.max",3, false); + SetParameterInt("classifier.gbt.max",3); SetParameterDescription( "classifier.gbt.max", "The training algorithm attempts to split each node while its depth is smaller than the maximum " "possible depth of the tree. The actual depth may be smaller if the other termination criteria are met, and/or " diff --git a/Modules/Applications/AppClassification/include/otbTrainImagesBase.txx b/Modules/Applications/AppClassification/include/otbTrainImagesBase.txx index a646cea9539fc3c8b6dcc5f013a6996ed7bf2a9d..15d599176a00bace3665bf780ec4ea55ad197b4d 100644 --- a/Modules/Applications/AppClassification/include/otbTrainImagesBase.txx +++ b/Modules/Applications/AppClassification/include/otbTrainImagesBase.txx @@ -39,11 +39,10 @@ void TrainImagesBase::InitIO() SetParameterDescription( "io.vd", "A list of vector data to select the training samples." ); MandatoryOn( "io.vd" ); - AddParameter( ParameterType_Empty, "cleanup", "Temporary files cleaning" ); - EnableParameter( "cleanup" ); + AddParameter( ParameterType_Bool, "cleanup", "Temporary files cleaning" ); SetParameterDescription( "cleanup", "If activated, the application will try to clean all temporary files it created" ); - MandatoryOff( "cleanup" ); + SetParameterInt( "cleanup", 1); } void TrainImagesBase::InitSampling() @@ -79,7 +78,7 @@ void TrainImagesBase::InitSampling() AddParameter( ParameterType_Float, "sample.vtr", "Training and validation sample ratio" ); SetParameterDescription( "sample.vtr", "Ratio between training and validation samples (0.0 = all training, 1.0 = " "all validation) (default = 0.5)." ); - SetParameterFloat( "sample.vtr", 0.5, false ); + SetParameterFloat( "sample.vtr", 0.5); SetMaximumParameterFloatValue( "sample.vtr", 1.0 ); SetMinimumParameterFloatValue( "sample.vtr", 0.0 ); @@ -160,8 +159,8 @@ void TrainImagesBase::ComputePolygonStatistics(FloatVectorImageListType *imageLi for( unsigned int i = 0; i < nbImages; i++ ) { GetInternalApplication( "polystat" )->SetParameterInputImage( "in", imageList->GetNthElement( i ) ); - GetInternalApplication( "polystat" )->SetParameterString( "vec", vectorFileNames[i], false ); - GetInternalApplication( "polystat" )->SetParameterString( "out", statisticsFileNames[i], false ); + GetInternalApplication( "polystat" )->SetParameterString( "vec", vectorFileNames[i]); + GetInternalApplication( "polystat" )->SetParameterString( "out", statisticsFileNames[i]); ExecuteInternal( "polystat" ); } } @@ -170,7 +169,7 @@ void TrainImagesBase::ComputePolygonStatistics(FloatVectorImageListType *imageLi TrainImagesBase::SamplingRates TrainImagesBase::ComputeFinalMaximumSamplingRates(bool dedicatedValidation) { SamplingRates rates; - GetInternalApplication( "rates" )->SetParameterString( "mim", "proportional", false ); + GetInternalApplication( "rates" )->SetParameterString( "mim", "proportional"); double vtr = GetParameterFloat( "sample.vtr" ); long mt = GetParameterInt( "sample.mt" ); long mv = GetParameterInt( "sample.mv" ); @@ -224,11 +223,11 @@ void TrainImagesBase::ComputeSamplingRate(const std::vector<std::string> &statis const std::string &ratesFileName, long maximum) { // Sampling rates - GetInternalApplication( "rates" )->SetParameterStringList( "il", statisticsFileNames, false ); - GetInternalApplication( "rates" )->SetParameterString( "out", ratesFileName, false ); + GetInternalApplication( "rates" )->SetParameterStringList( "il", statisticsFileNames); + GetInternalApplication( "rates" )->SetParameterString( "out", ratesFileName); if( GetParameterInt( "sample.bm" ) != 0 ) { - GetInternalApplication( "rates" )->SetParameterString( "strategy", "smallest", false ); + GetInternalApplication( "rates" )->SetParameterString( "strategy", "smallest"); } else { @@ -236,12 +235,12 @@ void TrainImagesBase::ComputeSamplingRate(const std::vector<std::string> &statis { std::ostringstream oss; oss << maximum; - GetInternalApplication( "rates" )->SetParameterString( "strategy", "constant", false ); - GetInternalApplication( "rates" )->SetParameterString( "strategy.constant.nb", oss.str(), false ); + GetInternalApplication( "rates" )->SetParameterString( "strategy", "constant"); + GetInternalApplication( "rates" )->SetParameterString( "strategy.constant.nb", oss.str()); } else { - GetInternalApplication( "rates" )->SetParameterString( "strategy", "all", false ); + GetInternalApplication( "rates" )->SetParameterString( "strategy", "all"); } } ExecuteInternal( "rates" ); @@ -251,9 +250,9 @@ void TrainImagesBase::TrainModel(FloatVectorImageListType *imageList, const std::vector<std::string> &sampleTrainFileNames, const std::vector<std::string> &sampleValidationFileNames) { - GetInternalApplication( "training" )->SetParameterStringList( "io.vd", sampleTrainFileNames, false ); + GetInternalApplication( "training" )->SetParameterStringList( "io.vd", sampleTrainFileNames); if( !sampleValidationFileNames.empty() ) - GetInternalApplication( "training" )->SetParameterStringList( "valid.vd", sampleValidationFileNames, false ); + GetInternalApplication( "training" )->SetParameterStringList( "valid.vd", sampleValidationFileNames); UpdateInternalParameters( "training" ); // set field names @@ -266,7 +265,7 @@ TrainImagesBase::TrainModel(FloatVectorImageListType *imageList, const std::vect oss << i; selectedNames.push_back( "value_" + oss.str() ); } - GetInternalApplication( "training" )->SetParameterStringList( "feat", selectedNames, false ); + GetInternalApplication( "training" )->SetParameterStringList( "feat", selectedNames); ExecuteInternal( "training" ); } @@ -276,38 +275,38 @@ void TrainImagesBase::SelectAndExtractSamples(FloatVectorImageType *image, std:: std::string selectedField) { GetInternalApplication( "select" )->SetParameterInputImage( "in", image ); - GetInternalApplication( "select" )->SetParameterString( "out", sampleFileName, false ); + GetInternalApplication( "select" )->SetParameterString( "out", sampleFileName); // Change the selection strategy based on selected sampling strategy switch( strategy ) { // case GEOMETRIC: -// GetInternalApplication( "select" )->SetParameterString( "sampler", "random", false ); -// GetInternalApplication( "select" )->SetParameterString( "strategy", "percent", false ); +// GetInternalApplication( "select" )->SetParameterString( "sampler", "random"); +// GetInternalApplication( "select" )->SetParameterString( "strategy", "percent"); // GetInternalApplication( "select" )->SetParameterFloat( "strategy.percent.p", -// GetParameterFloat( "sample.percent" ), false ); +// GetParameterFloat( "sample.percent" )); // break; case CLASS: default: - GetInternalApplication( "select" )->SetParameterString( "vec", vectorFileName, false ); - GetInternalApplication( "select" )->SetParameterString( "instats", statisticsFileName, false ); - GetInternalApplication( "select" )->SetParameterString( "sampler", "periodic", false ); + GetInternalApplication( "select" )->SetParameterString( "vec", vectorFileName); + GetInternalApplication( "select" )->SetParameterString( "instats", statisticsFileName); + GetInternalApplication( "select" )->SetParameterString( "sampler", "periodic"); GetInternalApplication( "select" )->SetParameterInt( "sampler.periodic.jitter", 50 ); - GetInternalApplication( "select" )->SetParameterString( "strategy", "byclass", false ); - GetInternalApplication( "select" )->SetParameterString( "strategy.byclass.in", ratesFileName, false ); + GetInternalApplication( "select" )->SetParameterString( "strategy", "byclass"); + GetInternalApplication( "select" )->SetParameterString( "strategy.byclass.in", ratesFileName); break; } // select sample positions ExecuteInternal( "select" ); - GetInternalApplication( "extraction" )->SetParameterString( "vec", sampleFileName, false ); + GetInternalApplication( "extraction" )->SetParameterString( "vec", sampleFileName); UpdateInternalParameters( "extraction" ); if( !selectedField.empty() ) - GetInternalApplication( "extraction" )->SetParameterString( "field", selectedField, false ); + GetInternalApplication( "extraction" )->SetParameterString( "field", selectedField); - GetInternalApplication( "extraction" )->SetParameterString( "outfield", "prefix", false ); - GetInternalApplication( "extraction" )->SetParameterString( "outfield.prefix.name", "value_", false ); + GetInternalApplication( "extraction" )->SetParameterString( "outfield", "prefix"); + GetInternalApplication( "extraction" )->SetParameterString( "outfield.prefix.name", "value_"); // extract sample descriptors ExecuteInternal( "extraction" ); diff --git a/Modules/Applications/AppClassification/include/otbTrainKNN.txx b/Modules/Applications/AppClassification/include/otbTrainKNN.txx index 2ff93632bcd9b399e6d399f16cfe1fa33ed2cc6d..71e02215dbbf94e4b6d014ae89e92f11ac1389fb 100644 --- a/Modules/Applications/AppClassification/include/otbTrainKNN.txx +++ b/Modules/Applications/AppClassification/include/otbTrainKNN.txx @@ -39,7 +39,7 @@ namespace Wrapper //K parameter AddParameter(ParameterType_Int, "classifier.knn.k", "Number of Neighbors"); - SetParameterInt("classifier.knn.k",32, false); + SetParameterInt("classifier.knn.k",32); SetParameterDescription("classifier.knn.k","The number of neighbors to use."); if (this->m_RegressionFlag) diff --git a/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx b/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx index 18b9f4d39a8926abf645647bec30273d2b98e3b5..0e34ad78c40f9e7465f1de7a88e5bef08bfa1fa0 100644 --- a/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx +++ b/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx @@ -54,7 +54,7 @@ namespace Wrapper SetParameterDescription("classifier.libsvm.k.sigmoid", "The kernel is a hyperbolic tangente function of the vectors."); - SetParameterString("classifier.libsvm.k", "linear", false); + SetParameterString("classifier.libsvm.k", "linear"); SetParameterDescription("classifier.libsvm.k", "SVM Kernel Type."); AddParameter(ParameterType_Choice, "classifier.libsvm.m", "SVM Model Type"); SetParameterDescription("classifier.libsvm.m", "Type of SVM formulation."); @@ -67,7 +67,7 @@ namespace Wrapper "multiplier C is used "); AddChoice("classifier.libsvm.m.nusvr", "Nu Support Vector Regression"); - SetParameterString("classifier.libsvm.m", "epssvr", false); + SetParameterString("classifier.libsvm.m", "epssvr"); SetParameterDescription("classifier.libsvm.m.nusvr", "Same as the epsilon regression except that this time the bounded " "parameter nu is used instead of epsilon"); @@ -89,33 +89,32 @@ namespace Wrapper SetParameterDescription("classifier.libsvm.m.oneclass", "All the training data are from the same class, SVM builds a boundary " "that separates the class from the rest of the feature space."); - SetParameterString("classifier.libsvm.m", "csvc", false); + SetParameterString("classifier.libsvm.m", "csvc"); } AddParameter(ParameterType_Float, "classifier.libsvm.c", "Cost parameter C"); - SetParameterFloat("classifier.libsvm.c",1.0, false); + SetParameterFloat("classifier.libsvm.c",1.0); SetParameterDescription("classifier.libsvm.c", "SVM models have a cost parameter C (1 by default) to control the " "trade-off between training errors and forcing rigid margins."); AddParameter(ParameterType_Float, "classifier.libsvm.nu", "Cost parameter Nu"); - SetParameterFloat("classifier.libsvm.nu",0.5, false); + SetParameterFloat("classifier.libsvm.nu",0.5); SetParameterDescription("classifier.libsvm.nu", "Cost parameter Nu, in the range 0..1, the larger the value, " "the smoother the decision."); // It seems that it miss a nu parameter for the nu-SVM use. - AddParameter(ParameterType_Empty, "classifier.libsvm.opt", "Parameters optimization"); - MandatoryOff("classifier.libsvm.opt"); + AddParameter(ParameterType_Bool, "classifier.libsvm.opt", "Parameters optimization"); SetParameterDescription("classifier.libsvm.opt", "SVM parameters optimization flag."); - AddParameter(ParameterType_Empty, "classifier.libsvm.prob", "Probability estimation"); - MandatoryOff("classifier.libsvm.prob"); + + AddParameter(ParameterType_Bool, "classifier.libsvm.prob", "Probability estimation"); SetParameterDescription("classifier.libsvm.prob", "Probability estimation flag."); if (this->m_RegressionFlag) { AddParameter(ParameterType_Float, "classifier.libsvm.eps", "Epsilon"); - SetParameterFloat("classifier.libsvm.eps",1e-3, false); + SetParameterFloat("classifier.libsvm.eps",1e-3); SetParameterDescription("classifier.libsvm.eps", "The distance between feature vectors from the training set and " "the fitting hyper-plane must be less than Epsilon. For outliers" @@ -137,14 +136,8 @@ namespace Wrapper libSVMClassifier->SetTargetListSample(trainingLabeledListSample); //SVM Option //TODO : Add other options ? - if (IsParameterEnabled("classifier.libsvm.opt")) - { - libSVMClassifier->SetParameterOptimization(true); - } - if (IsParameterEnabled("classifier.libsvm.prob")) - { - libSVMClassifier->SetDoProbabilityEstimates(true); - } + libSVMClassifier->SetParameterOptimization(GetParameterInt("classifier.libsvm.opt")); + libSVMClassifier->SetDoProbabilityEstimates(GetParameterInt("classifier.libsvm.prob")); libSVMClassifier->SetNu(GetParameterFloat("classifier.libsvm.nu")); libSVMClassifier->SetC(GetParameterFloat("classifier.libsvm.c")); diff --git a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx index 4081034a5f0fead34f03f3f0325f0ad6294b5582..33a4930ac4f2458b0aa0153d7f762529b7fa280a 100644 --- a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx +++ b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx @@ -52,7 +52,7 @@ LearningApplicationBase<TInputValue,TOutputValue> "take into account the magnitude of the partial derivative (coordinate " "of the gradient) but only its sign."); - SetParameterString("classifier.ann.t", "reg", false); + SetParameterString("classifier.ann.t", "reg"); SetParameterDescription("classifier.ann.t", "Type of training method for the multilayer perceptron (MLP) neural network."); @@ -73,7 +73,7 @@ LearningApplicationBase<TInputValue,TOutputValue> AddChoice("classifier.ann.f.ident", "Identity function"); AddChoice("classifier.ann.f.sig", "Symmetrical Sigmoid function"); AddChoice("classifier.ann.f.gau", "Gaussian function (Not completely supported)"); - SetParameterString("classifier.ann.f", "sig", false); + SetParameterString("classifier.ann.f", "sig"); SetParameterDescription("classifier.ann.f", "This function determine whether the output of the node is positive or not " "depending on the output of the transfert function."); @@ -81,21 +81,21 @@ LearningApplicationBase<TInputValue,TOutputValue> //Alpha AddParameter(ParameterType_Float, "classifier.ann.a", "Alpha parameter of the activation function"); - SetParameterFloat("classifier.ann.a",1., false); + SetParameterFloat("classifier.ann.a",1.); SetParameterDescription("classifier.ann.a", "Alpha parameter of the activation function (used only with sigmoid and gaussian functions)."); //Beta AddParameter(ParameterType_Float, "classifier.ann.b", "Beta parameter of the activation function"); - SetParameterFloat("classifier.ann.b",1., false); + SetParameterFloat("classifier.ann.b",1.); SetParameterDescription("classifier.ann.b", "Beta parameter of the activation function (used only with sigmoid and gaussian functions)."); //BackPropDWScale AddParameter(ParameterType_Float, "classifier.ann.bpdw", "Strength of the weight gradient term in the BACKPROP method"); - SetParameterFloat("classifier.ann.bpdw",0.1, false); + SetParameterFloat("classifier.ann.bpdw",0.1); SetParameterDescription("classifier.ann.bpdw", "Strength of the weight gradient term in the BACKPROP method. The " "recommended value is about 0.1."); @@ -103,7 +103,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //BackPropMomentScale AddParameter(ParameterType_Float, "classifier.ann.bpms", "Strength of the momentum term (the difference between weights on the 2 previous iterations)"); - SetParameterFloat("classifier.ann.bpms",0.1, false); + SetParameterFloat("classifier.ann.bpms",0.1); SetParameterDescription("classifier.ann.bpms", "Strength of the momentum term (the difference between weights on the 2 previous " "iterations). This parameter provides some inertia to smooth the random " @@ -113,14 +113,14 @@ LearningApplicationBase<TInputValue,TOutputValue> //RegPropDW0 AddParameter(ParameterType_Float, "classifier.ann.rdw", "Initial value Delta_0 of update-values Delta_{ij} in RPROP method"); - SetParameterFloat("classifier.ann.rdw",0.1, false); + SetParameterFloat("classifier.ann.rdw",0.1); SetParameterDescription("classifier.ann.rdw", "Initial value Delta_0 of update-values Delta_{ij} in RPROP method (default = 0.1)."); //RegPropDWMin AddParameter(ParameterType_Float, "classifier.ann.rdwm", "Update-values lower limit Delta_{min} in RPROP method"); - SetParameterFloat("classifier.ann.rdwm",1e-7, false); + SetParameterFloat("classifier.ann.rdwm",1e-7); SetParameterDescription("classifier.ann.rdwm", "Update-values lower limit Delta_{min} in RPROP method. It must be positive " "(default = 1e-7)."); @@ -139,20 +139,20 @@ LearningApplicationBase<TInputValue,TOutputValue> AddChoice("classifier.ann.term.all", "Max. iterations + Epsilon"); SetParameterDescription("classifier.ann.term.all", "Both termination criteria are used. Training stop at the first reached"); - SetParameterString("classifier.ann.term", "all", false); + SetParameterString("classifier.ann.term", "all"); SetParameterDescription("classifier.ann.term", "Termination criteria."); //Epsilon AddParameter(ParameterType_Float, "classifier.ann.eps", "Epsilon value used in the Termination criteria"); - SetParameterFloat("classifier.ann.eps",0.01, false); + SetParameterFloat("classifier.ann.eps",0.01); SetParameterDescription("classifier.ann.eps", "Epsilon value used in the Termination criteria."); //MaxIter AddParameter(ParameterType_Int, "classifier.ann.iter", "Maximum number of iterations used in the Termination criteria"); - SetParameterInt("classifier.ann.iter",1000, false); + SetParameterInt("classifier.ann.iter",1000); SetParameterDescription("classifier.ann.iter", "Maximum number of iterations used in the Termination criteria."); diff --git a/Modules/Applications/AppClassification/include/otbTrainRandomForests.txx b/Modules/Applications/AppClassification/include/otbTrainRandomForests.txx index f557731207aa92509c7f156fcfbdf794ebaf9d03..e19777a6861c793150c652cdb9d695cde874a618 100644 --- a/Modules/Applications/AppClassification/include/otbTrainRandomForests.txx +++ b/Modules/Applications/AppClassification/include/otbTrainRandomForests.txx @@ -39,7 +39,7 @@ LearningApplicationBase<TInputValue,TOutputValue> "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/random_trees.html}."); //MaxDepth AddParameter(ParameterType_Int, "classifier.rf.max", "Maximum depth of the tree"); - SetParameterInt("classifier.rf.max",5, false); + SetParameterInt("classifier.rf.max",5); SetParameterDescription( "classifier.rf.max", "The depth of the tree. A low value will likely underfit and conversely a high value will likely overfit. " @@ -47,14 +47,14 @@ LearningApplicationBase<TInputValue,TOutputValue> //MinSampleCount AddParameter(ParameterType_Int, "classifier.rf.min", "Minimum number of samples in each node"); - SetParameterInt("classifier.rf.min",10, false); + SetParameterInt("classifier.rf.min",10); SetParameterDescription( "classifier.rf.min", "If the number of samples in a node is smaller than this parameter, " "then the node will not be split. A reasonable value is a small percentage of the total data e.g. 1 percent."); //RegressionAccuracy AddParameter(ParameterType_Float, "classifier.rf.ra", "Termination Criteria for regression tree"); - SetParameterFloat("classifier.rf.ra",0., false); + SetParameterFloat("classifier.rf.ra",0.); SetParameterDescription("classifier.rf.ra", "If all absolute differences between an estimated value in a node " "and the values of the train samples in this node are smaller than this regression accuracy parameter, " "then the node will not be split."); @@ -66,7 +66,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //MaxNumberOfCategories AddParameter(ParameterType_Int, "classifier.rf.cat", "Cluster possible values of a categorical variable into K <= cat clusters to find a suboptimal split"); - SetParameterInt("classifier.rf.cat",10, false); + SetParameterInt("classifier.rf.cat",10); SetParameterDescription( "classifier.rf.cat", "Cluster possible values of a categorical variable into K <= cat clusters to find a suboptimal split."); @@ -78,7 +78,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //MaxNumberOfVariables AddParameter(ParameterType_Int, "classifier.rf.var", "Size of the randomly selected subset of features at each tree node"); - SetParameterInt("classifier.rf.var",0, false); + SetParameterInt("classifier.rf.var",0); SetParameterDescription( "classifier.rf.var", "The size of the subset of features, randomly selected at each tree node, that are used to find the best split(s). " @@ -87,7 +87,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //MaxNumberOfTrees AddParameter(ParameterType_Int, "classifier.rf.nbtrees", "Maximum number of trees in the forest"); - SetParameterInt("classifier.rf.nbtrees",100, false); + SetParameterInt("classifier.rf.nbtrees",100); SetParameterDescription( "classifier.rf.nbtrees", "The maximum number of trees in the forest. Typically, the more trees you have, the better the accuracy. " @@ -97,7 +97,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //ForestAccuracy AddParameter(ParameterType_Float, "classifier.rf.acc", "Sufficient accuracy (OOB error)"); - SetParameterFloat("classifier.rf.acc",0.01, false); + SetParameterFloat("classifier.rf.acc",0.01); SetParameterDescription("classifier.rf.acc","Sufficient accuracy (OOB error)."); diff --git a/Modules/Applications/AppClassification/include/otbTrainSVM.txx b/Modules/Applications/AppClassification/include/otbTrainSVM.txx index ac9524faa26de64a04e4a98b008b101f225cc8ca..ab5138ba33027df907b4d908622250404e2dd1a0 100644 --- a/Modules/Applications/AppClassification/include/otbTrainSVM.txx +++ b/Modules/Applications/AppClassification/include/otbTrainSVM.txx @@ -42,14 +42,14 @@ namespace Wrapper { AddChoice("classifier.svm.m.epssvr", "Epsilon Support Vector Regression"); AddChoice("classifier.svm.m.nusvr", "Nu Support Vector Regression"); - SetParameterString("classifier.svm.m", "epssvr", false); + SetParameterString("classifier.svm.m", "epssvr"); } else { AddChoice("classifier.svm.m.csvc", "C support vector classification"); AddChoice("classifier.svm.m.nusvc", "Nu support vector classification"); AddChoice("classifier.svm.m.oneclass", "Distribution estimation (One Class SVM)"); - SetParameterString("classifier.svm.m", "csvc", false); + SetParameterString("classifier.svm.m", "csvc"); } AddParameter(ParameterType_Choice, "classifier.svm.k", "SVM Kernel Type"); AddChoice("classifier.svm.k.linear", "Linear"); @@ -57,22 +57,22 @@ namespace Wrapper AddChoice("classifier.svm.k.rbf", "Gaussian radial basis function"); AddChoice("classifier.svm.k.poly", "Polynomial"); AddChoice("classifier.svm.k.sigmoid", "Sigmoid"); - SetParameterString("classifier.svm.k", "linear", false); + SetParameterString("classifier.svm.k", "linear"); SetParameterDescription("classifier.svm.k", "SVM Kernel Type."); AddParameter(ParameterType_Float, "classifier.svm.c", "Cost parameter C"); - SetParameterFloat("classifier.svm.c",1.0, false); + SetParameterFloat("classifier.svm.c",1.0); SetParameterDescription("classifier.svm.c", "SVM models have a cost parameter C (1 by default) to control the trade-off" " between training errors and forcing rigid margins."); AddParameter(ParameterType_Float, "classifier.svm.nu", "Parameter nu of a SVM optimization problem (NU_SVC / ONE_CLASS)"); - SetParameterFloat("classifier.svm.nu",0.0, false); + SetParameterFloat("classifier.svm.nu",0.0); SetParameterDescription("classifier.svm.nu", "Parameter nu of a SVM optimization problem."); if (this->m_RegressionFlag) { AddParameter(ParameterType_Float, "classifier.svm.p", "Parameter epsilon of a SVM optimization problem (EPS_SVR)"); - SetParameterFloat("classifier.svm.p",1.0, false); + SetParameterFloat("classifier.svm.p",1.0); SetParameterDescription("classifier.svm.p", "Parameter epsilon of a SVM optimization problem (EPS_SVR)."); AddParameter(ParameterType_Choice, @@ -87,34 +87,33 @@ namespace Wrapper "Stops when either iteration or epsilon criteria is true"); AddParameter(ParameterType_Float, "classifier.svm.iter", "Maximum iteration"); - SetParameterFloat("classifier.svm.iter",1000, false); + SetParameterFloat("classifier.svm.iter",1000); SetParameterDescription("classifier.svm.iter", "Maximum number of iterations (corresponds to the termination criteria 'iter')."); AddParameter(ParameterType_Float, "classifier.svm.eps", "Epsilon accuracy threshold"); - SetParameterFloat("classifier.svm.eps",FLT_EPSILON, false); + SetParameterFloat("classifier.svm.eps",FLT_EPSILON); SetParameterDescription("classifier.svm.eps", "Epsilon accuracy (corresponds to the termination criteria 'eps')."); } AddParameter(ParameterType_Float, "classifier.svm.coef0", "Parameter coef0 of a kernel function (POLY / SIGMOID)"); - SetParameterFloat("classifier.svm.coef0",0.0, false); + SetParameterFloat("classifier.svm.coef0",0.0); SetParameterDescription("classifier.svm.coef0", "Parameter coef0 of a kernel function (POLY / SIGMOID)."); AddParameter(ParameterType_Float, "classifier.svm.gamma", "Parameter gamma of a kernel function (POLY / RBF / SIGMOID)"); - SetParameterFloat("classifier.svm.gamma",1.0, false); + SetParameterFloat("classifier.svm.gamma",1.0); SetParameterDescription("classifier.svm.gamma", "Parameter gamma of a kernel function (POLY / RBF / SIGMOID)."); AddParameter(ParameterType_Float, "classifier.svm.degree", "Parameter degree of a kernel function (POLY)"); - SetParameterFloat("classifier.svm.degree",1.0, false); + SetParameterFloat("classifier.svm.degree",1.0); SetParameterDescription("classifier.svm.degree", "Parameter degree of a kernel function (POLY)."); - AddParameter(ParameterType_Empty, "classifier.svm.opt", + AddParameter(ParameterType_Bool, "classifier.svm.opt", "Parameters optimization"); - MandatoryOff("classifier.svm.opt"); SetParameterDescription("classifier.svm.opt", "SVM parameters optimization flag.\n" "-If set to True, then the optimal SVM parameters will be estimated. " "Parameters are considered optimal by OpenCV when the cross-validation estimate of " @@ -229,23 +228,20 @@ namespace Wrapper SVMClassifier->SetCoef0(GetParameterFloat("classifier.svm.coef0")); SVMClassifier->SetGamma(GetParameterFloat("classifier.svm.gamma")); SVMClassifier->SetDegree(GetParameterFloat("classifier.svm.degree")); - if (IsParameterEnabled("classifier.svm.opt")) - { - SVMClassifier->SetParameterOptimization(true); - } + SVMClassifier->SetParameterOptimization(GetParameterInt("classifier.svm.opt")); SVMClassifier->Train(); SVMClassifier->Save(modelPath); // Update the displayed parameters in the GUI after the training process, for further use of them - SetParameterFloat("classifier.svm.c",static_cast<float> (SVMClassifier->GetOutputC()), false); - SetParameterFloat("classifier.svm.nu",static_cast<float> (SVMClassifier->GetOutputNu()), false); + SetParameterFloat("classifier.svm.c",static_cast<float> (SVMClassifier->GetOutputC())); + SetParameterFloat("classifier.svm.nu",static_cast<float> (SVMClassifier->GetOutputNu())); if (this->m_RegressionFlag) { - SetParameterFloat("classifier.svm.p",static_cast<float> (SVMClassifier->GetOutputP()), false); + SetParameterFloat("classifier.svm.p",static_cast<float> (SVMClassifier->GetOutputP())); } - SetParameterFloat("classifier.svm.coef0",static_cast<float> (SVMClassifier->GetOutputCoef0()), false); - SetParameterFloat("classifier.svm.gamma",static_cast<float> (SVMClassifier->GetOutputGamma()), false); - SetParameterFloat("classifier.svm.degree",static_cast<float> (SVMClassifier->GetOutputDegree()), false); + SetParameterFloat("classifier.svm.coef0",static_cast<float> (SVMClassifier->GetOutputCoef0())); + SetParameterFloat("classifier.svm.gamma",static_cast<float> (SVMClassifier->GetOutputGamma())); + SetParameterFloat("classifier.svm.degree",static_cast<float> (SVMClassifier->GetOutputDegree())); } } //end namespace wrapper diff --git a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.txx b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.txx index f2c2f97dc24bc77d798e533eadb09ef9354298d0..fa7ef6646ac634a1dca47dbc5741743ad201ccee 100644 --- a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.txx +++ b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.txx @@ -43,7 +43,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //MaxNumberOfTrees AddParameter(ParameterType_Int, "classifier.sharkrf.nbtrees", "Maximum number of trees in the forest"); - SetParameterInt("classifier.sharkrf.nbtrees",100, false); + SetParameterInt("classifier.sharkrf.nbtrees",100); SetParameterDescription( "classifier.sharkrf.nbtrees", "The maximum number of trees in the forest. Typically, the more trees you have, the better the accuracy. " @@ -53,7 +53,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //NodeSize AddParameter(ParameterType_Int, "classifier.sharkrf.nodesize", "Min size of the node for a split"); - SetParameterInt("classifier.sharkrf.nodesize",25, false); + SetParameterInt("classifier.sharkrf.nodesize",25); SetParameterDescription( "classifier.sharkrf.nodesize", "If the number of samples in a node is smaller than this parameter, " @@ -61,7 +61,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //MTry AddParameter(ParameterType_Int, "classifier.sharkrf.mtry", "Number of features tested at each node"); - SetParameterInt("classifier.sharkrf.mtry",0, false); + SetParameterInt("classifier.sharkrf.mtry",0); SetParameterDescription( "classifier.sharkrf.mtry", "The number of features (variables) which will be tested at each node in " @@ -71,7 +71,7 @@ LearningApplicationBase<TInputValue,TOutputValue> //OOB Ratio AddParameter(ParameterType_Float, "classifier.sharkrf.oobr", "Out of bound ratio"); - SetParameterFloat("classifier.sharkrf.oobr",0.66, false); + SetParameterFloat("classifier.sharkrf.oobr",0.66); SetParameterDescription("classifier.sharkrf.oobr", "Set the fraction of the original training dataset to use as the out of bag sample." "A good default value is 0.66. "); diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx b/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx index 2c3575c2ead20381438f9f66d5cd9c65c1723132..453db3f3f02c29a23533ef26db67fb71d8cb6411 100644 --- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx +++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx @@ -91,10 +91,9 @@ void TrainVectorBase::DoInit() "The contingency table is output when we unsupervised algorithms is used otherwise the confusion matrix is output." ); MandatoryOff( "io.confmatout" ); - AddParameter(ParameterType_Empty, "v", "Verbose mode"); - EnableParameter("v"); + AddParameter(ParameterType_Bool, "v", "Verbose mode"); SetParameterDescription("v", "Verbose mode, display the contingency table result."); - MandatoryOff("v"); + SetParameterInt("v", 1); // Doc example parameter settings SetDocExampleParameterValue( "io.vd", "vectorData.shp" ); diff --git a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx index 073e53727f6b194b27e49887c4cf8c70469c537f..04cf50df4d626be84da6288cdd740e9b2f10db55 100644 --- a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx +++ b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx @@ -135,10 +135,8 @@ private: SetMinimumParameterFloatValue("threshold",0.0); SetDefaultParameterFloat("threshold",0.6); - AddParameter(ParameterType_Empty,"backmatching","Use back-matching to filter matches."); + AddParameter(ParameterType_Bool,"backmatching","Use back-matching to filter matches."); SetParameterDescription("backmatching","If set to true, matches should be consistent in both ways."); - MandatoryOff("backmatching"); - DisableParameter("backmatching"); AddParameter(ParameterType_Choice,"mode","Keypoints search mode"); @@ -177,10 +175,10 @@ private: SetParameterDescription("precision","Estimated precision of the colocalisation function in pixels"); SetDefaultParameterFloat("precision",0.); - AddParameter(ParameterType_Empty,"mfilter","Filter points according to geographical or sensor based colocalisation"); + AddParameter(ParameterType_Bool,"mfilter","Filter points according to geographical or sensor based colocalisation"); SetParameterDescription("mfilter","If enabled, this option allows one to filter matches according to colocalisation from sensor or geographical information, using the given tolerancy expressed in pixels"); - AddParameter(ParameterType_Empty,"2wgs84","If enabled, points from second image will be exported in WGS84"); + AddParameter(ParameterType_Bool,"2wgs84","If enabled, points from second image will be exported in WGS84"); // Elevation ElevationParametersHandler::AddElevationParameters(this, "elev"); @@ -251,7 +249,7 @@ private: matchingFilter->SetInput1(surf1->GetOutput()); matchingFilter->SetInput2(surf2->GetOutput()); matchingFilter->SetDistanceThreshold(GetParameterFloat("threshold")); - matchingFilter->SetUseBackMatching(IsParameterEnabled("backmatching")); + matchingFilter->SetUseBackMatching(GetParameterInt("backmatching")); } try @@ -276,7 +274,7 @@ private: bool filtered = false; - if(IsParameterEnabled("mfilter")) + if(GetParameterInt("mfilter")) { pprime1 = rsTransform->TransformPoint(point1); error = vcl_sqrt((point2[0]-pprime1[0])*(point2[0]-pprime1[0])+(point2[1]-pprime1[1])*(point2[1]-pprime1[1])); @@ -289,7 +287,7 @@ private: if(!filtered) { - if(IsParameterEnabled("2wgs84")) + if(GetParameterInt("2wgs84")) { pprime2 = rsTransform2ToWGS84->TransformPoint(point2); diff --git a/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt b/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt index 63c4a2105666056a75d4f7b02a8a1dbac75a2e50..6e57a26cb83cf691166b6f1e8e98dff98a21c578 100644 --- a/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt +++ b/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt @@ -22,3 +22,22 @@ otb_create_application( NAME DimensionalityReduction SOURCES otbDimensionalityReduction.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES}) + +OTB_CREATE_APPLICATION( + NAME TrainDimensionalityReduction + SOURCES otbTrainDimensionalityReduction.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES} ${OTBCommon_LIBRARIES} ${OTBITK_LIBRARIES} ${OTBBoost_LIBRARIES} ${OTBShark_LIBRARIES} + ) + +OTB_CREATE_APPLICATION( + NAME ImageDimensionalityReduction + SOURCES otbImageDimensionalityReduction.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES} ${OTBCommon_LIBRARIES} ${OTBITK_LIBRARIES} ${OTBBoost_LIBRARIES} ${OTBShark_LIBRARIES} + ) + +OTB_CREATE_APPLICATION( + NAME VectorDimensionalityReduction + SOURCES otbVectorDimensionalityReduction.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES} ${OTBCommon_LIBRARIES} ${OTBITK_LIBRARIES} ${OTBBoost_LIBRARIES} ${OTBShark_LIBRARIES} + ) + diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx index 686b78bb4cad81a332c249358998b59523fabdc6..d783a3df7535f9f2848ab50fe55867c30a4610ea 100644 --- a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx +++ b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx @@ -164,9 +164,8 @@ private: MandatoryOff("nbcomp"); SetMinimumParameterIntValue("nbcomp", 0); - AddParameter(ParameterType_Empty, "normalize", "Normalize."); + AddParameter(ParameterType_Bool, "normalize", "Normalize."); SetParameterDescription("normalize", "center AND reduce data before Dimensionality reduction."); - MandatoryOff("normalize"); AddParameter(ParameterType_OutputFilename, "outmatrix", "Transformation matrix output (text format)"); SetParameterDescription("outmatrix", "Filename to store the transformation matrix (csv format)"); @@ -196,7 +195,7 @@ private: unsigned int nbComp = static_cast<unsigned int> (GetParameterInt("nbcomp")); if (nbComp > nbComponents) { - SetParameterInt("nbcomp",nbComponents, false); + SetParameterInt("nbcomp",nbComponents); otbAppLogINFO( << "number of selected components can't exceed image dimension : "<<nbComponents ); } @@ -206,14 +205,14 @@ private: if (this->GetParameterString("outinv").size()!= 0) { otbAppLogWARNING(<<"This application only provides the forward transform for the MAF method."); - this->SetParameterString("outinv", "", false); + this->SetParameterString("outinv", ""); } this->DisableParameter("outinv"); if (this->GetParameterString("outmatrix").size()!= 0) { otbAppLogWARNING(<<"No transformation matrix available for MAF method."); - this->SetParameterString("outmatrix", "", false); + this->SetParameterString("outmatrix", ""); } this->DisableParameter("outmatrix"); @@ -225,7 +224,7 @@ private: unsigned int nbComp = static_cast<unsigned int> (GetParameterInt("nbcomp")); if ((nbComp != 0) && (nbComp != nbComponents)) { - SetParameterInt("nbcomp",nbComponents, false); + SetParameterInt("nbcomp",nbComponents); otbAppLogINFO( << "all components are kept when using MAF filter method."); } @@ -237,7 +236,7 @@ private: // Get Parameters int nbComp = GetParameterInt("nbcomp"); - bool normalize = IsParameterEnabled("normalize"); + bool normalize = GetParameterInt("normalize"); bool rescale = IsParameterEnabled("rescale"); bool invTransform = HasValue("outinv") && IsParameterEnabled("outinv"); diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c221302c033c889e1ddb601662ab840f01257a22 --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "itkUnaryFunctorImageFilter.h" +#include "otbChangeLabelImageFilter.h" +#include "otbStandardWriterWatcher.h" +#include "otbStatisticsXMLFileReader.h" +#include "otbShiftScaleVectorImageFilter.h" +#include "otbImageDimensionalityReductionFilter.h" +#include "otbMultiToMonoChannelExtractROI.h" +#include "otbImageToVectorImageCastFilter.h" +#include "otbDimensionalityReductionModelFactory.h" + +namespace otb +{ +namespace Functor +{ +/** + * simple affine function : y = ax+b + */ +template<class TInput, class TOutput> +class AffineFunctor +{ +public: + typedef double InternalType; + + // constructor + AffineFunctor() : m_A(1.0),m_B(0.0) {} + + // destructor + virtual ~AffineFunctor() {} + + void SetA(InternalType a) + { + m_A = a; + } + + void SetB(InternalType b) + { + m_B = b; + } + + inline TOutput operator()(const TInput & x) const + { + return static_cast<TOutput>( static_cast<InternalType>(x)*m_A + m_B); + } +private: + InternalType m_A; + InternalType m_B; +}; + +} // end of namespace Functor + +namespace Wrapper +{ +/** + * \class ImageDimensionalityReduction + * + * Apply a dimensionality reduction model to an image + */ +class ImageDimensionalityReduction : public Application +{ +public: + /** Standard class typedefs. */ + typedef ImageDimensionalityReduction Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Standard macro */ + itkNewMacro(Self); + + itkTypeMacro(ImageDimensionalityReduction, otb::Application); + + /** Filters typedef */ + typedef UInt8ImageType MaskImageType; + typedef itk::VariableLengthVector< + FloatVectorImageType::InternalPixelType> MeasurementType; + typedef otb::StatisticsXMLFileReader<MeasurementType> StatisticsReader; + typedef otb::ShiftScaleVectorImageFilter< + FloatVectorImageType, FloatVectorImageType> RescalerType; + typedef itk::UnaryFunctorImageFilter< + FloatImageType, + FloatImageType, + otb::Functor::AffineFunctor<float,float> > OutputRescalerType; + typedef otb::ImageDimensionalityReductionFilter< + FloatVectorImageType, + FloatVectorImageType, + MaskImageType> DimensionalityReductionFilterType; + typedef DimensionalityReductionFilterType::Pointer DimensionalityReductionFilterPointerType; + typedef DimensionalityReductionFilterType::ModelType ModelType; + typedef ModelType::Pointer ModelPointerType; + typedef DimensionalityReductionFilterType::ValueType ValueType; + typedef DimensionalityReductionFilterType::LabelType LabelType; + typedef otb::DimensionalityReductionModelFactory< + ValueType, LabelType> DimensionalityReductionModelFactoryType; + +protected: + + ~ImageDimensionalityReduction() ITK_OVERRIDE + { + DimensionalityReductionModelFactoryType::CleanFactories(); + } + +private: + void DoInit() ITK_OVERRIDE + { + SetName("DimensionalityReduction"); + SetDescription("Performs dimensionality reduction of the input image " + "according to a dimensionality reduction model file."); + + // Documentation + SetDocName("DimensionalityReduction"); + SetDocLongDescription("This application reduces the dimension of an input" + " image, based on a machine learning model file produced by" + " the TrainDimensionalityReduction application. Pixels of the " + "output image will contain the reduced values from" + "the model. The input pixels" + " can be optionally centered and reduced according " + "to the statistics file produced by the " + "ComputeImagesStatistics application. "); + + SetDocLimitations("The input image must contain the feature bands used for" + " the model training. " + "If a statistics file was used during training by the " + "Training application, it is mandatory to use the same " + "statistics file for reduction."); + SetDocAuthors("OTB-Team"); + SetDocSeeAlso("TrainDimensionalityReduction, ComputeImagesStatistics"); + + AddDocTag(Tags::Learning); + + AddParameter(ParameterType_InputImage, "in", "Input Image"); + SetParameterDescription( "in", "The input image to predict."); + + AddParameter(ParameterType_InputImage, "mask", "Input Mask"); + SetParameterDescription( "mask", "The mask allow restricting " + "classification of the input image to the area where mask pixel values " + "are greater than 0."); + MandatoryOff("mask"); + + AddParameter(ParameterType_InputFilename, "model", "Model file"); + SetParameterDescription("model", "A dimensionality reduction model file (produced by " + "TrainRegression application)."); + + AddParameter(ParameterType_InputFilename, "imstat", "Statistics file"); + SetParameterDescription("imstat", "A XML file containing mean and standard" + " deviation to center and reduce samples before prediction " + "(produced by ComputeImagesStatistics application). If this file contains" + "one more bands than the sample size, the last stat of last band will be" + "applied to expand the output predicted value"); + MandatoryOff("imstat"); + + AddParameter(ParameterType_OutputImage, "out", "Output Image"); + SetParameterDescription( "out", "Output image containing reduced values"); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "QB_1_ortho.tif"); + SetDocExampleParameterValue("imstat", "EstimateImageStatisticsQB1.xml"); + SetDocExampleParameterValue("model", "clsvmModelQB1.model"); + SetDocExampleParameterValue("out", "ReducedImageQB1.tif"); + } + + void DoUpdateParameters() ITK_OVERRIDE + { + // Nothing to do here : all parameters are independent + } + + void DoExecute() ITK_OVERRIDE + { + // Load input image + FloatVectorImageType::Pointer inImage = GetParameterImage("in"); + inImage->UpdateOutputInformation(); + unsigned int nbFeatures = inImage->GetNumberOfComponentsPerPixel(); + + // Load DR model using a factory + otbAppLogINFO("Loading model"); + m_Model = DimensionalityReductionModelFactoryType::CreateDimensionalityReductionModel( + GetParameterString("model"), + DimensionalityReductionModelFactoryType::ReadMode); + + if (m_Model.IsNull()) + { + otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") + << " : unsupported model type"); + } + + m_Model->Load(GetParameterString("model")); + otbAppLogINFO("Model loaded, dimension = "<< m_Model->GetDimension()); + + // Classify + m_ClassificationFilter = DimensionalityReductionFilterType::New(); + m_ClassificationFilter->SetModel(m_Model); + + FloatVectorImageType::Pointer outputImage = m_ClassificationFilter->GetOutput(); + + // Normalize input image if asked + if( IsParameterEnabled("imstat") && HasValue("imstat") ) + { + otbAppLogINFO("Input image normalization activated."); + // Normalize input image (optional) + StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + m_Rescaler = RescalerType::New(); + + // Load input image statistics + statisticsReader->SetFileName(GetParameterString("imstat")); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + otbAppLogINFO( "mean used: " << meanMeasurementVector ); + otbAppLogINFO( "standard deviation used: " << stddevMeasurementVector ); + if (meanMeasurementVector.Size() != nbFeatures) + { + otbAppLogFATAL("Wrong number of components in statistics file : "<<meanMeasurementVector.Size()); + } + + // Rescale vector image + m_Rescaler->SetScale(stddevMeasurementVector); + m_Rescaler->SetShift(meanMeasurementVector); + m_Rescaler->SetInput(inImage); + + m_ClassificationFilter->SetInput(m_Rescaler->GetOutput()); + } + else + { + otbAppLogINFO("Input image normalization deactivated."); + m_ClassificationFilter->SetInput(inImage); + } + + if(IsParameterEnabled("mask")) + { + otbAppLogINFO("Using input mask"); + // Load mask image and cast into LabeledImageType + MaskImageType::Pointer inMask = GetParameterUInt8Image("mask"); + + m_ClassificationFilter->SetInputMask(inMask); + } + + SetParameterOutputImage<FloatVectorImageType>("out", outputImage); + } + + DimensionalityReductionFilterType::Pointer m_ClassificationFilter; + ModelPointerType m_Model; + RescalerType::Pointer m_Rescaler; + OutputRescalerType::Pointer m_OutRescaler; +}; + +} // end of namespace Wrapper +} // end of namespace otb + +OTB_APPLICATION_EXPORT(otb::Wrapper::ImageDimensionalityReduction) diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1cbc567c562948f356f55b84f0a4bf42a7f7b0da --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "otbOGRDataSourceWrapper.h" +#include "otbOGRFeatureWrapper.h" + +#include "itkVariableLengthVector.h" + +#include "otbShiftScaleSampleListFilter.h" +#include "otbStatisticsXMLFileReader.h" + +#include <fstream> // write the model file + +#include "otbDimensionalityReductionModelFactory.h" +#include "otbTrainDimensionalityReductionApplicationBase.h" + +namespace otb +{ +namespace Wrapper +{ + +/** + * \class TrainDimensionalityReduction + * + * Training of a dimensionality reduction model + */ +class TrainDimensionalityReduction : public TrainDimensionalityReductionApplicationBase<float,float> +{ +public: + typedef TrainDimensionalityReduction Self; + typedef TrainDimensionalityReductionApplicationBase<float, float> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + itkNewMacro(Self); + itkTypeMacro(TrainDimensionalityReduction, otb::Application); + + typedef Superclass::SampleType SampleType; + typedef Superclass::ListSampleType ListSampleType; + typedef Superclass::SampleImageType SampleImageType; + + typedef float ValueType; + typedef itk::VariableLengthVector<ValueType> MeasurementType; + + typedef otb::StatisticsXMLFileReader<SampleType> StatisticsReader; + + typedef otb::Statistics::ShiftScaleSampleListFilter<ListSampleType, ListSampleType> ShiftScaleFilterType; + + typedef otb::DimensionalityReductionModelFactory<ValueType, ValueType> ModelFactoryType; + +private: + void DoInit() + { + SetName("TrainDimensionalityReduction"); + SetDescription("Train a dimensionality reduction model"); + + SetDocName("Train Dimensionality Reduction"); + SetDocLongDescription("Trainer for dimensionality reduction algorithms " + "(autoencoders, PCA, SOM). All input samples are used to compute the " + "model, like other machine learning models.\n" + "The model can be used in the ImageDimensionalityReduction and " + "VectorDimensionalityReduction applications."); + + SetDocLimitations("None"); + SetDocAuthors("OTB-Team"); + SetDocSeeAlso("ImageDimensionalityReduction, VectorDimensionalityReduction"); + + AddParameter(ParameterType_Group, "io", "Input and output data"); + SetParameterDescription("io", "This group of parameters allows setting input and output data."); + + AddParameter(ParameterType_InputVectorData, "io.vd", "Input Vector Data"); + SetParameterDescription("io.vd", "Input geometries used for training (note " + ": all geometries from the layer will be used)"); + + AddParameter(ParameterType_OutputFilename, "io.out", "Output model"); + SetParameterDescription("io.out", "Output file containing the estimated model (.txt format)."); + + AddParameter(ParameterType_InputFilename, "io.stats", "Input XML image statistics file"); + MandatoryOff("io.stats"); + SetParameterDescription("io.stats", "XML file containing mean and variance of each feature."); + + AddParameter(ParameterType_StringList, "feat", "Field names to be used for training."); // + SetParameterDescription("feat","List of field names in the input vector data" + " used as features for training."); // + + Superclass::DoInit(); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("io.vd", "cuprite_samples.sqlite"); + SetDocExampleParameterValue("io.out", "mode.ae"); + SetDocExampleParameterValue("algorithm", "pca"); + SetDocExampleParameterValue("algorithm.pca.dim", "8"); + SetDocExampleParameterValue("feat","value_0 value_1 value_2 value_3 value_4" + " value_5 value_6 value_7 value_8 value_9"); + } + + void DoUpdateParameters() + { + } + + void DoExecute() + { + std::string shapefile = GetParameterString("io.vd"); + + otb::ogr::DataSource::Pointer source = + otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read); + otb::ogr::Layer layer = source->GetLayer(0); + ListSampleType::Pointer input = ListSampleType::New(); + const int nbFeatures = GetParameterStringList("feat").size(); + + input->SetMeasurementVectorSize(nbFeatures); + otb::ogr::Layer::const_iterator it = layer.cbegin(); + otb::ogr::Layer::const_iterator itEnd = layer.cend(); + for( ; it!=itEnd ; ++it) + { + MeasurementType mv; + mv.SetSize(nbFeatures); + for(int idx=0; idx < nbFeatures; ++idx) + { + mv[idx] = (*it)[GetParameterStringList("feat")[idx]].GetValue<double>(); + } + input->PushBack(mv); + } + + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + + if (HasValue("io.stats") && IsParameterEnabled("io.stats")) + { + StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + std::string XMLfile = GetParameterString("io.stats"); + statisticsReader->SetFileName(XMLfile); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + } + else + { + meanMeasurementVector.SetSize(nbFeatures); + meanMeasurementVector.Fill(0.); + stddevMeasurementVector.SetSize(nbFeatures); + stddevMeasurementVector.Fill(1.); + } + + ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); + trainingShiftScaleFilter->SetInput(input); + trainingShiftScaleFilter->SetShifts(meanMeasurementVector); + trainingShiftScaleFilter->SetScales(stddevMeasurementVector); + trainingShiftScaleFilter->Update(); + + ListSampleType::Pointer trainingListSample= trainingShiftScaleFilter->GetOutput(); + + this->Train(trainingListSample,GetParameterString("io.out")); + } + +}; + +} // end of namespace Wrapper +} // end of namespace otb + +OTB_APPLICATION_EXPORT(otb::Wrapper::TrainDimensionalityReduction) diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx new file mode 100644 index 0000000000000000000000000000000000000000..132e13875cbffdc0d6152601173c7a24e89afd9a --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" +#include "otbOGRDataSourceWrapper.h" +#include "otbOGRFeatureWrapper.h" +#include "itkVariableLengthVector.h" +#include "otbStatisticsXMLFileReader.h" +#include "itkListSample.h" +#include "otbShiftScaleSampleListFilter.h" +#include "otbDimensionalityReductionModelFactory.h" +#include <time.h> + +namespace otb +{ +namespace Wrapper +{ + +/** Utility function to negate std::isalnum */ +bool IsNotAlphaNum(char c) +{ +return !std::isalnum(c); +} + +/** + * \class VectorDimensionalityReduction + * + * Apply a dimensionality reduction model on a vector file + */ +class VectorDimensionalityReduction : public Application +{ +public: + /** Standard class typedefs. */ + typedef VectorDimensionalityReduction Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Standard macro */ + itkNewMacro(Self); + itkTypeMacro(Self, Application) + + /** Filters typedef */ + typedef float ValueType; + typedef itk::VariableLengthVector<ValueType> InputSampleType; + typedef itk::Statistics::ListSample<InputSampleType> ListSampleType; + typedef MachineLearningModel< + itk::VariableLengthVector<ValueType>, + itk::VariableLengthVector<ValueType> > DimensionalityReductionModelType; + typedef DimensionalityReductionModelFactory< + ValueType,ValueType> DimensionalityReductionModelFactoryType; + typedef DimensionalityReductionModelType::Pointer ModelPointerType; + + /** Statistics Filters typedef */ + typedef itk::VariableLengthVector<ValueType> MeasurementType; + typedef otb::StatisticsXMLFileReader<MeasurementType> StatisticsReader; + typedef otb::Statistics::ShiftScaleSampleListFilter< + ListSampleType, ListSampleType> ShiftScaleFilterType; + +protected: + ~VectorDimensionalityReduction() ITK_OVERRIDE + { + DimensionalityReductionModelFactoryType::CleanFactories(); + } + +private: + void DoInit() ITK_OVERRIDE + { + SetName("VectorDimensionalityReduction"); + SetDescription("Performs dimensionality reduction of the input vector data " + "according to a model file."); + SetDocName("Vector Dimensionality Reduction"); + SetDocAuthors("OTB-Team"); + SetDocLongDescription("This application performs a vector data " + "dimensionality reduction based on a model file produced by the " + "TrainDimensionalityReduction application."); + SetDocSeeAlso("TrainDimensionalityReduction"); + SetDocLimitations("None"); + AddDocTag(Tags::Learning); + + AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + SetParameterDescription("in","The input vector data to reduce."); + + AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); + SetParameterDescription("instat", "A XML file containing mean and standard " + "deviation to center and reduce samples before dimensionality reduction " + "(produced by ComputeImagesStatistics application)."); + MandatoryOff("instat"); + + AddParameter(ParameterType_InputFilename, "model", "Model file"); + SetParameterDescription("model", "A model file (produced by the " + "TrainDimensionalityReduction application,"); + + AddParameter(ParameterType_OutputFilename, "out", "Output vector data file " + "containing the reduced vector"); + SetParameterDescription("out","Output vector data file storing sample " + "values (OGR format). If not given, the input vector data file is used. " + "In overwrite mode, the original features will be lost."); + MandatoryOff("out"); + + AddParameter(ParameterType_ListView, "feat", "Input features to use for reduction."); // + SetParameterDescription("feat","List of field names in the input vector " + "data used as features for reduction."); // + + AddParameter(ParameterType_Choice, "featout", "Output feature"); // + SetParameterDescription("featout", "Naming of output features"); + + AddChoice("featout.prefix", "Prefix"); + SetParameterDescription("featout.prefix", "Use a name prefix"); + + AddParameter(ParameterType_String, "featout.prefix.name", "Feature name prefix"); + SetParameterDescription("featout.prefix.name","Name prefix for output " + "features. This prefix is followed by the numeric index of each output feature."); + SetParameterString("featout.prefix.name","reduced_", false); + + AddChoice("featout.list","List"); + SetParameterDescription("featout.list", "Use a list with all names"); + + AddParameter(ParameterType_StringList, "featout.list.names", "Feature name list"); + SetParameterDescription("featout.list.names","List of field names for the output " + "features which result from the reduction."); // + + AddParameter(ParameterType_Int, "pcadim", "Principal component dimension"); // + SetParameterDescription("pcadim","This optional parameter can be set to " + "reduce the number of eignevectors used in the PCA model file. This " + "parameter can't be used for other models"); // + MandatoryOff("pcadim"); + + AddParameter(ParameterType_Choice, "mode", "Writting mode"); // + SetParameterDescription("mode", "This parameter determines if the output " + "file is overwritten or updated [overwrite/update]. If an output file " + "name is given, the original file is copied before creating the new features."); + + AddChoice("mode.overwrite", "Overwrite"); + SetParameterDescription("mode.overwrite","Overwrite mode"); // + + AddChoice("mode.update", "Update"); + SetParameterDescription("mode.update", "Update mode"); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "vectorData.shp"); + SetDocExampleParameterValue("instat", "meanVar.xml"); + SetDocExampleParameterValue("model", "model.txt"); + SetDocExampleParameterValue("out", "vectorDataOut.shp"); + SetDocExampleParameterValue("feat", "perimeter area width"); + //SetOfficialDocLink(); + } + + void DoUpdateParameters() ITK_OVERRIDE + { + if ( HasValue("in") ) + { + std::string shapefile = GetParameterString("in"); + otb::ogr::DataSource::Pointer ogrDS; + OGRSpatialReference oSRS(""); + std::vector<std::string> options; + ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read); + otb::ogr::Layer layer = ogrDS->GetLayer(0); + OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); + ClearChoices("feat"); + + for(int iField=0; iField< layerDefn.GetFieldCount(); iField++) + { + std::string item = layerDefn.GetFieldDefn(iField)->GetNameRef(); + std::string key(item); + std::string::iterator end = std::remove_if( key.begin(), key.end(), IsNotAlphaNum ); + std::transform( key.begin(), end, key.begin(), tolower ); + std::string tmpKey = "feat." + key.substr( 0, static_cast<unsigned long>( end - key.begin() ) ); + AddChoice(tmpKey,item); + } + } + } + + void DoExecute() ITK_OVERRIDE + { + clock_t tic = clock(); + + std::string shapefile = GetParameterString("in"); + otb::ogr::DataSource::Pointer source = otb::ogr::DataSource::New( + shapefile, otb::ogr::DataSource::Modes::Read); + otb::ogr::Layer layer = source->GetLayer(0); + ListSampleType::Pointer input = ListSampleType::New(); + std::vector<int> inputIndexes = GetSelectedItems("feat"); + int nbFeatures = inputIndexes.size(); + + input->SetMeasurementVectorSize(nbFeatures); + otb::ogr::Layer::const_iterator it = layer.cbegin(); + otb::ogr::Layer::const_iterator itEnd = layer.cend(); + + // Get the list of non-selected field indexes + // /!\ The 'feat' is assumed to expose all available fields, hence the + // mapping between GetSelectedItems() and OGR field indexes + OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); + std::set<int> otherInputFields; + for (int i=0 ; i < inLayerDefn.GetFieldCount() ; i++) + otherInputFields.insert(i); + for (int k=0 ; k < nbFeatures ; k++) + otherInputFields.erase(inputIndexes[k]); + + for( ; it!=itEnd ; ++it) + { + MeasurementType mv; + mv.SetSize(nbFeatures); + + for(int idx=0; idx < nbFeatures; ++idx) + { + mv[idx] = static_cast<float>( (*it)[inputIndexes[idx]].GetValue<double>() ); + } + input->PushBack(mv); + } + + /** Statistics for shift/scale */ + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + + if (HasValue("instat") && IsParameterEnabled("instat")) + { + StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + std::string XMLfile = GetParameterString("instat"); + statisticsReader->SetFileName(XMLfile); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + otbAppLogINFO("Mean used: " << meanMeasurementVector); + otbAppLogINFO("Standard deviation used: " << stddevMeasurementVector); + } + else + { + meanMeasurementVector.SetSize(nbFeatures); + meanMeasurementVector.Fill(0.); + stddevMeasurementVector.SetSize(nbFeatures); + stddevMeasurementVector.Fill(1.); + } + + ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); + trainingShiftScaleFilter->SetInput(input); + trainingShiftScaleFilter->SetShifts(meanMeasurementVector); + trainingShiftScaleFilter->SetScales(stddevMeasurementVector); + trainingShiftScaleFilter->Update(); + + otbAppLogINFO("Loading model"); + /** Read the model */ + m_Model = DimensionalityReductionModelFactoryType::CreateDimensionalityReductionModel( + GetParameterString("model"), + DimensionalityReductionModelFactoryType::ReadMode); + if (m_Model.IsNull()) + { + otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") + << " : unsupported model type"); + } + m_Model->Load(GetParameterString("model")); + if (HasValue("pcadim") && IsParameterEnabled("pcadim")) + { + std::string modelName(m_Model->GetNameOfClass()); + if (modelName != "PCAModel") + { + otbAppLogFATAL(<< "Can't set 'pcadim' on a model : "<< modelName); + } + m_Model->SetDimension( GetParameterInt("pcadim") ); + } + otbAppLogINFO("Model loaded, dimension : "<< m_Model->GetDimension()); + + /** Perform Dimensionality Reduction */ + ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); + ListSampleType::Pointer target = m_Model->PredictBatch(listSample); + + /** Create/Update Output Shape file */ + ogr::DataSource::Pointer output; + ogr::DataSource::Pointer buffer = ogr::DataSource::New(); + bool updateMode = false; + + if (IsParameterEnabled("out") && HasValue("out")) + { + // Create new OGRDataSource + if (GetParameterString("mode")=="overwrite") + { + output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); + otb::ogr::Layer newLayer = output->CreateLayer( + GetParameterString("out"), + const_cast<OGRSpatialReference*>(layer.GetSpatialRef()), + layer.GetGeomType()); + // Copy existing fields except the ones selected for reduction + for (const int& k : otherInputFields) + { + OGRFieldDefn fieldDefn(inLayerDefn.GetFieldDefn(k)); + newLayer.CreateField(fieldDefn); + } + } + else if (GetParameterString("mode")=="update") + { + //output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Update_LayerCreateOnly); + // Update mode + otb::ogr::DataSource::Pointer source_output = + otb::ogr::DataSource::New(GetParameterString("out"), otb::ogr::DataSource::Modes::Read); + layer = source_output->GetLayer(0); + updateMode = true; + otbAppLogINFO("Update input vector data."); + + // fill temporary buffer for the transfer + otb::ogr::Layer inputLayer = layer; + layer = buffer->CopyLayer(inputLayer, std::string("Buffer")); + // close input data source + source_output->Clear(); + // Re-open input data source in update mode + output = otb::ogr::DataSource::New( + GetParameterString("out"), + otb::ogr::DataSource::Modes::Update_LayerUpdate); + } + else + { + otbAppLogFATAL(<< "Error when creating the output file" << + GetParameterString("mode") << " : unsupported writting mode type"); + } + } + + otb::ogr::Layer outLayer = output->GetLayer(0); + OGRErr errStart = outLayer.ogr().StartTransaction(); + + if (errStart != OGRERR_NONE) + { + otbAppLogFATAL(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); + } + + // Build the list of output fields + std::vector<std::string> outFields; + if(GetParameterString("featout") == "prefix") + { + std::string prefix = GetParameterString("featout.prefix.name"); + std::ostringstream oss; + for (unsigned int i=0 ; i < m_Model->GetDimension() ; i++) + { + oss.str(prefix); + oss.seekp(0,std::ios_base::end); + oss << i; + outFields.push_back(oss.str()); + } + } + else if(GetParameterString("featout") == "list") + { + outFields = GetParameterStringList("featout.list.names"); + if (outFields.size() != m_Model->GetDimension()) + { + otbAppLogFATAL( << "Wrong number of output field names, expected " + << m_Model->GetDimension() << " , got "<< outFields.size()); + } + } + else + { + otbAppLogFATAL( << "Unsupported output feature mode : " + << GetParameterString("featout")); + } + + // Add the field of prediction in the output layer if field not exist + for (unsigned int i=0; i<outFields.size() ;i++) + { + OGRFeatureDefn &layerDefn = outLayer.GetLayerDefn(); + int idx = layerDefn.GetFieldIndex(outFields[i].c_str()); + + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) + otbAppLogFATAL("Field name "<< outFields[i] + << " already exists with a different type!"); + } + else + { + OGRFieldDefn predictedField(outFields[i].c_str(), OFTReal); + ogr::FieldDefn predictedFieldDef(predictedField); + outLayer.CreateField(predictedFieldDef); + } + } + + // Fill output layer + unsigned int count=0; + it = layer.cbegin(); + itEnd = layer.cend(); + for( ; it!=itEnd ; ++it, ++count) + { + ogr::Feature dstFeature(outLayer.GetLayerDefn()); + + dstFeature.SetFrom( *it , TRUE); + dstFeature.SetFID(it->GetFID()); + + for (std::size_t i=0; i<outFields.size(); ++i) + { + dstFeature[outFields[i]].SetValue<double>(target->GetMeasurementVector(count)[i]); + } + if (updateMode) + { + outLayer.SetFeature(dstFeature); + } + else + { + outLayer.CreateFeature(dstFeature); + } + } + + if(outLayer.ogr().TestCapability("Transactions")) + { + const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); + if (errCommitX != OGRERR_NONE) + { + otbAppLogFATAL(<< "Unable to commit transaction for OGR layer " << + outLayer.ogr().GetName() << "."); + } + } + output->SyncToDisk(); + clock_t toc = clock(); + otbAppLogINFO( "Elapsed: "<< ((double)(toc - tic) / CLOCKS_PER_SEC)<<" seconds."); + } + + ModelPointerType m_Model; +}; + +} // end of namespace Wrapper +} // end of namespace otb + +OTB_APPLICATION_EXPORT(otb::Wrapper::VectorDimensionalityReduction) diff --git a/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainAutoencoder.txx b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainAutoencoder.txx new file mode 100644 index 0000000000000000000000000000000000000000..f474167e38be7fe6f2a8e56fc8838811afec789b --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainAutoencoder.txx @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbDimensionalityReductionTrainAutoencoder_txx +#define otbDimensionalityReductionTrainAutoencoder_txx + +#include "otbTrainDimensionalityReductionApplicationBase.h" +#include "otbAutoencoderModel.h" + +namespace otb +{ +namespace Wrapper +{ + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::InitAutoencoderParams() +{ + AddChoice("algorithm.autoencoder", "Shark Autoencoder"); + SetParameterDescription("algorithm.autoencoder", + "This group of parameters allows setting Shark autoencoder parameters. " + ); + + //Number Of Iterations + AddParameter(ParameterType_Int, "algorithm.autoencoder.nbiter", + "Maximum number of iterations during training"); + SetParameterInt("algorithm.autoencoder.nbiter",100, false); + SetParameterDescription( + "algorithm.autoencoder.nbiter", + "The maximum number of iterations used during training."); + + AddParameter(ParameterType_Int, "algorithm.autoencoder.nbiterfinetuning", + "Maximum number of iterations during training"); + SetParameterInt("algorithm.autoencoder.nbiterfinetuning",0, false); + SetParameterDescription( + "algorithm.autoencoder.nbiterfinetuning", + "The maximum number of iterations used during fine tuning of the whole network."); + + AddParameter(ParameterType_Float, "algorithm.autoencoder.epsilon", + "Epsilon"); + SetParameterFloat("algorithm.autoencoder.epsilon",0, false); + SetParameterDescription( + "algorithm.autoencoder.epsilon", + "Epsilon"); + + AddParameter(ParameterType_Float, "algorithm.autoencoder.initfactor", + "Weight initialization factor"); + SetParameterFloat("algorithm.autoencoder.initfactor",1, false); + SetParameterDescription( + "algorithm.autoencoder.initfactor", "Parameter that control the weight initialization of the autoencoder"); + + //Number Of Hidden Neurons + AddParameter(ParameterType_StringList, "algorithm.autoencoder.nbneuron", "Size"); + SetParameterDescription( + "algorithm.autoencoder.nbneuron", + "The number of neurons in each hidden layer."); + + //Regularization + AddParameter(ParameterType_StringList, "algorithm.autoencoder.regularization", "Strength of the regularization"); + SetParameterDescription("algorithm.autoencoder.regularization", + "Strength of the L2 regularization used during training"); + + //Noise strength + AddParameter(ParameterType_StringList, "algorithm.autoencoder.noise", "Strength of the noise"); + SetParameterDescription("algorithm.autoencoder.noise", + "Strength of the noise"); + + // Sparsity parameter + AddParameter(ParameterType_StringList, "algorithm.autoencoder.rho", "Sparsity parameter"); + SetParameterDescription("algorithm.autoencoder.rho", + "Sparsity parameter"); + + // Sparsity regularization strength + AddParameter(ParameterType_StringList, "algorithm.autoencoder.beta", "Sparsity regularization strength"); + SetParameterDescription("algorithm.autoencoder.beta", + "Sparsity regularization strength"); + + AddParameter(ParameterType_OutputFilename, "algorithm.autoencoder.learningcurve", "Learning curve"); + SetParameterDescription("algorithm.autoencoder.learningcurve", "Learning error values"); + MandatoryOff("algorithm.autoencoder.learningcurve"); +} + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::BeforeTrainAutoencoder(typename ListSampleType::Pointer trainingListSample, + std::string modelPath) +{ + typedef shark::LogisticNeuron NeuronType; + typedef otb::AutoencoderModel<InputValueType, NeuronType> AutoencoderModelType; + TrainAutoencoder<AutoencoderModelType>(trainingListSample,modelPath); +} + +template <class TInputValue, class TOutputValue> +template <typename autoencoderchoice> +void TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue>::TrainAutoencoder(typename ListSampleType::Pointer trainingListSample,std::string modelPath) +{ + typename autoencoderchoice::Pointer dimredTrainer = autoencoderchoice::New(); + itk::Array<unsigned int> nb_neuron; + itk::Array<float> noise; + itk::Array<float> regularization; + itk::Array<float> rho; + itk::Array<float> beta; + std::vector<std::basic_string<char>> s_nbneuron= GetParameterStringList("algorithm.autoencoder.nbneuron"); + std::vector<std::basic_string<char>> s_noise= GetParameterStringList("algorithm.autoencoder.noise"); + std::vector<std::basic_string<char>> s_regularization= GetParameterStringList("algorithm.autoencoder.regularization"); + std::vector<std::basic_string<char>> s_rho= GetParameterStringList("algorithm.autoencoder.rho"); + std::vector<std::basic_string<char>> s_beta= GetParameterStringList("algorithm.autoencoder.beta"); + nb_neuron.SetSize(s_nbneuron.size()); + noise.SetSize(s_nbneuron.size()); + regularization.SetSize(s_nbneuron.size()); + rho.SetSize(s_nbneuron.size()); + beta.SetSize(s_nbneuron.size()); + for (unsigned int i=0; i<s_nbneuron.size(); i++) + { + nb_neuron[i]=std::stoi(s_nbneuron[i]); + noise[i]=std::stof(s_noise[i]); + regularization[i]=std::stof(s_regularization[i]); + rho[i]=std::stof(s_rho[i]); + beta[i]=std::stof(s_beta[i]); + } + dimredTrainer->SetNumberOfHiddenNeurons(nb_neuron); + dimredTrainer->SetNumberOfIterations(GetParameterInt("algorithm.autoencoder.nbiter")); + dimredTrainer->SetNumberOfIterationsFineTuning(GetParameterInt("algorithm.autoencoder.nbiterfinetuning")); + dimredTrainer->SetEpsilon(GetParameterFloat("algorithm.autoencoder.epsilon")); + dimredTrainer->SetInitFactor(GetParameterFloat("algorithm.autoencoder.initfactor")); + dimredTrainer->SetRegularization(regularization); + dimredTrainer->SetNoise(noise); + dimredTrainer->SetRho(rho); + dimredTrainer->SetBeta(beta); + dimredTrainer->SetWriteWeights(true); + if (HasValue("algorithm.autoencoder.learningcurve") && + IsParameterEnabled("algorithm.autoencoder.learningcurve")) + { + dimredTrainer->SetWriteLearningCurve(true); + dimredTrainer->SetLearningCurveFileName(GetParameterString("algorithm.autoencoder.learningcurve")); + } + + dimredTrainer->SetInputListSample(trainingListSample); + dimredTrainer->Train(); + dimredTrainer->Save(modelPath); +} + +} //end namespace wrapper +} //end namespace otb + +#endif diff --git a/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainPCA.txx b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainPCA.txx new file mode 100644 index 0000000000000000000000000000000000000000..03016916cb0186d118f57a95ee726b80f69486d5 --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainPCA.txx @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbDimensionalityReductionTrainPCA_txx +#define otbDimensionalityReductionTrainPCA_txx + +#include "otbTrainDimensionalityReductionApplicationBase.h" +#include "otbPCAModel.h" + +namespace otb +{ +namespace Wrapper +{ + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::InitPCAParams() +{ + AddChoice("algorithm.pca", "Shark PCA"); + SetParameterDescription("algorithm.pca", + "This group of parameters allows setting Shark PCA parameters. " + ); + + //Output Dimension + AddParameter(ParameterType_Int, "algorithm.pca.dim", + "Dimension of the output of the pca transformation"); + SetParameterInt("algorithm.pca.dim",10, false); + SetParameterDescription( + "algorithm.pca.dim", + "Dimension of the output of the pca transformation."); +} + +template <class TInputValue, class TOutputValue> +void TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::TrainPCA(typename ListSampleType::Pointer trainingListSample,std::string modelPath) +{ + typedef otb::PCAModel<InputValueType> PCAModelType; + typename PCAModelType::Pointer dimredTrainer = PCAModelType::New(); + dimredTrainer->SetDimension(GetParameterInt("algorithm.pca.dim")); + dimredTrainer->SetInputListSample(trainingListSample); + dimredTrainer->SetWriteEigenvectors(true); + dimredTrainer->Train(); + dimredTrainer->Save(modelPath); +} + +} //end namespace wrapper +} //end namespace otb + +#endif diff --git a/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainSOM.txx b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainSOM.txx new file mode 100644 index 0000000000000000000000000000000000000000..51cdd9e1acf1ededba9b54f93260e10c16962572 --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/include/otbDimensionalityReductionTrainSOM.txx @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbDimensionalityReductionTrainSOM_txx +#define otbDimensionalityReductionTrainSOM_txx +#include "otbTrainDimensionalityReductionApplicationBase.h" +#include "otbSOMModel.h" + +namespace otb +{ +namespace Wrapper +{ + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::InitSOMParams() +{ + AddChoice("algorithm.som", "OTB SOM"); + SetParameterDescription("algorithm.som", + "This group of parameters allows setting SOM parameters. "); + + AddParameter(ParameterType_StringList , "algorithm.som.s", "Map size"); + SetParameterDescription("algorithm.som.s", "Sizes of the SOM map (one per " + "dimension). For instance, [12;15] means a 2D map of size 12x15. Support" + "2D to 5D maps."); + MandatoryOff("algorithm.som.s"); + + AddParameter(ParameterType_StringList , "algorithm.som.n", "Neighborhood sizes"); + SetParameterDescription("algorithm.som.n", "Sizes of the initial neighborhood " + "in the SOM map (one per dimension). The number of sizes should be the same" + " as the map sizes"); + MandatoryOff("algorithm.som.n"); + + AddParameter(ParameterType_Int, "algorithm.som.ni", "NumberIteration"); + SetParameterDescription("algorithm.som.ni", "Number of iterations for SOM learning"); + MandatoryOff("algorithm.som.ni"); + + AddParameter(ParameterType_Float, "algorithm.som.bi", "BetaInit"); + SetParameterDescription("algorithm.som.bi", "Initial learning coefficient"); + MandatoryOff("algorithm.som.bi"); + + AddParameter(ParameterType_Float, "algorithm.som.bf", "BetaFinal"); + SetParameterDescription("algorithm.som.bf", "Final learning coefficient"); + MandatoryOff("algorithm.som.bf"); + + AddParameter(ParameterType_Float, "algorithm.som.iv", "InitialValue"); + SetParameterDescription("algorithm.som.iv", "Maximum initial neuron weight"); + MandatoryOff("algorithm.som.iv"); + + std::vector<std::string> size(2, std::string("10")); + std::vector<std::string> radius(2, std::string("3")); + SetParameterStringList("algorithm.som.s", size, false); + SetParameterStringList("algorithm.som.n", radius, false); + DisableParameter("algorithm.som.s"); + DisableParameter("algorithm.som.n"); + + SetDefaultParameterInt("algorithm.som.ni", 5); + SetDefaultParameterFloat("algorithm.som.bi", 1.0); + SetDefaultParameterFloat("algorithm.som.bf", 0.1); + SetDefaultParameterFloat("algorithm.som.iv", 10.0); +} + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, + std::string modelPath) +{ + std::vector<std::string> s = GetParameterStringList("algorithm.som.s"); + int SomDim = s.size(); + + if(SomDim == 2) + { + typedef otb::SOMModel<InputValueType, 2> SOM2DModelType; + TrainSOM<SOM2DModelType >(trainingListSample,modelPath); + } + + if(SomDim == 3) + { + typedef otb::SOMModel<InputValueType, 3> SOM3DModelType; + TrainSOM<SOM3DModelType >(trainingListSample,modelPath); + } + + if(SomDim == 4) + { + typedef otb::SOMModel<InputValueType, 4> SOM4DModelType; + TrainSOM<SOM4DModelType >(trainingListSample,modelPath); + } + + if(SomDim == 5) + { + typedef otb::SOMModel<InputValueType, 5> SOM5DModelType; + TrainSOM<SOM5DModelType >(trainingListSample,modelPath); + } + if(SomDim > 5 || SomDim < 2) + { + otbAppLogFATAL(<< "Invalid number of dimensions : " << SomDim << + ". Only support 2, 3, 4 or 5 dimensions"); + } +} + +template <class TInputValue, class TOutputValue> +template <typename TSOM> +void TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::TrainSOM(typename ListSampleType::Pointer trainingListSample,std::string modelPath) +{ + typename TSOM::Pointer dimredTrainer = TSOM::New(); + dimredTrainer->SetNumberOfIterations(GetParameterInt("algorithm.som.ni")); + dimredTrainer->SetBetaInit(GetParameterFloat("algorithm.som.bi")); + dimredTrainer->SetWriteMap(true); + dimredTrainer->SetBetaEnd(GetParameterFloat("algorithm.som.bf")); + dimredTrainer->SetMaxWeight(GetParameterFloat("algorithm.som.iv")); + typename TSOM::SizeType size; + std::vector<std::string> s = GetParameterStringList("algorithm.som.s"); + for (unsigned int i=0; i<s.size(); i++) + { + size[i]=boost::lexical_cast<unsigned int>(s[i]); + } + + dimredTrainer->SetMapSize(size); + typename TSOM::SizeType radius; + std::vector<std::string> n = GetParameterStringList("algorithm.som.n"); + if (n.size() != s.size()) + { + otbAppLogFATAL(<< "Wrong number of neighborhood radii : expected "<< s.size() << " ; got "<< n.size()); + } + for (unsigned int i=0; i < n.size(); i++) + { + radius[i]=boost::lexical_cast<unsigned int>(n[i]); + } + dimredTrainer->SetNeighborhoodSizeInit(radius); + dimredTrainer->SetInputListSample(trainingListSample); + dimredTrainer->Train(); + dimredTrainer->Save(modelPath); +} + +} //end namespace wrapper +} //end namespace otb + +#endif diff --git a/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.h b/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.h new file mode 100644 index 0000000000000000000000000000000000000000..b0a2ae847ac0595c1744c73117a9c4d711bc93a9 --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbTrainDimensionalityReductionApplicationBase_h +#define otbTrainDimensionalityReductionApplicationBase_h + +#include "otbConfigure.h" +#include "otbWrapperApplication.h" +#include "otbDimensionalityReductionModelFactory.h" + +// ListSample +#include "itkListSample.h" +#include "itkVariableLengthVector.h" + +#include <iostream> + +namespace otb +{ +namespace Wrapper +{ + +/** \class LearningApplicationBase + * \brief LearningApplicationBase is the base class for application that + * use machine learning model. + * + * This base class offers a DoInit() method to initialize all the parameters + * related to machine learning models. They will all be in the choice parameter + * named "classifier". The class also offers generic Train() and Classify() + * methods. The classes derived from LearningApplicationBase only need these + * 3 methods to handle the machine learning model. + * + * There are multiple machine learning models in OTB, some imported + * from OpenCV and one imported from LibSVM. They all have + * different parameters. The purpose of this class is to handle the + * creation of all parameters related to machine learning models (in + * DoInit() ), and to dispatch the calls to specific train functions + * in function Train(). + * + * This class is templated over scalar types for input and output values. + * Typically, the input value type will be either float of double. The choice + * of an output value type depends on the learning mode. This base class + * supports both classification and regression modes. For classification + * (enabled by default), the output value type corresponds to a class + * identifier so integer types suit well. For regression, the output value + * should not be an integer type, but rather a floating point type. In addition, + * an application deriving this base class for regression should initialize + * the m_RegressionFlag to true in their constructor. + * + * \sa TrainImagesClassifier + * \sa TrainRegression + * + * \ingroup OTBAppDimensionalityReduction + */ +template <class TInputValue, class TOutputValue> +class TrainDimensionalityReductionApplicationBase: public Application +{ +public: + /** Standard class typedefs. */ + typedef TrainDimensionalityReductionApplicationBase Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Standard macro */ + itkTypeMacro(TrainDimensionalityReductionApplicationBase, otb::Application) + + typedef TInputValue InputValueType; + typedef TOutputValue OutputValueType; + + typedef otb::VectorImage<InputValueType> SampleImageType; + typedef typename SampleImageType::PixelType PixelType; + + typedef otb::DimensionalityReductionModelFactory< + InputValueType, OutputValueType> ModelFactoryType; + typedef typename ModelFactoryType::DimensionalityReductionModelTypePointer ModelPointerType; + typedef typename ModelFactoryType::DimensionalityReductionModelType ModelType; + + typedef typename ModelType::InputSampleType SampleType; + typedef typename ModelType::InputListSampleType ListSampleType; + +protected: + TrainDimensionalityReductionApplicationBase(); + ~TrainDimensionalityReductionApplicationBase() override; + + /** Generic method to train and save the machine learning model. This method + * uses specific train methods depending on the chosen model.*/ + void Train(typename ListSampleType::Pointer trainingListSample, + std::string modelPath); + + /** Generic method to load a model file and use it to classify a sample list*/ + void Reduce(typename ListSampleType::Pointer validationListSample, + std::string modelPath); + + /** Init method that creates all the parameters for machine learning models */ + void DoInit() override; + +private: + + /** Specific Init and Train methods for each machine learning model */ + + void InitSOMParams(); + template <class somchoice> + void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath); + void BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath); + +#ifdef OTB_USE_SHARK + void InitAutoencoderParams(); + void InitPCAParams(); + + void BeforeTrainAutoencoder(typename ListSampleType::Pointer trainingListSample, std::string modelPath); + template <class autoencoderchoice> + void TrainAutoencoder(typename ListSampleType::Pointer trainingListSample, std::string modelPath); + + void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath); +#endif +}; + +} // end of namespace Wrapper +} // end of namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbTrainDimensionalityReductionApplicationBase.txx" +#include "otbDimensionalityReductionTrainSOM.txx" + +#ifdef OTB_USE_SHARK +#include "otbDimensionalityReductionTrainAutoencoder.txx" +#include "otbDimensionalityReductionTrainPCA.txx" +#endif +#endif + +#endif diff --git a/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.txx b/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.txx new file mode 100644 index 0000000000000000000000000000000000000000..057541017693139268c1039820dc3febde93562b --- /dev/null +++ b/Modules/Applications/AppDimensionalityReduction/include/otbTrainDimensionalityReductionApplicationBase.txx @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbTrainDimensionalityReductionApplicationBase_txx +#define otbTrainDimensionalityReductionApplicationBase_txx + +#include "otbTrainDimensionalityReductionApplicationBase.h" + +namespace otb +{ +namespace Wrapper +{ + +template <class TInputValue, class TOutputValue> +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::TrainDimensionalityReductionApplicationBase() +{ +} + +template <class TInputValue, class TOutputValue> +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::~TrainDimensionalityReductionApplicationBase() +{ + ModelFactoryType::CleanFactories(); +} + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::DoInit() +{ + AddDocTag(Tags::Learning); + + // main choice parameter that will contain all dimensionality reduction options + AddParameter(ParameterType_Choice, "algorithm", "algorithm to use for the training"); + SetParameterDescription("algorithm", "Choice of the dimensionality reduction " + "algorithm to use for the training."); + + InitSOMParams(); + +#ifdef OTB_USE_SHARK + InitAutoencoderParams(); + InitPCAParams(); +#endif + +} + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::Reduce(typename ListSampleType::Pointer /*validationListSample*/,std::string /*modelPath*/) +{ +} + +template <class TInputValue, class TOutputValue> +void +TrainDimensionalityReductionApplicationBase<TInputValue,TOutputValue> +::Train( + typename ListSampleType::Pointer trainingListSample, + std::string modelPath) +{ + // get the name of the chosen machine learning model + const std::string modelName = GetParameterString("algorithm"); + // call specific train function + + if(modelName == "som") + { + BeforeTrainSOM(trainingListSample,modelPath); + } + + if(modelName == "autoencoder") + { +#ifdef OTB_USE_SHARK + BeforeTrainAutoencoder(trainingListSample,modelPath); +#else + otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration."); +#endif + } + + if(modelName == "pca") + { +#ifdef OTB_USE_SHARK + TrainPCA(trainingListSample,modelPath); +#else + otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration."); +#endif + } +} + +} // end of namespace Wrapper +} // end of namespace otb + +#endif diff --git a/Modules/Applications/AppDimensionalityReduction/otb-module.cmake b/Modules/Applications/AppDimensionalityReduction/otb-module.cmake index 2ee3b794a6d9741a7b7cb1a5ed15b6620702a77e..4b1a936de279cec5f16b1e9a7eb4c7839dc17379 100644 --- a/Modules/Applications/AppDimensionalityReduction/otb-module.cmake +++ b/Modules/Applications/AppDimensionalityReduction/otb-module.cmake @@ -25,9 +25,11 @@ otb_module(OTBAppDimensionalityReduction DEPENDS OTBImageManipulation OTBStatistics + OTBIOXML OTBApplicationEngine OTBDimensionalityReduction - TEST_DEPENDS + OTBDimensionalityReductionLearning + TEST_DEPENDS OTBTestKernel OTBCommandLine diff --git a/Modules/Applications/AppDimensionalityReduction/test/CMakeLists.txt b/Modules/Applications/AppDimensionalityReduction/test/CMakeLists.txt index 78737f6b82196796969f11363608af24814f5a62..0ec91c997978405bee777e5c9b230cbc9f977350 100644 --- a/Modules/Applications/AppDimensionalityReduction/test/CMakeLists.txt +++ b/Modules/Applications/AppDimensionalityReduction/test/CMakeLists.txt @@ -38,3 +38,58 @@ otb_test_application(NAME apTvFEDimensionalityReductionPCA ${BASELINE}/bfTvPCAImageFilter3.tif ${TEMP}/apTvChDimensionalityReductionPCA.tif) +#------------------------------------------------------------------------------- +set(algos ae pca som) + +set(ae_params +-algorithm autoencoder +-algorithm.autoencoder.nbneuron 8 +-algorithm.autoencoder.regularization 0.01 +-algorithm.autoencoder.noise 0 +-algorithm.autoencoder.rho 0 +-algorithm.autoencoder.beta 0) + +set(pca_params +-algorithm pca +-algorithm.pca.dim 8) + +set(som_params +-algorithm som +-algorithm.som.s 10 10 +-algorithm.som.n 3 3 +-algorithm.som.ni 10) + +foreach(algo ${algos}) + string(TOUPPER ${algo} ualgo) + #------------------ TrainDimensionalityReduction TESTS------------------------ + otb_test_application(NAME apTvDrTrainDimensionalityReduction${ualgo} + APP TrainDimensionalityReduction + OPTIONS -io.vd ${INPUTDATA}/cuprite_samples.sqlite + -io.out ${TEMP}/cuprite_DRModel.${algo} + -io.stats ${INPUTDATA}/cupriteStats.xml + -feat value_0 value_1 value_2 value_3 value_4 value_5 value_6 value_7 value_8 value_9 + ${${algo}_params}) + + #------------------ ImageDimensionalityReduction TESTS------------------------ + otb_test_application(NAME apTvDrImageDimensionalityReduction${ualgo} + APP ImageDimensionalityReduction + OPTIONS -in ${INPUTDATA}/cupriteSubHsi.tif + -model ${TEMP}/cuprite_DRModel.${algo} + -imstat ${INPUTDATA}/cupriteStats.xml + -out ${TEMP}/cupriteReduced_${algo}.tif) + + set_tests_properties( apTvDrImageDimensionalityReduction${ualgo} + PROPERTIES DEPENDS apTvDrTrainDimensionalityReduction${ualgo}) + + #------------------ VectorDimensionalityReduction TESTS----------------------- + otb_test_application(NAME apTvDrVectorDimensionalityReduction${ualgo} + APP VectorDimensionalityReduction + OPTIONS -in ${INPUTDATA}/cuprite_samples.sqlite + -model ${TEMP}/cuprite_DRModel.${algo} + -instat ${INPUTDATA}/cupriteStats.xml + -out ${TEMP}/cupriteReduced_${algo}.sqlite + -feat value_0 value_1 value_2 value_3 value_4 value_5 value_6 value_7 value_8 value_9) + + set_tests_properties( apTvDrVectorDimensionalityReduction${ualgo} + PROPERTIES DEPENDS apTvDrTrainDimensionalityReduction${ualgo}) +endforeach() diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx index c853f4863b75e799d10a1199098cffae48640792..e66c5a35fc92a4c7a129b0ddc5c565208e5ab6af 100644 --- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx +++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx @@ -134,7 +134,7 @@ private: AddChoice("mode.fft", "FFT transform"); SetParameterDescription("mode.fft", "FFT transform"); - AddParameter(ParameterType_Empty, "mode.fft.shift", "Shift fft transform"); + AddParameter(ParameterType_Bool, "mode.fft.shift", "Shift fft transform"); SetParameterDescription("mode.fft.shift", "Shift transform of fft filter"); AddChoice("mode.wavelet", "Wavelet"); @@ -152,8 +152,8 @@ private: AddChoice("mode.wavelet.form.sym8", "SYMLET8"); // Default values for mode - SetParameterString("mode", "wavelet", false); - SetParameterString("mode.wavelet.form", "haar", false); + SetParameterString("mode", "wavelet"); + SetParameterString("mode.wavelet.form", "haar"); AddParameter(ParameterType_Choice,"direction", "Direction"); AddChoice("direction.forward", "Forward"); @@ -263,7 +263,7 @@ private: else { // fft ttransform - bool shift = IsParameterEnabled( "mode.fft.shift"); + bool shift = GetParameterInt( "mode.fft.shift"); typedef otb::Image< std::complex<OutputPixelType> > ComplexOutputImageType; if (dir == 0 ) diff --git a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx index 45bc66c51d3562a5850bf83c269f8102e87828e0..588e8e1ff6af8a3497495c6962fd316147fb1888 100644 --- a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx +++ b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx @@ -85,11 +85,10 @@ private: // Elevation ElevationParametersHandler::AddElevationParameters(this, "elev"); - AddParameter(ParameterType_Empty, "norescale", "No rescaling in [0, 255]"); + AddParameter(ParameterType_Bool, "norescale", "No rescaling in [0, 255]"); SetParameterDescription("norescale", "By default, the input image amplitude is rescaled between [0,255]." " Turn on this parameter to skip rescaling"); - MandatoryOff("norescale"); AddRAMParameter(); @@ -132,7 +131,7 @@ private: = ShiftScaleImageFilterType::New(); // Default behavior is to do the rescaling - if ( !IsParameterEnabled("norescale") ) + if ( !GetParameterInt("norescale") ) { stats->SetInput(amplitudeConverter->GetOutput()); stats->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram")); diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx index ec2af7c1a45f5fc59a8f2e8ff2ad103c6e9e62ee..3d7fed0f93aaf23b466b18b3c5d7bed65122dcf6 100644 --- a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx +++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx @@ -231,7 +231,7 @@ private: SetParameterDescription("minmax.auto" , "Minimum and maximum value will " "be computed on the image (nodata value won't be taken " "into account) . Each band will have a minimum and a maximum."); - AddParameter(ParameterType_Empty, "minmax.auto.global", "Global"); + AddParameter(ParameterType_Bool, "minmax.auto.global", "Global"); SetParameterDescription("minmax.auto.global" , "Automatic" "Min/max computation will result in the same minimum and maximum for " "all the bands."); @@ -469,7 +469,7 @@ private: if ( m_MinMaxMode == "auto" ) { oss << "automatic"; - if ( IsParameterEnabled( "minmax.auto.global" ) ) + if ( GetParameterInt( "minmax.auto.global" ) ) { oss << " and global"; } @@ -565,7 +565,7 @@ private: statFilter->Update(); min = statFilter->GetMinimum(); max = statFilter->GetMaximum(); - if ( IsParameterEnabled("minmax.auto.global") ) + if ( GetParameterInt("minmax.auto.global") ) { float temp(min[0]); for ( unsigned int i = 1 ; i < min.GetSize() ; i++ ) @@ -583,7 +583,7 @@ private: } std::ostringstream oss; oss<<"Minimum and maximum are for each channel : "; - if ( IsParameterEnabled("minmax.auto.global") || + if ( GetParameterInt("minmax.auto.global") || m_MinMaxMode == "manual" ) { oss<<std::endl<<min[0]<<" and "<<max[0]; diff --git a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx index a31dc933881f65e3e50618d151f880fc87c90e9c..5f93a6b87183e62b5d40581f00d1a918b7794b0d 100644 --- a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx +++ b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx @@ -116,7 +116,7 @@ private: SetDefaultParameterInt( "type.anidif.nbiter" , 10 ); SetDefaultParameterInt( "type.anidif.conductance" , 1. ); - SetParameterString( "type" , "anidif" , false ); + SetParameterString( "type" , "anidif"); // Doc example parameter settings SetExampleComment( "Image smoothing using a mean filter." , 0 ); diff --git a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx index 8d510460a6892d3a64124625e3288b8d107a476e..3a5032af1f3a37fbda3d8a534a832dff8b31e63a 100644 --- a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx +++ b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx @@ -144,7 +144,7 @@ private: AddChoice("ua.mdmdnmf", "MDMDNMF"); SetParameterDescription("ua.mdmdnmf", "Minimum Dispersion Constrained Non Negative Matrix Factorization"); - SetParameterString("ua", "ucls", false); + SetParameterString("ua", "ucls"); // Doc example parameter settings SetDocExampleParameterValue("in", "cupriteSubHsi.tif"); SetDocExampleParameterValue("ie", "cupriteEndmembers.tif"); diff --git a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx index c3b04df6a957230444db0dfb6a5c1eb8f3961587..1dc286bb9cf35ea88dfc8f8da5402a0780aaad36 100644 --- a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx +++ b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx @@ -80,7 +80,7 @@ private: AddParameter(ParameterType_Int, "ne", "Number of endmembers"); SetParameterDescription("ne","The number of endmembers to extract from the hyperspectral image."); - SetParameterInt("ne",1, false); + SetParameterInt("ne",1); MandatoryOn("ne"); AddParameter(ParameterType_OutputImage, "outendm", "Output Endmembers"); diff --git a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx index ad8c68b614ed9b23f12182729964cabaae40f104..d68776716981ea94e1b691020bdbcd3d243595c2 100644 --- a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx +++ b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx @@ -346,11 +346,11 @@ private: AddParameter(ParameterType_Float,"method.continuous.min","Mapping range lower value"); SetParameterDescription("method.continuous.min","Set the lower input value of the mapping range."); - SetParameterFloat("method.continuous.min",0., false); + SetParameterFloat("method.continuous.min",0.); AddParameter(ParameterType_Float,"method.continuous.max","Mapping range higher value"); SetParameterDescription("method.continuous.max","Set the higher input value of the mapping range."); - SetParameterFloat("method.continuous.max",255., false); + SetParameterFloat("method.continuous.max",255.); // Optimal LUT AddChoice("method.optimal","Compute an optimized look-up table"); @@ -359,7 +359,7 @@ private: "[color to label] Searching all the colors present in the image to compute a continuous label list"); AddParameter(ParameterType_Int,"method.optimal.background", "Background label"); SetParameterDescription("method.optimal.background","Value of the background label"); - SetParameterInt("method.optimal.background",0, false); + SetParameterInt("method.optimal.background",0); SetMinimumParameterIntValue("method.optimal.background", 0); SetMaximumParameterIntValue("method.optimal.background", 255); @@ -371,18 +371,18 @@ private: AddParameter(ParameterType_Float, "method.image.nodatavalue", "NoData value"); SetParameterDescription("method.image.nodatavalue","NoData value for each channel of the support image, which will not be handled in the LUT estimation. If NOT checked, ALL the pixel values of the support image will be handled in the LUT estimation."); MandatoryOff("method.image.nodatavalue"); - SetParameterFloat("method.image.nodatavalue",0, false); + SetParameterFloat("method.image.nodatavalue",0); DisableParameter("method.image.nodatavalue"); AddParameter(ParameterType_Int, "method.image.low", "lower quantile"); SetParameterDescription("method.image.low","lower quantile for image normalization"); MandatoryOff("method.image.low"); - SetParameterInt("method.image.low",2, false); + SetParameterInt("method.image.low",2); SetMinimumParameterIntValue("method.image.low", 0); SetMaximumParameterIntValue("method.image.low", 100); AddParameter(ParameterType_Int, "method.image.up", "upper quantile"); SetParameterDescription("method.image.up","upper quantile for image normalization"); MandatoryOff("method.image.up"); - SetParameterInt("method.image.up",2, false); + SetParameterInt("method.image.up",2); SetMinimumParameterIntValue("method.image.up", 0); SetMaximumParameterIntValue("method.image.up", 100); @@ -406,7 +406,7 @@ private: if (GetParameterInt("method")==1 || GetParameterInt("method")==3) { otbAppLogWARNING("Override method : use optimal"); - SetParameterInt("method",2, false); + SetParameterInt("method",2); } } } diff --git a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx index 2d0d54c83c8e1297ebcbfba5206cf88a231f2bc0..d376e56b5c0172dd5039fe2b35296025c5bfc6ae 100644 --- a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx +++ b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx @@ -225,10 +225,10 @@ private: otbAppLogINFO( << "PSNR: " << m_CompareFilter->GetPSNR() ); otbAppLogINFO( << "Number of Pixel different: " << m_CompareFilter->GetDiffCount() ); - SetParameterFloat( "mse",m_CompareFilter->GetMSE() , false); - SetParameterFloat( "mae",m_CompareFilter->GetMAE() , false); - SetParameterFloat( "psnr",m_CompareFilter->GetPSNR() , false); - SetParameterFloat( "count",m_CompareFilter->GetDiffCount() , false); + SetParameterFloat( "mse",m_CompareFilter->GetMSE()); + SetParameterFloat( "mae",m_CompareFilter->GetMAE()); + SetParameterFloat( "psnr",m_CompareFilter->GetPSNR()); + SetParameterFloat( "count",m_CompareFilter->GetDiffCount()); } diff --git a/Modules/Applications/AppImageUtils/app/otbConvert.cxx b/Modules/Applications/AppImageUtils/app/otbConvert.cxx index 621d48adb330f544d8b7afb1ec7bd09aee43001b..2a553a76803cb3b682adfdd8247e8fe05afe2e21 100644 --- a/Modules/Applications/AppImageUtils/app/otbConvert.cxx +++ b/Modules/Applications/AppImageUtils/app/otbConvert.cxx @@ -120,7 +120,7 @@ private: AddChoice("type.none", "None"); AddChoice("type.linear", "Linear"); AddChoice("type.log2", "Log2"); - SetParameterString("type", "none", false); + SetParameterString("type", "none"); AddParameter(ParameterType_Float,"type.linear.gamma","Gamma correction factor"); SetParameterDescription("type.linear.gamma","Gamma correction factor"); diff --git a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx index fa8b76c501ec66ee5672ce6a19efd8128ac8f5c7..28d51f406ee07f1cce78c5616864bd8e6bab4b8d 100644 --- a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx +++ b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx @@ -124,7 +124,7 @@ private: SetParameterDescription("type", "Transfer function for the rescaling"); AddChoice("type.linear", "Linear"); AddChoice("type.log2", "Log2"); - SetParameterString("type", "linear", false); + SetParameterString("type", "linear"); AddParameter(ParameterType_Float,"type.linear.gamma", "Gamma correction factor"); diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx index bd6a8d1583cf4b54dd0ebc441108000735a943ec..6bbd121c894926d7c97a5b469f32638e58dff5d6 100644 --- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx +++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx @@ -267,8 +267,8 @@ private: // Update the sizes only if the user has not defined a size if (!HasUserValue("sizex") && !HasUserValue("sizey") ) { - SetParameterInt("sizex",largestRegion.GetSize()[0], false); - SetParameterInt("sizey",largestRegion.GetSize()[1], false); + SetParameterInt("sizex",largestRegion.GetSize()[0]); + SetParameterInt("sizey",largestRegion.GetSize()[1]); // Compute extent parameter with default sizex and sizey if ( GetParameterString( "mode" ) == "extent" && userExtent ) @@ -316,8 +316,8 @@ private: if(!this->CropRegionOfInterest()) { // Put the index of the ROI to origin and try to crop again - SetParameterInt("startx",0, false); - SetParameterInt("starty",0, false); + SetParameterInt("startx",0); + SetParameterInt("starty",0); this->CropRegionOfInterest(); } @@ -390,10 +390,10 @@ private: inImage->UpdateOutputInformation(); if (region.Crop(inImage->GetLargestPossibleRegion())) { - SetParameterInt("sizex",region.GetSize(0), HasUserValue("sizex")); - SetParameterInt("sizey",region.GetSize(1), HasUserValue("sizey")); - SetParameterInt("startx",region.GetIndex(0), HasUserValue("startx")); - SetParameterInt("starty",region.GetIndex(1), HasUserValue("starty")); + SetParameterInt("sizex",region.GetSize(0)); + SetParameterInt("sizey",region.GetSize(1)); + SetParameterInt("startx",region.GetIndex(0)); + SetParameterInt("starty",region.GetIndex(1)); return true; } } @@ -409,15 +409,15 @@ private: if (GetParameterString( "mode.extent.unit" ) == "pxl" ) { pixelValue = std::round( GetParameterFloat( "mode.extent.ulx" ) ); - SetParameterInt( "startx", pixelValue , true ); + SetParameterInt( "startx", pixelValue); pixelValue = std::round( GetParameterFloat( "mode.extent.lrx" ) \ - pixelValue ) + 1 ; - SetParameterInt( "sizex", pixelValue , true ); + SetParameterInt( "sizex", pixelValue); pixelValue = std::round( GetParameterFloat( "mode.extent.uly" ) ); - SetParameterInt( "starty", pixelValue , true ); + SetParameterInt( "starty", pixelValue); pixelValue = std::round( GetParameterFloat( "mode.extent.lry" ) \ - pixelValue ) + 1 ; - SetParameterInt( "sizey", pixelValue , true ); + SetParameterInt( "sizey", pixelValue); } else if( GetParameterString( "mode.extent.unit" ) == "phy" ) { @@ -432,11 +432,11 @@ private: inImage->TransformPhysicalPointToIndex(ulp,uli); inImage->TransformPhysicalPointToIndex(lrp,lri); - SetParameterInt( "startx", uli[0] , true ); - SetParameterInt( "starty", uli[1] , true ); + SetParameterInt( "startx", uli[0]); + SetParameterInt( "starty", uli[1]); - SetParameterInt( "sizex", lri[0] - uli[0] + 1, true ); - SetParameterInt( "sizey", lri[1] - uli[1] + 1, true ); + SetParameterInt( "sizex", lri[0] - uli[0] + 1); + SetParameterInt( "sizey", lri[1] - uli[1] + 1); } else if( GetParameterString( "mode.extent.unit" ) == "lonlat" ) @@ -458,11 +458,11 @@ private: inImage->TransformPhysicalPointToIndex(ulp_out,uli_out); inImage->TransformPhysicalPointToIndex(lrp_out,lri_out); - SetParameterInt( "startx", uli_out[0] , true ); - SetParameterInt( "starty", uli_out[1] , true ); + SetParameterInt( "startx", uli_out[0]); + SetParameterInt( "starty", uli_out[1]); - SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1, true ); - SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1, true ); + SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1); + SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1); } this->CropRegionOfInterest(); } @@ -477,22 +477,22 @@ private: lri[ 1 ] = largestRegion.GetSize()[1]; if ( GetParameterString( "mode.extent.unit" ) == "pxl" ) { - SetParameterFloat("mode.extent.ulx", uli[0] , false); - SetParameterFloat("mode.extent.uly", uli[1] , false); - SetParameterFloat("mode.extent.lrx", lri[0] , false); - SetParameterFloat("mode.extent.lry", lri[1] , false); + SetParameterFloat("mode.extent.ulx", uli[0]); + SetParameterFloat("mode.extent.uly", uli[1]); + SetParameterFloat("mode.extent.lrx", lri[0]); + SetParameterFloat("mode.extent.lry", lri[1]); } else if ( GetParameterString( "mode.extent.unit" ) == "phy" ) { itk::Point<float, 2> ulp, lrp; input->TransformIndexToPhysicalPoint(uli,ulp); - SetParameterFloat("mode.extent.ulx",ulp[0], false); - SetParameterFloat("mode.extent.uly",ulp[1], false); + SetParameterFloat("mode.extent.ulx",ulp[0]); + SetParameterFloat("mode.extent.uly",ulp[1]); input->TransformIndexToPhysicalPoint(lri,lrp); - SetParameterFloat("mode.extent.lrx",lrp[0], false); - SetParameterFloat("mode.extent.lry",lrp[1], false); + SetParameterFloat("mode.extent.lrx",lrp[0]); + SetParameterFloat("mode.extent.lry",lrp[1]); } else if ( GetParameterString( "mode.extent.unit" ) == "lonlat" ) { @@ -503,13 +503,13 @@ private: itk::Point<float, 2> ulp_in, lrp_in , ulp_out , lrp_out; input->TransformIndexToPhysicalPoint(uli,ulp_in); ulp_out = rsTransform->TransformPoint( ulp_in ); - SetParameterFloat( "mode.extent.ulx" , ulp_out[ 0 ] , false ); - SetParameterFloat( "mode.extent.uly" , ulp_out[ 1 ] , false ); + SetParameterFloat( "mode.extent.ulx" , ulp_out[ 0 ]); + SetParameterFloat( "mode.extent.uly" , ulp_out[ 1 ]); input->TransformIndexToPhysicalPoint( lri , lrp_in ); lrp_out = rsTransform->TransformPoint( lrp_in ); - SetParameterFloat( "mode.extent.lrx" , lrp_out[ 0 ] , false ); - SetParameterFloat( "mode.extent.lry" , lrp_out[ 1 ] , false ); + SetParameterFloat( "mode.extent.lrx" , lrp_out[ 0 ]); + SetParameterFloat( "mode.extent.lry" , lrp_out[ 1 ]); } } @@ -524,8 +524,8 @@ private: if ( GetParameterString( "mode.radius.unitr" ) == "pxl" ) { pixelValue = std::floor( 2 * GetParameterFloat( "mode.radius.r" ) ) + 1; - SetParameterInt( "sizey", pixelValue , true ); - SetParameterInt( "sizex", pixelValue , true ); + SetParameterInt( "sizey", pixelValue); + SetParameterInt( "sizex", pixelValue); } if ( GetParameterString( "mode.radius.unitr" ) == "phy" ) { @@ -564,8 +564,8 @@ private: { pixelValue = maxR; } - SetParameterInt( "sizey", 2 * pixelValue + 1 , true ); - SetParameterInt( "sizex", 2 * pixelValue + 1 , true ); + SetParameterInt( "sizey", 2 * pixelValue + 1); + SetParameterInt( "sizex", 2 * pixelValue + 1); } } @@ -579,9 +579,9 @@ private: if ( GetParameterString( "mode.radius.unitc" ) == "pxl" && size ) { pixelValue = std::round(GetParameterFloat( "mode.radius.cx" )); - SetParameterInt( "startx", pixelValue - radiusxi , true ); + SetParameterInt( "startx", pixelValue - radiusxi); pixelValue = std::round(GetParameterFloat( "mode.radius.cy" )); - SetParameterInt( "starty", pixelValue - radiusyi , true ); + SetParameterInt( "starty", pixelValue - radiusyi); } if ( GetParameterString( "mode.radius.unitc" ) == "phy" && size ) { @@ -593,8 +593,8 @@ private: bool isIn = inImage->TransformPhysicalPointToIndex( centerp , centeri ); if ( isIn ) { - SetParameterInt( "startx", centeri[0] - radiusxi , true ); - SetParameterInt( "starty", centeri[1] - radiusyi , true ); + SetParameterInt( "startx", centeri[0] - radiusxi); + SetParameterInt( "starty", centeri[1] - radiusyi); } } if ( GetParameterString( "mode.radius.unitc" ) == "lonlat" && size ) @@ -613,8 +613,8 @@ private: centeri_out ); if ( isIn ) { - SetParameterInt( "startx", centeri_out[0] - radiusxi , true ); - SetParameterInt( "starty", centeri_out[1] - radiusyi , true ); + SetParameterInt( "startx", centeri_out[0] - radiusxi); + SetParameterInt( "starty", centeri_out[1] - radiusyi); } } } @@ -636,7 +636,7 @@ private: if ( GetParameterString("mode.radius.unitr") == "pxl" ) { int rad = std::min( centeri[ 0 ], centeri[ 1 ] ); - SetParameterFloat( "mode.radius.r" , rad , false ); + SetParameterFloat( "mode.radius.r" , rad); } if ( GetParameterString("mode.radius.unitr") == "phy" ) { @@ -645,19 +645,19 @@ private: input->TransformIndexToPhysicalPoint(helpRxi,helpRxp); input->TransformIndexToPhysicalPoint(helpRyi,helpRyp); float rad = std::min( helpRxp[0] - helpRyp[0] , helpRyp[1] - helpRxp[1] ); - SetParameterFloat( "mode.radius.r" , rad , false ); + SetParameterFloat( "mode.radius.r" , rad); } if ( GetParameterString("mode.radius.unitc") == "pxl" ) { - SetParameterFloat( "mode.radius.cx" , centeri[0] , false ); - SetParameterFloat( "mode.radius.cy" , centeri[1] , false) ; + SetParameterFloat( "mode.radius.cx" , centeri[0]); + SetParameterFloat( "mode.radius.cy" , centeri[1]) ; } if ( GetParameterString("mode.radius.unitc") == "phy" ) { itk::Point<float, 2> centerp , helpRp; input->TransformIndexToPhysicalPoint(centeri,centerp); - SetParameterFloat( "mode.radius.cx" , centerp[0] , false ); - SetParameterFloat( "mode.radius.cy" , centerp[1] , false) ; + SetParameterFloat( "mode.radius.cx" , centerp[0]); + SetParameterFloat( "mode.radius.cy" , centerp[1]) ; } if ( GetParameterString("mode.radius.unitc") == "lonlat" ) { @@ -668,8 +668,8 @@ private: itk::Point<float, 2> centerp_in, centerp_out; input->TransformIndexToPhysicalPoint(centeri,centerp_in); centerp_out = rsTransform->TransformPoint( centerp_in ); - SetParameterFloat( "mode.radius.cx" , centerp_out[ 0 ] , false ); - SetParameterFloat( "mode.radius.cy" , centerp_out[ 1 ] , false ); + SetParameterFloat( "mode.radius.cx" , centerp_out[ 0 ]); + SetParameterFloat( "mode.radius.cy" , centerp_out[ 1 ]); } } @@ -755,10 +755,10 @@ private: lri[1] = std::max( std::max( uli_out[1] , uri_out[1] ) , std::max( lli_out[1] , lri_out[1] ) ); - SetParameterInt( "startx", uli[0] , false ); - SetParameterInt( "starty", uli[1] , false ); - SetParameterInt( "sizex", lri[0] - uli[0] , false ); - SetParameterInt( "sizey", lri[1] - uli[1] , false ); + SetParameterInt( "startx", uli[0]); + SetParameterInt( "starty", uli[1]); + SetParameterInt( "sizex", lri[0] - uli[0]); + SetParameterInt( "sizey", lri[1] - uli[1]); } } else if( HasValue( "mode.fit.im" ) && GetParameterString( "mode" ) == "fit" ) diff --git a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx index 439ba055904d6e1a3c8c5e72e367d2a27cc73771..8f0b43cfece666f796756d4b38fbf934783dc0d9 100644 --- a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx +++ b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx @@ -79,10 +79,8 @@ private: AddParameter(ParameterType_OutputImage, "out", "Output Image"); SetParameterDescription("out", "Output image"); - AddParameter(ParameterType_Empty,"usenan", "Consider NaN as no-data"); + AddParameter(ParameterType_Bool,"usenan", "Consider NaN as no-data"); SetParameterDescription("usenan","If active, the application will consider NaN as no-data values as well"); - MandatoryOff("usenan"); - DisableParameter("usenan"); AddParameter(ParameterType_Choice,"mode","No-data handling mode"); SetParameterDescription("mode","Allows choosing between different no-data handling options"); @@ -112,7 +110,7 @@ private: SetParameterDescription("mode.apply.ndval","No Data value used according to the mask image"); SetDefaultParameterFloat("mode.apply.ndval", 0.0); - SetParameterString("mode","buildmask", false); + SetParameterString("mode","buildmask"); AddRAMParameter(); @@ -138,12 +136,12 @@ private: m_Filter = FilterType::New(); m_Filter->SetInsideValue(this->GetParameterFloat("mode.buildmask.inv")); m_Filter->SetOutsideValue(this->GetParameterFloat("mode.buildmask.outv")); - m_Filter->SetNaNIsNoData(IsParameterEnabled("usenan")); + m_Filter->SetNaNIsNoData(GetParameterInt("usenan")); m_Filter->SetInput(inputPtr); m_ChangeNoDataFilter = ChangeNoDataFilterType::New(); m_ChangeNoDataFilter->SetInput(inputPtr); - m_ChangeNoDataFilter->SetNaNIsNoData(IsParameterEnabled("usenan")); + m_ChangeNoDataFilter->SetNaNIsNoData(GetParameterInt("usenan")); std::vector<double> newNoData(inputPtr->GetNumberOfComponentsPerPixel(),GetParameterFloat("mode.changevalue.newv")); diff --git a/Modules/Applications/AppImageUtils/app/otbMultiResolutionPyramid.cxx b/Modules/Applications/AppImageUtils/app/otbMultiResolutionPyramid.cxx index d94f67b260a694de203b6814f20b67ce207b6c03..8117e4c165fd95ced9c8d2cec4485508b647d947 100644 --- a/Modules/Applications/AppImageUtils/app/otbMultiResolutionPyramid.cxx +++ b/Modules/Applications/AppImageUtils/app/otbMultiResolutionPyramid.cxx @@ -96,12 +96,11 @@ private: SetParameterDescription( "vfactor", "Variance factor use in smoothing. It is multiplied by the subsampling factor of each level in the pyramid (default is 0.6)."); // Boolean Fast scheme - AddParameter(ParameterType_Empty, "fast", "Use Fast Scheme"); + AddParameter(ParameterType_Bool, "fast", "Use Fast Scheme"); std::ostringstream desc; desc<<"If used, this option allows one to speed-up computation by iteratively" <<" subsampling previous level of pyramid instead of processing the full input."; SetParameterDescription("fast", desc.str()); - MandatoryOff("fast"); // Doc example parameter settings SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif"); @@ -132,7 +131,7 @@ private: unsigned int shrinkFactor = GetParameterInt("sfactor"); double varianceFactor = GetParameterFloat("vfactor"); - bool fastScheme = IsParameterEnabled("fast"); + bool fastScheme = GetParameterInt("fast"); // Get the input image FloatVectorImageType::Pointer inImage = GetParameterImage("in"); diff --git a/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx b/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx index 1bca9241ea384ab9210913f1ca7949e68178142c..03f1351b8dd5d3a11bafa9b1aa4caa2fa18e57c5 100644 --- a/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx +++ b/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx @@ -292,7 +292,7 @@ private: id.Fill(0); std::ostringstream oss; oss << extractor->GetOutput()->GetPixel(id); - SetParameterString("value", oss.str(), false); + SetParameterString("value", oss.str()); //Display image information in the dedicated logger otbAppLogINFO( << oss.str() ); } diff --git a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx index dd7134c62009cdfadc14b11f98f9f39734b09c50..f7f9db4a94e1364db0426c874fa7a65608e9fb89 100644 --- a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx +++ b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx @@ -146,8 +146,8 @@ private: if (!HasUserValue("rsx") && !HasUserValue("rsy") ) { - SetParameterInt("rsx",largestRegion.GetSize()[0], false); - SetParameterInt("rsy",largestRegion.GetSize()[1], false); + SetParameterInt("rsx",largestRegion.GetSize()[0]); + SetParameterInt("rsy",largestRegion.GetSize()[1]); } // Put the limit of the index and the size relative the image @@ -168,8 +168,8 @@ private: if(!this->CropRegionOfInterest()) { // Put the index of the ROI to origin and try to crop again - SetParameterInt("rox",0, false); - SetParameterInt("roy",0, false); + SetParameterInt("rox",0); + SetParameterInt("roy",0); this->CropRegionOfInterest(); } } @@ -183,15 +183,20 @@ bool CropRegionOfInterest() region.SetSize(1, GetParameterInt("rsy")); region.SetIndex(0, GetParameterInt("rox")); region.SetIndex(1, GetParameterInt("roy")); + FloatVectorImageType::RegionType region0 = region; if ( HasValue("in") ) { if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion())) { - SetParameterInt( "rsx", region.GetSize(0), HasUserValue("rsx") ); - SetParameterInt( "rsy", region.GetSize(1), HasUserValue("rsy") ); - SetParameterInt( "rox", region.GetIndex(0), HasUserValue("rox") ); - SetParameterInt( "roy", region.GetIndex(1), HasUserValue("roy") ); + if (region0.GetSize(0) != region.GetSize(0)) + SetParameterInt( "rsx", region.GetSize(0)); + if (region0.GetSize(1) != region.GetSize(1)) + SetParameterInt( "rsy", region.GetSize(1)); + if (region0.GetIndex(0) != region.GetIndex(0)) + SetParameterInt( "rox", region.GetIndex(0)); + if (region0.GetIndex(1) != region.GetIndex(1)) + SetParameterInt( "roy", region.GetIndex(1)); return true; } } diff --git a/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx b/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx index 74bb9c42dadb51c605f164d14c228f5a6e5602c3..1aabf57ca8acf3b6c1be4e951ba03e56b87ae82a 100644 --- a/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx +++ b/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx @@ -67,10 +67,8 @@ private: AddParameter(ParameterType_InputImage, "in", "Input Image"); SetParameterDescription("in", "Input image to analyse"); - AddParameter(ParameterType_Empty, "keywordlist", "Display the OSSIM keywordlist"); + AddParameter(ParameterType_Bool, "keywordlist", "Display the OSSIM keywordlist"); SetParameterDescription("keywordlist", "Output the OSSIM keyword list. It contains metadata information (sensor model, geometry ). Information is stored in keyword list (pairs of key/value)"); - DisableParameter("keywordlist"); - MandatoryOff("keywordlist"); AddParameter(ParameterType_OutputFilename, "outkwl", "Write the OSSIM keywordlist to a geom file"); SetParameterDescription("outkwl", "This option allows extracting the OSSIM keywordlist of the image into a geom file."); @@ -267,7 +265,7 @@ private: ImageMetadataInterfaceType::Pointer metadataInterface = ImageMetadataInterfaceFactory::CreateIMI(inImage->GetMetaDataDictionary()); //Get number of bands - SetParameterInt("numberbands",inImage->GetNumberOfComponentsPerPixel(), false); + SetParameterInt("numberbands",inImage->GetNumberOfComponentsPerPixel()); ossOutput << "\tNumber of bands : " << GetParameterInt("numberbands") << std::endl; std::vector<bool> noDataValueAvailable; bool ret = itk::ExposeMetaData<std::vector<bool> >(inImage->GetMetaDataDictionary(),MetaDataKey::NoDataValueAvailable,noDataValueAvailable); @@ -298,26 +296,26 @@ private: ossOutput<<std::endl; //Get image size - SetParameterInt("indexx",inImage->GetLargestPossibleRegion().GetIndex()[0], false); - SetParameterInt("indexy",inImage->GetLargestPossibleRegion().GetIndex()[1], false); + SetParameterInt("indexx",inImage->GetLargestPossibleRegion().GetIndex()[0]); + SetParameterInt("indexy",inImage->GetLargestPossibleRegion().GetIndex()[1]); ossOutput << "\tStart index : [" << GetParameterInt("indexx") << "," << GetParameterInt("indexy") << "]" << std::endl; //Get image size - SetParameterInt("sizex",inImage->GetLargestPossibleRegion().GetSize()[0], false); - SetParameterInt("sizey",inImage->GetLargestPossibleRegion().GetSize()[1], false); + SetParameterInt("sizex",inImage->GetLargestPossibleRegion().GetSize()[0]); + SetParameterInt("sizey",inImage->GetLargestPossibleRegion().GetSize()[1]); ossOutput << "\tSize : [" << GetParameterInt("sizex") << "," << GetParameterInt("sizey") << "]" << std::endl; //Get image origin - SetParameterFloat("originx",inImage->GetOrigin()[0], false); - SetParameterFloat("originy",inImage->GetOrigin()[1], false); + SetParameterFloat("originx",inImage->GetOrigin()[0]); + SetParameterFloat("originy",inImage->GetOrigin()[1]); ossOutput << "\tOrigin : [" << GetParameterFloat("originx") << "," << GetParameterFloat("originy") << "]" << std::endl; //Get image spacing - SetParameterFloat("spacingx",inImage->GetSignedSpacing()[0], false); - SetParameterFloat("spacingy",inImage->GetSignedSpacing()[1], false); + SetParameterFloat("spacingx",inImage->GetSignedSpacing()[0]); + SetParameterFloat("spacingy",inImage->GetSignedSpacing()[1]); ossOutput << "\tSpacing : [" << GetParameterFloat("spacingx") << "," << GetParameterFloat("spacingy") << "]" << std::endl; //Estimate ground spacing @@ -336,14 +334,14 @@ private: approxGroundSpacing = groundSpacing->EvaluateAtIndex(index); //Get image estimated ground spacing (in m) - SetParameterFloat("estimatedgroundspacingx",approxGroundSpacing[0], false); - SetParameterFloat("estimatedgroundspacingy",approxGroundSpacing[1], false); + SetParameterFloat("estimatedgroundspacingx",approxGroundSpacing[0]); + SetParameterFloat("estimatedgroundspacingy",approxGroundSpacing[1]); ossOutput << "\tEstimated ground spacing (in meters): [" << GetParameterFloat("estimatedgroundspacingx") << "," << GetParameterFloat("estimatedgroundspacingy") << "]" << std::endl; ossOutput << std::endl << "Image acquisition information:" << std::endl; - SetParameterString("sensor", metadataInterface->GetSensorID(), false); + SetParameterString("sensor", metadataInterface->GetSensorID()); ossOutput << "\tSensor : "; if (!GetParameterString("sensor").empty()) ossOutput << GetParameterString("sensor"); @@ -353,11 +351,11 @@ private: ossOutput << "\tImage identification number: "; if (metadataInterface->GetImageKeywordlist().HasKey("image_id")) { - SetParameterString("id", metadataInterface->GetImageKeywordlist().GetMetadataByKey("image_id"), false); + SetParameterString("id", metadataInterface->GetImageKeywordlist().GetMetadataByKey("image_id")); ossOutput << GetParameterString("id"); } ossOutput << std::endl; - SetParameterString("projectionref", metadataInterface->GetProjectionRef(), false); + SetParameterString("projectionref", metadataInterface->GetProjectionRef()); if (!GetParameterString("projectionref").empty()) ossOutput << "\tImage projection : " << GetParameterString("projectionref") << std::endl; @@ -381,7 +379,7 @@ private: osstime<<"0"; osstime<<metadataInterface->GetMinute(); osstime<<":00"; - SetParameterString("time", osstime.str(), false); + SetParameterString("time", osstime.str()); ossOutput << "\tAcquisition time : " << GetParameterString("time") << std::endl; } @@ -410,29 +408,29 @@ private: if( !coord2name->GetCountryName().empty() ) { - SetParameterString("country", coord2name->GetCountryName(), false); + SetParameterString("country", coord2name->GetCountryName()); ossOutput << "\tCountry : " << GetParameterString("country") << std::endl; } else - SetParameterString("country", "Not available", false); + SetParameterString("country", "Not available"); if( !coord2name->GetPlaceName().empty() ) { - SetParameterString("town", coord2name->GetPlaceName(), false); + SetParameterString("town", coord2name->GetPlaceName()); ossOutput << "\tTown : " << GetParameterString("town") << std::endl; } else - SetParameterString("town", "Not available", false); + SetParameterString("town", "Not available"); // Retrieve footprint - SetParameterFloat("ullat",ullat, false); - SetParameterFloat("ullon",ullon, false); - SetParameterFloat("urlat",urlat, false); - SetParameterFloat("urlon",urlon, false); - SetParameterFloat("lrlat",lrlat, false); - SetParameterFloat("lrlon",lrlon, false); - SetParameterFloat("lllat",lllat, false); - SetParameterFloat("lllon",lllon, false); + SetParameterFloat("ullat",ullat); + SetParameterFloat("ullon",ullon); + SetParameterFloat("urlat",urlat); + SetParameterFloat("urlon",urlon); + SetParameterFloat("lrlat",lrlat); + SetParameterFloat("lrlon",lrlon); + SetParameterFloat("lllat",lllat); + SetParameterFloat("lllon",lllon); ossOutput << std::endl << "Image footprint coordinates:" << std::endl; ossOutput << "\tUpper left corner (latitude, longitude) = [" << GetParameterFloat("ullat") << "," << GetParameterFloat("ullon") << "]" << std::endl; @@ -444,15 +442,15 @@ private: { } - SetParameterInt("rgb.r",metadataInterface->GetDefaultDisplay()[0], false); - SetParameterInt("rgb.g",metadataInterface->GetDefaultDisplay()[1], false); - SetParameterInt("rgb.b",metadataInterface->GetDefaultDisplay()[2], false); + SetParameterInt("rgb.r",metadataInterface->GetDefaultDisplay()[0]); + SetParameterInt("rgb.g",metadataInterface->GetDefaultDisplay()[1]); + SetParameterInt("rgb.b",metadataInterface->GetDefaultDisplay()[2]); ossOutput << std::endl << "Image default RGB composition:" << std::endl; ossOutput << "\t[R, G, B] = [" << GetParameterInt("rgb.r") << "," << GetParameterInt("rgb.g") << "," << GetParameterInt("rgb.b") << "]" << std::endl; - SetParameterInt("gcp.count",metadataInterface->GetGCPCount(), false); - SetParameterString("gcp.proj", metadataInterface->GetGCPProjection(), false); + SetParameterInt("gcp.count",metadataInterface->GetGCPCount()); + SetParameterString("gcp.proj", metadataInterface->GetGCPProjection()); ossOutput << std::endl << "Ground control points information:" << std::endl; ossOutput << "\tNumber of GCPs = " << GetParameterInt("gcp.count") << std::endl; @@ -481,16 +479,16 @@ private: ossOutput << "\t\tGround coordinates =" << gcp_geocoord.back() << std::endl; } - SetParameterStringList("gcp.ids", gcp_ids, false); - SetParameterStringList("gcp.imcoord", gcp_imcoord, false); - SetParameterStringList("gcp.geocoord", gcp_geocoord, false); - SetParameterStringList("gcp.info", gcp_infos, false); + SetParameterStringList("gcp.ids", gcp_ids); + SetParameterStringList("gcp.imcoord", gcp_imcoord); + SetParameterStringList("gcp.geocoord", gcp_geocoord); + SetParameterStringList("gcp.info", gcp_infos); - if ( IsParameterEnabled("keywordlist") ) + if ( GetParameterInt("keywordlist") ) { std::ostringstream osskeywordlist; osskeywordlist<<metadataInterface->GetImageKeywordlist() << std::endl; - SetParameterString("keyword", osskeywordlist.str(), false); + SetParameterString("keyword", osskeywordlist.str()); ossOutput << std::endl << "Image OSSIM keywordlist (optional):" << std::endl; ossOutput << "\t" << GetParameterString("keyword") << std::endl; @@ -499,7 +497,7 @@ private: //Display image information in the dedicated logger otbAppLogINFO( << ossOutput.str() ); - if(IsParameterEnabled("outkwl")) + if(IsParameterEnabled("outkwl") && HasValue("outkwl")) { WriteGeometry(metadataInterface->GetImageKeywordlist(),GetParameterString("outkwl")); } diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx index 90a7f245a6f3e1adf1976c27634ec5bbb12c28fd..90be1a12b3512f386f74760c5e7673cfef4df5ed 100644 --- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx +++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx @@ -289,7 +289,7 @@ private: if (useContext) { // only set the first expression, 'ManyExpression' is disabled. - this->SetParameterString("exp",dummyFilter->GetExpression(0), false); + this->SetParameterString("exp",dummyFilter->GetExpression(0)); } } } diff --git a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx index 829c4f3052c9d95683dd55b0d62b28d5bd1f14f9..3c843fa5ac6112fb1b3e85442bdb9149c9eddc9b 100644 --- a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx +++ b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx @@ -197,18 +197,15 @@ private: AddChoice("level.toa", "Image to Top Of Atmosphere reflectance"); AddChoice("level.toatoim", "TOA reflectance to Image"); AddChoice("level.toc", "Image to Top Of Canopy reflectance (atmospheric corrections)"); - SetParameterString("level", "toa", false); + SetParameterString("level", "toa"); - AddParameter(ParameterType_Empty, "milli", "Convert to milli reflectance"); + AddParameter(ParameterType_Bool, "milli", "Convert to milli reflectance"); SetParameterDescription("milli", "Flag to use milli-reflectance instead of reflectance.\n" "This allows saving the image with integer pixel type (in the range [0, 1000] instead of floating point in the range [0, 1]. In order to do that, use this option and set the output pixel type (-out filename double for example)"); - DisableParameter("milli"); - MandatoryOff("milli"); - AddParameter(ParameterType_Empty, "clamp", "Clamp of reflectivity values between [0, 1]"); + AddParameter(ParameterType_Bool, "clamp", "Clamp of reflectivity values between [0, 1]"); SetParameterDescription("clamp", "Clamping in the range [0, 1]. It can be useful to preserve area with specular reflectance."); - EnableParameter("clamp"); - MandatoryOff("clamp"); + SetParameterInt("clamp",1); //Acquisition parameters AddParameter(ParameterType_Group,"acqui","Acquisition parameters"); @@ -429,21 +426,21 @@ private: ossOutput << "Acquisition Minute already set by user: no overload" <<std::endl; else { - SetParameterInt("acqui.minute",lImageMetadataInterface->GetMinute(), false); + SetParameterInt("acqui.minute",lImageMetadataInterface->GetMinute()); } if (HasUserValue("acqui.hour")) ossOutput << "Acquisition Hour already set by user: no overload" <<std::endl; else { - SetParameterInt("acqui.hour",lImageMetadataInterface->GetHour(), false); + SetParameterInt("acqui.hour",lImageMetadataInterface->GetHour()); } if (HasUserValue("acqui.day")) ossOutput << "Acquisition Day already set by user: no overload" <<std::endl; else { - SetParameterInt("acqui.day",lImageMetadataInterface->GetDay(), false); + SetParameterInt("acqui.day",lImageMetadataInterface->GetDay()); if (IsParameterEnabled("acqui.fluxnormcoeff")) DisableParameter("acqui.day"); } @@ -452,7 +449,7 @@ private: ossOutput << "Acquisition Month already set by user: no overload" <<std::endl; else { - SetParameterInt("acqui.month",lImageMetadataInterface->GetMonth(), false); + SetParameterInt("acqui.month",lImageMetadataInterface->GetMonth()); if (IsParameterEnabled("acqui.fluxnormcoeff")) DisableParameter("acqui.month"); } @@ -461,28 +458,28 @@ private: ossOutput << "Acquisition Year already set by user: no overload" <<std::endl; else { - SetParameterInt("acqui.year",lImageMetadataInterface->GetYear(), false); + SetParameterInt("acqui.year",lImageMetadataInterface->GetYear()); } if (HasUserValue("acqui.sun.elev")) ossOutput << "Acquisition Sun Elevation Angle already set by user: no overload" <<std::endl; else - SetParameterFloat("acqui.sun.elev",lImageMetadataInterface->GetSunElevation(), false); + SetParameterFloat("acqui.sun.elev",lImageMetadataInterface->GetSunElevation()); if (HasUserValue("acqui.sun.azim")) ossOutput << "Acquisition Sun Azimuth Angle already set by user: no overload" <<std::endl; else - SetParameterFloat("acqui.sun.azim",lImageMetadataInterface->GetSunAzimuth(), false); + SetParameterFloat("acqui.sun.azim",lImageMetadataInterface->GetSunAzimuth()); if (HasUserValue("acqui.view.elev")) ossOutput << "Acquisition Viewing Elevation Angle already set by user: no overload" <<std::endl; else - SetParameterFloat("acqui.view.elev",lImageMetadataInterface->GetSatElevation(), false); + SetParameterFloat("acqui.view.elev",lImageMetadataInterface->GetSatElevation()); if (HasUserValue("acqui.view.azim")) ossOutput << "Acquisition Viewing Azimuth Angle already set by user: no overload" <<std::endl; else - SetParameterFloat("acqui.view.azim",lImageMetadataInterface->GetSatAzimuth(), false); + SetParameterFloat("acqui.view.azim",lImageMetadataInterface->GetSatAzimuth()); // Set default value so that they are stored somewhere even if // they are overloaded by user values @@ -751,12 +748,12 @@ private: m_ImageToRadianceFilter->SetInput(inImage); m_RadianceToReflectanceFilter->SetInput(m_ImageToRadianceFilter->GetOutput()); - if (IsParameterEnabled("clamp")) + if (GetParameterInt("clamp")) { GetLogger()->Info("Clamp values between [0, 100]\n"); } - m_RadianceToReflectanceFilter->SetUseClamp(IsParameterEnabled("clamp")); + m_RadianceToReflectanceFilter->SetUseClamp(GetParameterInt("clamp")); m_RadianceToReflectanceFilter->UpdateOutputInformation(); m_ScaleFilter->SetInput(m_RadianceToReflectanceFilter->GetOutput()); } @@ -894,7 +891,7 @@ private: } //Rescale the surface reflectance in milli-reflectance - if (!IsParameterEnabled("clamp")) + if (!GetParameterInt("clamp")) { if (!adjComputation) m_ScaleFilter->SetInput(m_ReflectanceToSurfaceReflectanceFilter->GetOutput()); @@ -920,7 +917,7 @@ private: // Output Image double scale = 1.; - if (IsParameterEnabled("milli")) + if (GetParameterInt("milli")) { GetLogger()->Info("Use milli-reflectance\n"); if ( (GetParameterInt("level") == Level_IM_TOA) || (GetParameterInt("level") == Level_TOC) ) diff --git a/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx b/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx index dfecb742eab6f21f8bbeb72794f15aa68c5c849b..088428ef667cf4a89e8a47a29fe0baade21b9d56 100644 --- a/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx +++ b/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx @@ -122,8 +122,8 @@ private: otbAppLogINFO( << std::setprecision(10) << "Geographic Point (Long, Lat) : (" << geoPoint[0] << ", " << geoPoint[1] << ")" ); - SetParameterFloat( "long",geoPoint[0] , false); - SetParameterFloat( "lat",geoPoint[1] , false); + SetParameterFloat( "long",geoPoint[0]); + SetParameterFloat( "lat",geoPoint[1]); } }; diff --git a/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx b/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx index 384c892f14addbc1c66ac4b2f6b66d6ed28b460a..c7e6ee3619254f9e901f058d0b33c46f848b8ab3 100644 --- a/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx +++ b/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx @@ -130,8 +130,8 @@ private: outputPoint = model->TransformPoint(point); // Set the value computed - SetParameterFloat("output.idx",outputPoint[0], false); - SetParameterFloat("output.idy",outputPoint[1], false); + SetParameterFloat("output.idx",outputPoint[0]); + SetParameterFloat("output.idy",outputPoint[1]); // Set the town and the neaerest city CoordinateToName::Pointer coord2name = CoordinateToName::New(); @@ -139,8 +139,8 @@ private: coord2name->SetLat(outputPoint[1]); coord2name->Evaluate(); - SetParameterString("output.town", coord2name->GetPlaceName(), false); - SetParameterString("output.country", coord2name->GetCountryName(), false); + SetParameterString("output.town", coord2name->GetPlaceName()); + SetParameterString("output.country", coord2name->GetCountryName()); } }; diff --git a/Modules/Applications/AppProjection/app/otbGridBasedImageResampling.cxx b/Modules/Applications/AppProjection/app/otbGridBasedImageResampling.cxx index 72c9073a536035db0bf7b54dce52958e420590d4..750913f778e08afb6417812b9b05f40f8c26b04f 100644 --- a/Modules/Applications/AppProjection/app/otbGridBasedImageResampling.cxx +++ b/Modules/Applications/AppProjection/app/otbGridBasedImageResampling.cxx @@ -173,7 +173,7 @@ private: AddParameter(ParameterType_Radius, "interpolator.bco.radius", "Radius for bicubic interpolation"); SetParameterDescription("interpolator.bco.radius","This parameter allows controlling the size of the bicubic interpolation filter. If the target pixel size is higher than the input pixel size, increasing this parameter will reduce aliasing artifacts."); SetDefaultParameterInt("interpolator.bco.radius", 2); - SetParameterString("interpolator","bco", false); + SetParameterString("interpolator","bco"); AddRAMParameter(); diff --git a/Modules/Applications/AppProjection/app/otbObtainUTMZoneFromGeoPoint.cxx b/Modules/Applications/AppProjection/app/otbObtainUTMZoneFromGeoPoint.cxx index 37d0ec7b74b4104ef1ab1e6e893a8dac585d513c..0cfa820b268b01b54df2452170129a0d285ad9f8 100644 --- a/Modules/Applications/AppProjection/app/otbObtainUTMZoneFromGeoPoint.cxx +++ b/Modules/Applications/AppProjection/app/otbObtainUTMZoneFromGeoPoint.cxx @@ -93,7 +93,7 @@ private: { int utmZone = otb::Utils::GetZoneFromGeoPoint(GetParameterFloat("lon"), GetParameterFloat("lat")); - SetParameterInt("utm",utmZone, false); + SetParameterInt("utm",utmZone); } }; diff --git a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx index 3c91403e47100f50b352f436f2a7583d648a14de..5918102d7e096b4a45cf5e23485c0f96951666c7 100644 --- a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx +++ b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx @@ -177,13 +177,13 @@ private: MandatoryOff("outputs.lry"); MandatoryOff("outputs.ortho"); - AddParameter(ParameterType_Empty,"outputs.isotropic","Force isotropic spacing by default"); + AddParameter(ParameterType_Bool,"outputs.isotropic","Force isotropic spacing by default"); std::ostringstream isotropOss; isotropOss << "Default spacing (pixel size) values are estimated from the sensor modeling of the image. It can therefore result in a non-isotropic spacing. "; isotropOss << "This option allows you to force default values to be isotropic (in this case, the minimum of spacing in both direction is applied. "; isotropOss << "Values overridden by user are not affected by this option."; SetParameterDescription("outputs.isotropic", isotropOss.str()); - EnableParameter("outputs.isotropic"); + SetParameterInt("outputs.isotropic", 1); AddParameter(ParameterType_Float, "outputs.default", "Default pixel value"); SetParameterDescription("outputs.default","Default value to write when outside of input image."); @@ -259,7 +259,7 @@ private: typedef otb::ImageToGenericRSOutputParameters<FloatVectorImageType> OutputParametersEstimatorType; OutputParametersEstimatorType::Pointer genericRSEstimator = OutputParametersEstimatorType::New(); - if(IsParameterEnabled("outputs.isotropic")) + if(GetParameterInt("outputs.isotropic")) { genericRSEstimator->EstimateIsotropicSpacingOn(); } @@ -274,28 +274,28 @@ private: // Fill the Gui with the computed parameters if (!HasUserValue("outputs.sizex")) - SetParameterInt("outputs.sizex",genericRSEstimator->GetOutputSize()[0], false); + SetParameterInt("outputs.sizex",genericRSEstimator->GetOutputSize()[0]); if (!HasUserValue("outputs.sizey")) - SetParameterInt("outputs.sizey",genericRSEstimator->GetOutputSize()[1], false); + SetParameterInt("outputs.sizey",genericRSEstimator->GetOutputSize()[1]); if (!HasUserValue("outputs.spacingx")) - SetParameterFloat("outputs.spacingx",genericRSEstimator->GetOutputSpacing()[0], false); + SetParameterFloat("outputs.spacingx",genericRSEstimator->GetOutputSpacing()[0]); if (!HasUserValue("outputs.spacingy")) - SetParameterFloat("outputs.spacingy",genericRSEstimator->GetOutputSpacing()[1], false); + SetParameterFloat("outputs.spacingy",genericRSEstimator->GetOutputSpacing()[1]); if (!HasUserValue("outputs.ulx")) - SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0], false); + SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0]); if (!HasUserValue("outputs.uly")) - SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1], false); + SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1]); if (!HasUserValue("outputs.lrx")) - SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex")), false); + SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex"))); if (!HasUserValue("outputs.lry")) - SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey")), false); + SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey"))); // Handle the spacing and size field following the mode // chose by the user @@ -336,8 +336,8 @@ private: MandatoryOff("outputs.ortho"); // Update lower right - SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex")), false); - SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey")), false); + SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex"))); + SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey"))); } break; case Mode_AutomaticSize: @@ -382,16 +382,16 @@ private: genericRSEstimator->Compute(); // Set the processed size relative to this forced spacing - SetParameterInt("outputs.sizex",genericRSEstimator->GetOutputSize()[0], false); - SetParameterInt("outputs.sizey",genericRSEstimator->GetOutputSize()[1], false); + SetParameterInt("outputs.sizex",genericRSEstimator->GetOutputSize()[0]); + SetParameterInt("outputs.sizey",genericRSEstimator->GetOutputSize()[1]); // Reset Origin to default - SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0], false); - SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1], false); + SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0]); + SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1]); // Update lower right - SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex")), false); - SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey")), false); + SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex"))); + SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey"))); } break; case Mode_AutomaticSpacing: @@ -436,16 +436,16 @@ private: genericRSEstimator->Compute(); // Set the processed spacing relative to this forced size - SetParameterFloat("outputs.spacingx",genericRSEstimator->GetOutputSpacing()[0], false); - SetParameterFloat("outputs.spacingy",genericRSEstimator->GetOutputSpacing()[1], false); + SetParameterFloat("outputs.spacingx",genericRSEstimator->GetOutputSpacing()[0]); + SetParameterFloat("outputs.spacingy",genericRSEstimator->GetOutputSpacing()[1]); // Reset Origin to default - SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0], false); - SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1], false); + SetParameterFloat("outputs.ulx",genericRSEstimator->GetOutputOrigin()[0] - 0.5 * genericRSEstimator->GetOutputSpacing()[0]); + SetParameterFloat("outputs.uly",genericRSEstimator->GetOutputOrigin()[1] - 0.5 * genericRSEstimator->GetOutputSpacing()[1]); // Update lower right - SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex")), false); - SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey")), false); + SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex"))); + SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey"))); } break; @@ -489,9 +489,9 @@ private: // Set the processed size relative to this forced spacing if (vcl_abs(spacing[0]) > 0.0) - SetParameterInt("outputs.sizex",static_cast<int>(vcl_ceil((GetParameterFloat("outputs.lrx")-GetParameterFloat("outputs.ulx"))/spacing[0])), false); + SetParameterInt("outputs.sizex",static_cast<int>(vcl_ceil((GetParameterFloat("outputs.lrx")-GetParameterFloat("outputs.ulx"))/spacing[0]))); if (vcl_abs(spacing[1]) > 0.0) - SetParameterInt("outputs.sizey",static_cast<int>(vcl_ceil((GetParameterFloat("outputs.lry")-GetParameterFloat("outputs.uly"))/spacing[1])), false); + SetParameterInt("outputs.sizey",static_cast<int>(vcl_ceil((GetParameterFloat("outputs.lry")-GetParameterFloat("outputs.uly"))/spacing[1]))); } break; case Mode_OrthoFit: @@ -541,11 +541,11 @@ private: SetParameterInt("outputs.sizey",size[1]); SetParameterFloat("outputs.spacingx",spacing[0]); SetParameterFloat("outputs.spacingy",spacing[1]); - SetParameterFloat("outputs.ulx",orig[0] - 0.5 * spacing[0], false); - SetParameterFloat("outputs.uly",orig[1] - 0.5 * spacing[1], false); + SetParameterFloat("outputs.ulx",orig[0] - 0.5 * spacing[0]); + SetParameterFloat("outputs.uly",orig[1] - 0.5 * spacing[1]); // Update lower right - SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex")), false); - SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey")), false); + SetParameterFloat("outputs.lrx",GetParameterFloat("outputs.ulx") + GetParameterFloat("outputs.spacingx") * static_cast<double>(GetParameterInt("outputs.sizex"))); + SetParameterFloat("outputs.lry",GetParameterFloat("outputs.uly") + GetParameterFloat("outputs.spacingy") * static_cast<double>(GetParameterInt("outputs.sizey"))); } } break; @@ -591,11 +591,11 @@ private: // Use the smallest spacing (more precise grid) double optimalSpacing = std::min( vcl_abs(xgridspacing), vcl_abs(ygridspacing) ); otbAppLogINFO( "Setting grid spacing to " << optimalSpacing ); - SetParameterFloat("opt.gridspacing",optimalSpacing, false); + SetParameterFloat("opt.gridspacing",optimalSpacing); } else // if (m_OutputProjectionRef == otb::GeoInformationConversion::ToWKT(4326)) { - SetParameterFloat("opt.gridspacing",DefaultGridSpacingMeter, false); + SetParameterFloat("opt.gridspacing",DefaultGridSpacingMeter); } // if (m_OutputProjectionRef == otb::GeoInformationConversion::ToWKT(4326)) } // if (!HasUserValue("opt.gridspacing")) } // if (HasValue("io.in")) diff --git a/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx b/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx index 7b6da7d245c8e9b2d37f7191e56867903a2a76af..01a9d01124657247bdc64c8933b6047c4cf68bd4 100644 --- a/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx +++ b/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx @@ -159,7 +159,7 @@ private: AddParameter(ParameterType_Radius, "interpolator.bco.radius", "Radius for bicubic interpolation"); SetParameterDescription("interpolator.bco.radius","This parameter allows controlling the size of the bicubic interpolation filter. If the target pixel size is higher than the input pixel size, increasing this parameter will reduce aliasing artifacts."); SetDefaultParameterInt("interpolator.bco.radius", 2); - SetParameterString("interpolator","bco", false); + SetParameterString("interpolator","bco"); // RAM available AddRAMParameter("ram"); diff --git a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx index 1d1018e8fc74a755fa8b425a86369e4c0afc7d22..2f5786587b999d404edf1f2a82f20dd59ab5fd29 100644 --- a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx +++ b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx @@ -164,7 +164,7 @@ private: if(!HasUserValue("mode") && HasValue("inr") && HasValue("inm") && otb::PleiadesPToXSAffineTransformCalculator::CanCompute(GetParameterImage("inr"),GetParameterImage("inm"))) { otbAppLogWARNING("Forcing PHR mode with PHR data. You need to add \"-mode default\" to force the default mode with PHR images."); - SetParameterString("mode","phr", false); + SetParameterString("mode","phr"); } } diff --git a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx index 751678774184b69c0d048d18f906c2ecdb55694c..0709ad8007ff37fd6dafd0d3fa6b9a00d59ce738 100644 --- a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx +++ b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx @@ -68,9 +68,8 @@ private: AddRAMParameter(); - AddParameter(ParameterType_Empty, "noise", "Disable Noise"); + AddParameter(ParameterType_Bool, "noise", "Disable Noise"); SetParameterDescription("noise", "Flag to disable noise. For 5.2.0 release, the noise values are only read by TerraSARX product."); - MandatoryOff("noise"); AddParameter(ParameterType_Choice, "lut", "Lookup table sigma /gamma/ beta/ DN."); SetParameterDescription("lut", "Lookup table values are not available with all SAR products. Products that provide lookup table with metadata are: Sentinel1, Radarsat2."); @@ -104,17 +103,8 @@ private: // Set the filer input m_CalibrationFilter = CalibrationFilterType::New(); m_CalibrationFilter->SetInput(floatComplexImage); - - if (IsParameterEnabled("noise")) - { - m_CalibrationFilter->SetEnableNoise(false); - } - - short lut = 0; - - lut = GetParameterInt("lut"); - - m_CalibrationFilter->SetLookupSelected(lut); + m_CalibrationFilter->SetEnableNoise( !bool(GetParameterInt("noise")) ); + m_CalibrationFilter->SetLookupSelected(GetParameterInt("lut")); // Set the output image SetParameterOutputImage("out", m_CalibrationFilter->GetOutput()); diff --git a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx index 48dd57c2ad75d5f31c5eddd08ff606239f7aaa2a..7588f4eb873b073f9c101ce568b1c6c0c941ba67 100644 --- a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx +++ b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx @@ -297,10 +297,10 @@ private: m_InstanceFilter->Update(); - SetParameterFloat("rc",m_InstanceFilter->GetMeanRC(), false); - SetParameterFloat("rf",m_InstanceFilter->GetMeanRF(), false); - SetParameterFloat("ra",m_InstanceFilter->GetMeanRA(), false); - SetParameterFloat("rm",m_InstanceFilter->GetMeanRM(), false); + SetParameterFloat("rc",m_InstanceFilter->GetMeanRC()); + SetParameterFloat("rf",m_InstanceFilter->GetMeanRF()); + SetParameterFloat("ra",m_InstanceFilter->GetMeanRA()); + SetParameterFloat("rm",m_InstanceFilter->GetMeanRM()); } ImageToLabelMapFilterType::Pointer m_GTFilter; diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx index 93694cc420dcc271c6dff0ac551d43d519acd2b4..280faee001b8f12462b2799e26a0e187572c4027 100644 --- a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx +++ b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx @@ -139,7 +139,7 @@ private: void RemoveFile(std::string tile) { // Cleanup - if(IsParameterEnabled("cleanup")) + if(GetParameterInt("cleanup")) { // Try to remove the geom file if existing std::string geomfile = tile.substr(0,tile.size() - itksys::SystemTools::GetFilenameExtension(tile.c_str()).size()).append(".geom"); @@ -302,10 +302,9 @@ private: MandatoryOff("tmpdir"); DisableParameter("tmpdir"); - AddParameter(ParameterType_Empty,"cleanup","Temporary files cleaning"); - EnableParameter("cleanup"); + AddParameter(ParameterType_Bool,"cleanup","Temporary files cleaning"); SetParameterDescription("cleanup","If activated, the application will try to remove all temporary files it created."); - MandatoryOff("cleanup"); + SetParameterInt("cleanup",1); // Doc example parameter settings SetDocExampleParameterValue("in","smooth.tif"); @@ -724,7 +723,7 @@ private: // Release input files m_FinalReader = ITK_NULLPTR; - if(IsParameterEnabled("cleanup")) + if(GetParameterInt("cleanup")) { otbAppLogINFO(<<"Final clean-up ..."); diff --git a/Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx b/Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx index 27f8da837771c4eada660c43b6628e6fa32ec462..05ca673b6434030bab8d22067c9fcdc7219f4eaf 100644 --- a/Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx +++ b/Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx @@ -120,11 +120,10 @@ private: "The output raster image", "It corresponds to the output of the small region merging step."); - AddParameter( ParameterType_Empty, "cleanup", "Temporary files cleaning" ); - EnableParameter( "cleanup" ); + AddParameter( ParameterType_Bool, "cleanup", "Temporary files cleaning" ); SetParameterDescription( "cleanup", "If activated, the application will try to clean all temporary files it created" ); - MandatoryOff( "cleanup" ); + SetParameterInt("cleanup",1); // Setup RAM ShareParameter("ram","smoothing.ram"); diff --git a/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx b/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx index 8f63bf13ef99f1062726c988b7c6b18a8aa236d5..d8980392b05ebf8fc2694057e59bda0554de7239 100644 --- a/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx +++ b/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx @@ -159,10 +159,8 @@ private: SetMinimumParameterFloatValue("rangeramp", 0); MandatoryOff("rangeramp"); - AddParameter(ParameterType_Empty, "modesearch", "Mode search."); + AddParameter(ParameterType_Bool, "modesearch", "Mode search."); SetParameterDescription("modesearch", "If activated pixel iterative convergence is stopped if the path crosses an already converged pixel. Be careful, with this option, the result will slightly depend on thread number and the results will not be stable (see [4] for more details)."); - DisableParameter("modesearch"); - // Doc example parameter settings SetDocExampleParameterValue("in", "maur_rgb.png"); @@ -192,7 +190,7 @@ private: m_Filter->SetThreshold(GetParameterFloat("thres")); m_Filter->SetMaxIterationNumber(GetParameterInt("maxiter")); m_Filter->SetRangeBandwidthRamp(GetParameterFloat("rangeramp")); - m_Filter->SetModeSearch(IsParameterEnabled("modesearch")); + m_Filter->SetModeSearch(GetParameterInt("modesearch")); //Compute the margin used to ensure exact results (tile wise smoothing) //This margin is valid for the default uniform kernel used by the @@ -211,7 +209,7 @@ private: { SetParameterOutputImage("foutpos", m_Filter->GetSpatialOutput()); } - if(!IsParameterEnabled("modesearch")) + if(!GetParameterInt("modesearch")) { otbAppLogINFO(<<"Mode Search is disabled." << std::endl); } diff --git a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx index 5b3bfd2361f211e9dccf19b383542596fd1b994a..6978349e6401c67aebf778455263f373f64ff3cb 100644 --- a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx +++ b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx @@ -282,17 +282,13 @@ private: SetParameterDescription("mode.vector.inmask", "Only pixels whose mask value is strictly positive will be segmented."); MandatoryOff("mode.vector.inmask"); - AddParameter(ParameterType_Empty, "mode.vector.neighbor", "8-neighbor connectivity"); + AddParameter(ParameterType_Bool, "mode.vector.neighbor", "8-neighbor connectivity"); SetParameterDescription("mode.vector.neighbor", "Activate 8-Neighborhood connectivity (default is 4)."); - MandatoryOff("mode.vector.neighbor"); - DisableParameter("mode.vector.neighbor"); - - AddParameter(ParameterType_Empty,"mode.vector.stitch","Stitch polygons"); + AddParameter(ParameterType_Bool,"mode.vector.stitch","Stitch polygons"); SetParameterDescription("mode.vector.stitch", "Scan polygons on each side of tiles and stitch polygons which connect by more than one pixel."); - MandatoryOff("mode.vector.stitch"); - EnableParameter("mode.vector.stitch"); + SetParameterInt("mode.vector.stitch",1); AddParameter(ParameterType_Int, "mode.vector.minsize", "Minimum object size"); SetParameterDescription("mode.vector.minsize", @@ -311,11 +307,11 @@ private: AddParameter(ParameterType_String, "mode.vector.layername", "Layer name"); SetParameterDescription("mode.vector.layername", "Name of the layer in the vector file or database (default is Layer)."); - SetParameterString("mode.vector.layername", "layer", false); + SetParameterString("mode.vector.layername", "layer"); AddParameter(ParameterType_String, "mode.vector.fieldname", "Geometry index field name"); SetParameterDescription("mode.vector.fieldname", "Name of the field holding the geometry index in the output vector file or database."); - SetParameterString("mode.vector.fieldname", "DN", false); + SetParameterString("mode.vector.fieldname", "DN"); AddParameter(ParameterType_Int, "mode.vector.tilesize", "Tiles size"); SetParameterDescription("mode.vector.tilesize", @@ -365,7 +361,7 @@ private: // Retrieve tile size parameter const unsigned int tileSize = static_cast<unsigned int> (this->GetParameterInt("mode.vector.tilesize")); // Retrieve the 8-connected option - bool use8connected = IsParameterEnabled("mode.vector.neighbor"); + bool use8connected = GetParameterInt("mode.vector.neighbor"); // Retrieve min object size parameter const unsigned int minSize = static_cast<unsigned int> (this->GetParameterInt("mode.vector.minsize")); @@ -673,7 +669,7 @@ private: ogrDS->SyncToDisk(); // Stitching mode - if (IsParameterEnabled("mode.vector.stitch")) + if (GetParameterInt("mode.vector.stitch")) { otbAppLogINFO(<<"Segmentation done, stiching polygons ..."); diff --git a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx index 2ec8f7e63a0c00d90c3156c390ea71ce3af63573..41c9257ac04acd9256df53ad382608a17f26110b 100644 --- a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx +++ b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx @@ -202,7 +202,7 @@ private: DisableParameter("io.outmask"); MandatoryOff("io.outmask"); - AddParameter(ParameterType_Empty,"io.outmetric","Flag to output optimal " + AddParameter(ParameterType_Bool,"io.outmetric","Flag to output optimal " "metric values as well"); SetParameterDescription("io.outmetric","If enabled, the output image will " "have a third component with metric optimal values"); @@ -847,7 +847,7 @@ private: m_OutputImageList->PushBack(hdispImage); m_OutputImageList->PushBack(vdispImage); - if(IsParameterEnabled("io.outmetric")) + if(GetParameterInt("io.outmetric")) { m_OutputImageList->PushBack(metricImage); } diff --git a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx index 279c09ad2f9734bf45a95cb612408edb36efb8b8..b077adb1abdae581bc2c5ade1c51828fa5ea0aae 100644 --- a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx +++ b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx @@ -368,7 +368,7 @@ private: "first and second image, a second couple with third and fourth image etc." " (in this case image list must be even)."); MandatoryOff("input.co"); - SetParameterString("input.co","", false); + SetParameterString("input.co",""); DisableParameter("input.co"); AddParameter(ParameterType_Int, "input.channel", "Input Image channel"); @@ -385,7 +385,7 @@ private: // // Build the Output Map Projection // for custom map projection MapProjectionParametersHandler::AddMapProjectionParameters(this, "map"); - SetParameterString("map","wgs", false); + SetParameterString("map","wgs"); AddParameter(ParameterType_Float, "output.res","Output resolution"); SetParameterDescription("output.res","Spatial sampling distance of the output elevation : the cell size (in m)"); @@ -525,20 +525,16 @@ private: AddParameter(ParameterType_Group,"postproc","Postprocessing parameters"); SetParameterDescription("postproc","This group of parameters allow use optional filters."); - AddParameter(ParameterType_Empty,"postproc.bij","Use bijection consistency" + AddParameter(ParameterType_Bool,"postproc.bij","Use bijection consistency" " in block matching strategy"); SetParameterDescription("postproc.bij","Use bijection consistency. " "Right to Left correlation is computed to validate Left to Right " "disparities. If bijection is not found, the disparity is rejected."); - MandatoryOff("postproc.bij"); - EnableParameter("postproc.bij"); + SetParameterInt("postproc.bij", 1); - AddParameter(ParameterType_Empty,"postproc.med","Use median disparities filtering"); + AddParameter(ParameterType_Bool,"postproc.med","Use median disparities filtering"); SetParameterDescription("postproc.med","Disparity map can be filtered using" " median post filtering (disabled by default)."); - MandatoryOff("postproc.med"); - DisableParameter("postproc.med"); - AddParameter(ParameterType_Float,"postproc.metrict","Correlation metric threshold"); SetParameterDescription("postproc.metrict","Use block matching metric " @@ -624,7 +620,7 @@ private: } else blockMatcherFilter->MinimizeOff(); - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { invBlockMatcherFilter->SetLeftInput(rightImage); invBlockMatcherFilter->SetRightInput(leftImage); @@ -947,7 +943,7 @@ private: m_Filters.push_back(lBandMathFilter.GetPointer()); BandMathFilterType::Pointer finalMaskFilter; - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { finalMaskFilter = BandMathFilterType::New(); finalMaskFilter->SetNthInput(0, lBandMathFilter->GetOutput(), "inmask"); @@ -992,7 +988,7 @@ private: blockMatcherFilterPointer = SSDDivMeanBlockMatcherFilter.GetPointer(); m_Filters.push_back(blockMatcherFilterPointer); - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { //Reverse correlation invSSDDivMeanBlockMatcherFilter = SSDDivMeanBlockMatchingFilterType::New(); @@ -1025,7 +1021,7 @@ private: blockMatcherFilterPointer = SSDBlockMatcherFilter.GetPointer(); m_Filters.push_back(blockMatcherFilterPointer); - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { //Reverse correlation invSSDBlockMatcherFilter = SSDBlockMatchingFilterType::New(); @@ -1056,7 +1052,7 @@ private: blockMatcherFilterPointer = NCCBlockMatcherFilter.GetPointer(); m_Filters.push_back(blockMatcherFilterPointer); - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { //Reverse correlation invNCCBlockMatcherFilter = NCCBlockMatchingFilterType::New(); @@ -1090,7 +1086,7 @@ private: blockMatcherFilterPointer = LPBlockMatcherFilter.GetPointer(); m_Filters.push_back(blockMatcherFilterPointer); - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { //Reverse correlation invLPBlockMatcherFilter = LPBlockMatchingFilterType::New(); @@ -1119,7 +1115,7 @@ private: break; } - if (IsParameterEnabled("postproc.bij")) + if (GetParameterInt("postproc.bij")) { otbAppLogINFO(<<"Using reverse block-matching to filter incoherent disparity values."); bijectFilter = BijectionFilterType::New(); @@ -1149,7 +1145,7 @@ private: FloatImageType::Pointer hDispOutput = subPixelFilterPointer->GetOutput(0); FloatImageType::Pointer finalMaskImage=finalMaskFilter->GetOutput(); - if (IsParameterEnabled("postproc.med")) + if (GetParameterInt("postproc.med")) { MedianFilterType::Pointer hMedianFilter = MedianFilterType::New(); hMedianFilter->SetInput(subPixelFilterPointer->GetOutput(0)); @@ -1183,7 +1179,7 @@ private: FloatImageType::Pointer hDispOutput2 = disparityTranslateFilter->GetHorizontalDisparityMapOutput(); FloatImageType::Pointer vDispOutput2 = disparityTranslateFilter->GetVerticalDisparityMapOutput(); FloatImageType::Pointer translatedMaskImage = dispTranslateMaskFilter->GetOutput(); - if (IsParameterEnabled("postproc.med")) + if (GetParameterInt("postproc.med")) { MedianFilterType::Pointer hMedianFilter2 = MedianFilterType::New(); MedianFilterType::Pointer vMedianFilter2 = MedianFilterType::New(); diff --git a/Modules/Applications/AppTest/app/otbTestApplication.cxx b/Modules/Applications/AppTest/app/otbTestApplication.cxx index a2e9ee940da3b473f8e69fbd152eda675c66256d..4407d76ed36a5da9f329b31edd215ba6ebcbaaca 100644 --- a/Modules/Applications/AppTest/app/otbTestApplication.cxx +++ b/Modules/Applications/AppTest/app/otbTestApplication.cxx @@ -56,7 +56,8 @@ private: AddDocTag("Test"); //std::cout << "TestApplication::DoInit" << std::endl; - AddParameter(ParameterType_Empty, "boolean", "Boolean"); + AddParameter(ParameterType_Empty, "empty", "Boolean (old impl.)"); + AddParameter(ParameterType_Bool, "boolean", "Boolean"); AddParameter(ParameterType_Int, "int", "Integer"); MandatoryOff("int"); AddParameter(ParameterType_Float, "float", "Float"); diff --git a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx index 748d8f27be36f75205398bcbf7114b4b66343856..9ddef6c295fc4d12a2d60cbeeef7e1242c73be61 100644 --- a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx +++ b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx @@ -132,7 +132,7 @@ private: AddParameter(ParameterType_String,"mode.attribute.field","The attribute field to burn"); SetParameterDescription("mode.attribute.field","Name of the attribute field to burn"); - SetParameterString("mode.attribute.field","DN", false); + SetParameterString("mode.attribute.field","DN"); AddRAMParameter(); diff --git a/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx b/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx index d55626ed0bb0f79d3696a4a2940c59a870038217..ba625b5f4862f0f0377ee4d0f082193dcd0815e7 100644 --- a/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx +++ b/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx @@ -98,11 +98,10 @@ private: // Elevation ElevationParametersHandler::AddElevationParameters(this, "elev"); - AddParameter(ParameterType_Empty, "printclasses", "Displays available key/value classes"); + AddParameter(ParameterType_Bool, "printclasses", "Displays available key/value classes"); SetParameterDescription("printclasses","Print the key/value classes " "available for the selected support image. If enabled, the OSM tag Key " "(-key) and the output (-out) become optional" ); - MandatoryOff("printclasses"); // Doc example parameter settings SetDocExampleParameterValue("support", "qb_RoadExtract.tif"); @@ -118,15 +117,15 @@ private: // CASE: when the -print option is not required and the User // does not set the option OSMKey or the option Output or does not // set both of them - if ( !this->HasValue("printclasses") ) + if ( GetParameterInt("printclasses") ) { - MandatoryOn("out"); - MandatoryOn("key"); + MandatoryOff("out"); + MandatoryOff("key"); } else { - MandatoryOff("out"); - MandatoryOff("key"); + MandatoryOn("out"); + MandatoryOn("key"); } } @@ -178,7 +177,7 @@ private: // If the user wants to print the Key/Values present in the XML file // downloaded : - if ( this->HasValue("printclasses")) + if ( GetParameterInt("printclasses")) { // Print the classes VectorDataProviderType::KeyMapType keymap = m_VdOSMGenerator->GetKeysMap(); diff --git a/Modules/Core/Common/include/otbConfigurationManager.h b/Modules/Core/Common/include/otbConfigurationManager.h index 8c8f9af7ccd5ab93838100e780fe1546b0d66a7a..71e45fe72763231c649d559c687f2c8b7dafe0b8 100644 --- a/Modules/Core/Common/include/otbConfigurationManager.h +++ b/Modules/Core/Common/include/otbConfigurationManager.h @@ -31,7 +31,7 @@ #include <string> #include <boost/cstdint.hpp> - +#include "itkLoggerBase.h" #include "OTBCommonExport.h" namespace otb @@ -84,6 +84,27 @@ public: */ static RAMValueType GetMaxRAMHint(); + /** + * Logger level controls the level of logging that OTB will output. + * + * This is used to set-up the otb::Logger class. + * + * If OTB_LOGGER_LEVEL environment variable is set to one of DEBUG, + * INFO, WARNING, CRITICAL or FATAL, the logger level will be + * set accordingly. + * + * Priority is DEBUG < INFO < WARNING < CRITICAL < FATAL. + * + * Only messages with a higher priority than the logger level will + * be displayed. + * + * By default (if OTB_LOGGER_LEVEL is not set or can not be + * decoded), level is INFO. + * + */ + static itk::LoggerBase::PriorityLevelType GetLoggerLevel(); + + private: ConfigurationManager(); //purposely not implemented ~ConfigurationManager(); //purposely not implemented diff --git a/Modules/Wrappers/ApplicationEngine/include/otbLogger.h b/Modules/Core/Common/include/otbLogger.h similarity index 77% rename from Modules/Wrappers/ApplicationEngine/include/otbLogger.h rename to Modules/Core/Common/include/otbLogger.h index ba43072a199e2a1e29f481dc232022e457017389..3e69d173c0a9c75c0451919930fb3068b25b66e2 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbLogger.h +++ b/Modules/Core/Common/include/otbLogger.h @@ -23,6 +23,7 @@ #include "itkLoggerBase.h" #include "itkLogger.h" +#include "OTBCommonExport.h" namespace otb { @@ -31,9 +32,9 @@ namespace otb { * * Sets OTB wide settings in its constructor * - * \ingroup OTBApplicationEngine + * \ingroup OTBCommon */ -class Logger : public itk::Logger +class OTBCommon_EXPORT Logger : public itk::Logger { public: typedef Logger Self; @@ -41,15 +42,27 @@ public: typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - itkTypeMacro(Logger, Object); - itkNewMacro(Self); + itkTypeMacro(Logger, itk::Logger); + + static Pointer Instance(); + itkNewMacro(Self); + // Overwrite this to provide custom formatting of log entries std::string BuildFormattedEntry(itk::Logger::PriorityLevelType, std::string const&) ITK_OVERRIDE; + void LogSetupInformation(); + protected: - Logger(); - virtual ~Logger(); + Logger(); + virtual ~Logger() ITK_OVERRIDE; + +private: + Logger(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + static Pointer CreateInstance(); + }; // class Logger } // namespace otb diff --git a/Modules/Core/Common/include/otbMacro.h b/Modules/Core/Common/include/otbMacro.h index 84a5ffc77372e6bc0f6500b0f0a1e14146cf68fe..6a248d4551a2f3f57220b4de62f3550a7dee5ad0 100644 --- a/Modules/Core/Common/include/otbMacro.h +++ b/Modules/Core/Common/include/otbMacro.h @@ -31,6 +31,7 @@ #include "itkMacro.h" #include "itkObject.h" #include "otbConfigure.h" +#include "otbLogger.h" /** * \namespace otb @@ -42,86 +43,31 @@ namespace otb { } // end namespace otb - this is here for documentation purposes -/** This macro is used to print debug (or other information). They are - * also used to catch errors, etc. Example usage looks like: - * itkDebugMacro(<< "this is debug info" << this->SomeVariable); */ -#define otbDebugMacro(x) itkDebugMacro(x) -/* { if ( this->GetDebug() && *::itk::Object::GetGlobalWarningDisplay()) \ - { std::ostringstream itkmsg; \ - itkmsg << "Debug: In " __FILE__ ", line " << __LINE__ << "\n" \ - << this->GetNameOfClass() << " (" << this << "): " x \ - << "\n\n"; \ - ::itk::OutputWindowDisplayDebugText(itkmsg.str().c_str()); } \ -}*/ - -#define otbMsgDebugMacro(x) \ - { \ - if (this->GetDebug() && ::itk::Object::GetGlobalWarningDisplay()) \ - { \ - std::ostringstream itkmsg; \ - itkmsg << " Msg Debug: " x << "\n"; \ - ::itk::OutputWindowDisplayDebugText(itkmsg.str().c_str()); \ - } \ - } +#define otbFileContext(x) \ + << "file " __FILE__ ", line " << __LINE__<<", " x -#ifndef NDEBUG -#define otbGenericMsgDebugMacro(x) \ - { \ - if (::itk::Object::GetGlobalWarningDisplay()) \ - { \ - std::ostringstream itkmsg; \ - itkmsg << " Generic Msg Debug: " x << "\n"; \ - ::itk::OutputWindowDisplayDebugText(itkmsg.str().c_str()); \ - } \ - } -#else -#define otbGenericMsgDebugMacro(x) -#endif +#define otbClassContext(x) \ + << this->GetNameOfClass() << " (" << this << "): " x -#define otbGenericMsgTestingMacro(x) \ - { \ - std::cout x << std::endl; \ - } +// Beware that to log to CRITICAL level, level should be passed as "Error" +#define otbLogMacro(level,msg) \ + { \ + std::ostringstream itkmsg; \ + itkmsg msg << "\n"; \ + otb::Logger::Instance()->level(itkmsg.str().c_str()); \ + } -#ifdef OTB_SHOW_ALL_MSG_DEBUG -#define otbMsgDevMacro(x) \ - { \ - { \ - std::ostringstream itkmsg; \ - itkmsg << " Msg Dev: (" << __FILE__ << ":" << __LINE__ << ") " x << "\n"; \ - ::itk::OutputWindowDisplayDebugText(itkmsg.str().c_str()); \ - } \ - } -#else -#define otbMsgDevMacro(x) -#endif - -/** This macro is used to print warning information (i.e., unusual circumstance - * but not necessarily fatal.) Example usage looks like: - * itkWarningMacro(<< "this is warning info" << this->SomeVariable); */ -#define otbWarningMacro(x) \ - { \ - if (itk::Object::GetGlobalWarningDisplay()) \ - { \ - std::ostringstream itkmsg; \ - itkmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << "\n" \ - << this->GetNameOfClass() << " (" << this << "): " x \ - << "\n\n"; \ - itk::OutputWindowDisplayWarningText(itkmsg.str().c_str()); \ - } \ - } - -#define otbGenericWarningMacro(x) \ - { \ - if (itk::Object::GetGlobalWarningDisplay()) \ - { \ - std::ostringstream itkmsg; \ - itkmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << ": " x <<"\n";\ - itk::OutputWindowDisplayWarningText(itkmsg.str().c_str()); \ - } \ - } +// Re-definition of old log macros to use the otbLogMacro +#define otbDebugMacro(x) otbLogMacro(Debug,otbFileContext(otbClassContext(x))) +#define otbMsgDebugMacro(x) otbLogMacro(Debug,otbFileContext(x)) +#define otbGenericMsgDebugMacro(x) otbLogMacro(Debug,x) +#define otbMsgDevMacro(x) otbLogMacro(Debug,otbFileContext(x)) +#define otbWarningMacro(x) otbLogMacro(Warning,otbFileContext(otbClassContext(x))) +#define otbGenericWarningMacro(x) otbLogMacro(Warning,otbFileContext(x)) +#define otbGenericMsgTestingMAcro(x) otbLogMacro(Info,"[testing] "<<x) + /** This macro is used to control condition. It use ONLY by the OTB developers * */ diff --git a/Modules/Core/Common/src/CMakeLists.txt b/Modules/Core/Common/src/CMakeLists.txt index 02ff6250e794704244acbe370fc7c562a13524c3..ce5d20761e59a5e57cf7f3b909317dc1c072f7aa 100644 --- a/Modules/Core/Common/src/CMakeLists.txt +++ b/Modules/Core/Common/src/CMakeLists.txt @@ -29,12 +29,12 @@ set(OTBCommon_SRC otbWriterWatcherBase.cxx otbStopwatch.cxx otbStringToHTML.cxx + otbLogger.cxx ) add_library(OTBCommon ${OTBCommon_SRC}) target_link_libraries(OTBCommon - ${OTBITK_LIBRARIES} - + ${OTBITK_LIBRARIES} ${OTBGDAL_LIBRARIES} ) otb_module_target(OTBCommon) diff --git a/Modules/Core/Common/src/otbConfigurationManager.cxx b/Modules/Core/Common/src/otbConfigurationManager.cxx index de0ea045799aaded54294a9eba4cbfe68598fd65..d12d1833620ebce22b3cb1615457f7ec87057031 100644 --- a/Modules/Core/Common/src/otbConfigurationManager.cxx +++ b/Modules/Core/Common/src/otbConfigurationManager.cxx @@ -20,9 +20,13 @@ #include "otbConfigurationManager.h" +#include "otbMacro.h" + #include "itksys/SystemTools.hxx" #include <cstdlib> +#include <algorithm> +#include <string> namespace otb { @@ -59,6 +63,39 @@ ConfigurationManager::RAMValueType ConfigurationManager::GetMaxRAMHint() } return value; +} + +itk::LoggerBase::PriorityLevelType ConfigurationManager::GetLoggerLevel() +{ + std::string svalue; + // Default value is INFO + itk::LoggerBase::PriorityLevelType level = itk::LoggerBase::INFO; + + if(itksys::SystemTools::GetEnv("OTB_LOGGER_LEVEL",svalue)) + { + if(svalue.compare("DEBUG") == 0) + { + level = itk::LoggerBase::DEBUG; + } + else if(svalue.compare("INFO") == 0) + { + level = itk::LoggerBase::INFO; + } + else if(svalue.compare("WARNING") == 0) + { + level = itk::LoggerBase::WARNING; + } + else if(svalue.compare("CRITICAL") == 0) + { + level = itk::LoggerBase::CRITICAL; + } + else + { + otbLogMacro(Error,<<"Unknown value for OTB_LOGGER_LEVEL_MACRO. Possible values are DEBUG, INFO, WARNING, CRITICAL."); + } + } + return level; } + } diff --git a/Modules/Core/Common/src/otbConfigure.h.in b/Modules/Core/Common/src/otbConfigure.h.in index 5194398344bab96a44eb4bb622fda9dc1bf0ae46..2146cf15bffa6fdb90e30c766a9f3f483263944e 100644 --- a/Modules/Core/Common/src/otbConfigure.h.in +++ b/Modules/Core/Common/src/otbConfigure.h.in @@ -27,9 +27,6 @@ #cmakedefine OTB_BUILD_SHARED_LIBS -/* Show developer debug messages */ -#cmakedefine OTB_SHOW_ALL_MSG_DEBUG - #cmakedefine OTB_USE_GDAL_20 #cmakedefine OTB_USE_OPENMP diff --git a/Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx b/Modules/Core/Common/src/otbLogger.cxx similarity index 57% rename from Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx rename to Modules/Core/Common/src/otbLogger.cxx index f7994eed4db3a1830b7fc2e1028bd23344c205eb..b3730cf445a5816ca693da32de7d2a71f3aaba37 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx +++ b/Modules/Core/Common/src/otbLogger.cxx @@ -20,18 +20,42 @@ #include "otbLogger.h" #include "itksys/SystemTools.hxx" +#include "otbConfigurationManager.h" +#include "itkStdStreamLogOutput.h" +#include <iostream> +#include "gdal.h" +#include "itkMultiThreader.h" namespace otb { -Logger::Logger() : - itk::Logger::Logger() +Logger::Pointer Logger::CreateInstance() { -#if OTB_DEBUG - this->SetPriorityLevel(itk::LoggerBase::DEBUG); -#else - this->SetPriorityLevel(itk::LoggerBase::INFO); -#endif + Logger::Pointer instance = Logger::New(); + + // By default, redirect logs to std::cout + itk::StdStreamLogOutput::Pointer defaultOutput = itk::StdStreamLogOutput::New(); + defaultOutput->SetStream(std::cout); + + instance->AddLogOutput(defaultOutput); + + // Log setup information + instance->LogSetupInformation(); + + return instance; +} + +Logger::Pointer Logger::Instance() +{ + // Static locales are initialized once in a thread-safe way + static Logger::Pointer instance = CreateInstance(); + + return instance; +} + +Logger::Logger() +{ + this->SetPriorityLevel(otb::ConfigurationManager::GetLoggerLevel()); this->SetLevelForFlushing(itk::LoggerBase::CRITICAL); @@ -43,6 +67,26 @@ Logger::~Logger() { } +void Logger::LogSetupInformation() +{ + std::ostringstream oss; + + oss<<"Default RAM limit for OTB is "<<otb::ConfigurationManager::GetMaxRAMHint()<<" MB"<<std::endl; + this->Info(oss.str()); + oss.str(""); + oss.clear(); + + oss<<"GDAL maximum cache size is "<<GDALGetCacheMax64()/(1024*1024)<<" MB"<<std::endl; + this->Info(oss.str()); + oss.str(""); + oss.clear(); + + oss<<"OTB will use at most "<<itk::MultiThreader::GetGlobalDefaultNumberOfThreads()<<" threads"<<std::endl; + this->Info(oss.str()); + oss.str(""); + oss.clear(); +} + std::string Logger::BuildFormattedEntry(itk::Logger::PriorityLevelType level, std::string const & content) { static const std::string levelString[] = { "(MUSTFLUSH)", "(FATAL)", "(CRITICAL)", diff --git a/Modules/Core/ImageBase/include/otbExtractROIBase.txx b/Modules/Core/ImageBase/include/otbExtractROIBase.txx index 78f546387ffad9fd276030426eaf6abb1529480d..26108adf677fe834494606ae68f2d252778201ce 100644 --- a/Modules/Core/ImageBase/include/otbExtractROIBase.txx +++ b/Modules/Core/ImageBase/include/otbExtractROIBase.txx @@ -152,11 +152,6 @@ ExtractROIBase<TInputImage, TOutputImage> } requestedRegion.SetIndex(index); inputPtr->SetRequestedRegion(requestedRegion); - - otbMsgDevMacro(<< "InputRequestedRegion (otbExtractROIBase): "); - otbMsgDevMacro(<< " - index: " << requestedRegion.GetIndex()); - otbMsgDevMacro(<< " - size: " << requestedRegion.GetSize()); - } /** diff --git a/Modules/Core/Streaming/include/otbRAMDrivenAdaptativeStreamingManager.txx b/Modules/Core/Streaming/include/otbRAMDrivenAdaptativeStreamingManager.txx index 07dcdbd82dbac30b545398f9e17f7af23bc38e53..743d5de28151ab5a78646e113ff5217b7b1296b1 100644 --- a/Modules/Core/Streaming/include/otbRAMDrivenAdaptativeStreamingManager.txx +++ b/Modules/Core/Streaming/include/otbRAMDrivenAdaptativeStreamingManager.txx @@ -72,7 +72,7 @@ RAMDrivenAdaptativeStreamingManager<TImage>::PrepareStreaming( itk::DataObject * this->m_Splitter = splitter; this->m_ComputedNumberOfSplits = this->m_Splitter->GetNumberOfSplits(region, nbDivisions); - otbMsgDevMacro(<< "Number of split : " << this->m_ComputedNumberOfSplits) + this->m_Region = region; } diff --git a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx index b4fc50fbfacba49a145987ad00fdc73a6d80dd82..008b6c0eaafe7d39dfc3febf6889be7471d1cf0c 100644 --- a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx +++ b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx @@ -227,11 +227,11 @@ StreamingImageVirtualWriter<TInputImage> m_ObserverID = source->AddObserver(itk::ProgressEvent(), command); m_IsObserving = true; } - else - { - itkWarningMacro(<< "Could not get the source process object. Progress report might be buggy"); - } + const auto firstSplitSize = m_StreamingManager->GetSplit(0).GetSize(); + otbLogMacro(Info,<<"Estimation will be performed in "<<m_NumberOfDivisions<<" blocks of "<<firstSplitSize[0]<<"x"<<firstSplitSize[1]<<" pixels"); + + /** * Loop over the number of pieces, execute the upstream pipeline on each * piece, and copy the results into the output image. @@ -242,7 +242,6 @@ StreamingImageVirtualWriter<TInputImage> m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress()) { streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision); - otbMsgDevMacro(<< "Processing region : " << streamRegion ) //inputPtr->ReleaseData(); //inputPtr->SetRequestedRegion(streamRegion); //inputPtr->Update(); diff --git a/Modules/Core/Streaming/include/otbStreamingManager.txx b/Modules/Core/Streaming/include/otbStreamingManager.txx index b0fdfced068fffe79695afedc671b6f7d3d22d67..d30e3a2580195baf4dc0281fa7826af34e24e5cc 100644 --- a/Modules/Core/Streaming/include/otbStreamingManager.txx +++ b/Modules/Core/Streaming/include/otbStreamingManager.txx @@ -47,12 +47,9 @@ StreamingManager<TImage>::GetActualAvailableRAMInBytes(MemoryPrintType available if (availableRAMInBytes == 0) { - otbMsgDevMacro(<< "Retrieving available RAM size from configuration"); // Retrieve it from the configuration availableRAMInBytes = 1024*1024*ConfigurationManager::GetMaxRAMHint(); } - - otbMsgDevMacro("RAM used to estimate memory footprint : " << availableRAMInBytes / 1024 / 1024 << " MB") return availableRAMInBytes; } @@ -62,8 +59,6 @@ StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * inp MemoryPrintType availableRAM, double bias) { - otbMsgDevMacro(<< "availableRAM " << availableRAM) - MemoryPrintType availableRAMInBytes = GetActualAvailableRAMInBytes(availableRAM); otb::PipelineMemoryPrintCalculator::Pointer memoryPrintCalculator; @@ -103,7 +98,6 @@ StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * inp if (smallRegionSuccess) { - otbMsgDevMacro("Using an extract to estimate memory : " << smallRegion) // the region is well behaved, inside the largest possible region memoryPrintCalculator->SetDataToWrite(extractFilter->GetOutput() ); @@ -114,7 +108,6 @@ StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * inp } else { - otbMsgDevMacro("Using the input region to estimate memory : " << region) // the region is not well behaved // use the full region memoryPrintCalculator->SetDataToWrite(input); @@ -148,11 +141,8 @@ StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * inp unsigned int optimalNumberOfDivisions = otb::PipelineMemoryPrintCalculator::EstimateOptimalNumberOfStreamDivisions(pipelineMemoryPrint, availableRAMInBytes); - otbMsgDevMacro( "Estimated Memory print for the full image : " - << static_cast<unsigned int>(pipelineMemoryPrint * otb::PipelineMemoryPrintCalculator::ByteToMegabyte ) << std::endl) - otbMsgDevMacro( "Optimal number of stream divisions: " - << optimalNumberOfDivisions << std::endl) - + otbLogMacro(Info,<<"Estimated memory for full processing: "<<pipelineMemoryPrint * otb::PipelineMemoryPrintCalculator::ByteToMegabyte<<"MB (avail.: "<<availableRAMInBytes * otb::PipelineMemoryPrintCalculator::ByteToMegabyte<<" NB), optimal image partitioning: "<<optimalNumberOfDivisions<<" blocks"); + return optimalNumberOfDivisions; } diff --git a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx index d7d62e8c88cd6a779425feb92d5c9eeea7a71497..403c9d38674047805593342aa9cd3363c23d29a8 100644 --- a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx +++ b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx @@ -105,7 +105,7 @@ PipelineMemoryPrintCalculator::MemoryPrintType PipelineMemoryPrintCalculator ::EvaluateProcessObjectPrintRecursive(ProcessObjectType * process) { - otbMsgDevMacro(<< "EvaluateMemoryPrint for " << process->GetNameOfClass() << " (" << process << ")") + otbLogMacro(Debug,<<"Recursive evaluation of memory print for ProcessObject" << process->GetNameOfClass() << " (" << process << ")"); // This variable will store the final print MemoryPrintType print = 0; @@ -164,8 +164,9 @@ PipelineMemoryPrintCalculator::MemoryPrintType PipelineMemoryPrintCalculator ::EvaluateDataObjectPrint(DataObjectType * data) { - otbMsgDevMacro(<< "EvaluateMemoryPrint for " << data->GetNameOfClass() << " (" << data << ")") - + + otbLogMacro(Debug,<<"Evaluation of memory print for DataObject " << data->GetNameOfClass() << " (" << data << ")"); + #define OTB_IMAGE_SIZE_BLOCK(type) \ if(dynamic_cast<itk::Image<type, 2> *>(data) != NULL) \ { \ diff --git a/Modules/Feature/Descriptors/test/CMakeLists.txt b/Modules/Feature/Descriptors/test/CMakeLists.txt index 587685882e08c5adfec389e8d381de9cab0ea19d..6382e7b260145bece389dcc81ded8032f926bee1 100644 --- a/Modules/Feature/Descriptors/test/CMakeLists.txt +++ b/Modules/Feature/Descriptors/test/CMakeLists.txt @@ -263,9 +263,10 @@ otb_add_test(NAME feTvFourierMellinDescriptors COMMAND otbDescriptorsTestDriver ) otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterDistanceMap COMMAND otbDescriptorsTestDriver - --compare-ascii ${EPSILON_3} + --compare-ascii ${EPSILON_3} ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterDistanceMap.txt ${TEMP}/feTvImageToSIFTKeyPointSetFilterDistanceMap.txt + --ignore-lines-with 2 INFO DEBUG otbImageToSIFTKeyPointSetFilterDistanceMap ${INPUTDATA}/scene.png 6 3 0.08 10.0 diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx index f4cfe1ecfd01f6360d084c486daa451c0c794896..4f55f67b2b7e26937c2874ce508dad414bd9edb2 100644 --- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx +++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx @@ -74,57 +74,6 @@ public: }; // end of GDALDataTypeWrapper -/* -template<class InputType> -void printOutputData(InputType *pData, int nbBands, int nbPixelToRead) -{ - for (unsigned int itPxl = 0; itPxl < (unsigned int) (nbPixelToRead * nbBands); itPxl++) - { - std::cout << "Buffer["<< itPxl << "] = " << *(pData + itPxl) << std::endl; - } -}; - -void printDataBuffer(unsigned char *pData, GDALDataType pxlType, int nbBands, int nbPixelToRead) -{ - if (pxlType == GDT_Int16) - { - printOutputData( static_cast<short*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_Int32) - { - printOutputData( static_cast<int*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_Float32) - { - printOutputData( static_cast<float*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_Float64) - { - printOutputData( static_cast<double*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_CInt16) - { - printOutputData( static_cast<std::complex<short>*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_CInt32) - { - printOutputData( static_cast<std::complex<int>*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_CFloat32) - { - printOutputData( static_cast<std::complex<float>*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else if (pxlType == GDT_CFloat64) - { - printOutputData( static_cast<std::complex<double>*>( static_cast<void*>(pData) ), nbBands, nbPixelToRead); - } - else - { - std::cerr << "Pixel type unknown" << std::endl; - } -}; -*/ - GDALImageIO::GDALImageIO() { // By default set number of dimensions to two. @@ -147,9 +96,6 @@ GDALImageIO::GDALImageIO() m_IsIndexed = false; m_DatasetNumber = 0; - //m_poBands = NULL; - //m_hDriver = NULL; - //m_poDataset = NULL; m_NbBands = 0; m_FlagWriteImageInformation = true; @@ -177,7 +123,6 @@ bool GDALImageIO::CanReadFile(const char* file) // First check the extension if (file == ITK_NULLPTR) { - itkDebugMacro(<< "No filename specified."); return false; } m_Dataset = GDALDriverManagerWrapper::GetInstance().Open(file); @@ -207,7 +152,7 @@ void GDALImageIO::Read(void* buffer) // Check if conversion succeed if (p == ITK_NULLPTR) { - itkExceptionMacro(<< "GDAL : Bad alloc"); + itkExceptionMacro(<< "Buffer passed to GDALImageIO for reading is NULL."); return; } @@ -219,15 +164,10 @@ void GDALImageIO::Read(void* buffer) int lNbLinesRegion = this->GetIORegion().GetSize()[1]; int lNbColumnsRegion = this->GetIORegion().GetSize()[0]; - //std::cout << "OriginBuffer= " << lFirstLineRegion << " x " << lFirstColumnRegion << std::endl; - //std::cout << "SizeBuffer= " << lNbLinesRegion << " x " << lNbColumnsRegion << std::endl; - // Compute the origin of the image region to read at the initial resolution int lFirstLine = lFirstLineRegion * (1 << m_ResolutionFactor); int lFirstColumn = lFirstColumnRegion * (1 << m_ResolutionFactor); - //std::cout << "OriginImage= " << lFirstLine << " x " << lFirstColumn << std::endl; - // Compute the size of the image region to read at the initial resolution int lNbLines = lNbLinesRegion * (1 << m_ResolutionFactor); int lNbColumns = lNbColumnsRegion * (1 << m_ResolutionFactor); @@ -238,103 +178,11 @@ void GDALImageIO::Read(void* buffer) if (lFirstColumn + lNbColumns > static_cast<int>(m_OriginalDimensions[0])) lNbColumns = static_cast<int>(m_OriginalDimensions[0]-lFirstColumn); - //std::cout << "SizeImage= " << lNbLines << " x " << lNbColumns << std::endl; - - GDALDataset* dataset = m_Dataset->GetDataSet(); - // This special case is due to the fact the CINT/CLONG types - // do not exists in ITK. In this case we only report the first band - // TODO This should be fixed - /*if (GDALDataTypeIsComplex(m_PxType->pixType) - && (m_PxType->pixType != GDT_CFloat32) - && (m_PxType->pixType != GDT_CFloat64)) - { - int pixelOffset = m_BytePerPixel * m_NbBands; - int lineOffset = m_BytePerPixel * m_NbBands * lNbColumns; - int bandOffset = m_BytePerPixel; - int nbBands = m_NbBands; - - int nbPixelToRead = lNbColumns * lNbLines; - std::streamoff nbBytes = static_cast<std::streamoff>(m_NbBands) * static_cast<std::streamoff>(nbPixelToRead) * static_cast<std::streamoff>(m_BytePerPixel); - unsigned char *pBufferTemp = new unsigned char[static_cast<unsigned int>(nbBytes)]; - - // keep it for the moment - otbMsgDevMacro(<< "Parameters RasterIO (case CInt and CShort):" - << "\n indX = " << lFirstColumn - << "\n indY = " << lFirstLine - << "\n sizeX = " << lNbColumns - << "\n sizeY = " << lNbLines - << "\n GDAL Data Type = " << GDALGetDataTypeName(m_PxType->pixType) - << "\n pixelOffset = " << pixelOffset - << "\n lineOffset = " << lineOffset - << "\n bandOffset = " << bandOffset); - - CPLErr lCrGdal = m_Dataset->GetDataSet()->RasterIO(GF_Read, - lFirstColumn, - lFirstLine, - lNbColumns, - lNbLines, - pBufferTemp, //p, // pData - lNbColumns, - lNbLines, - m_PxType->pixType, - nbBands, - // We want to read all bands - NULL, - pixelOffset, - lineOffset, - bandOffset); - // Check for gdal error - if (lCrGdal == CE_Failure) - { - itkExceptionMacro(<< "Error while reading image (GDAL format) " << m_FileName ); - delete[] pBufferTemp; - return; - } - //std::cout << "RAW BUFFER:" <<std::endl; - //printDataBuffer(pBufferTemp, m_PxType->pixType, m_NbBands, lNbColumns*lNbLines); - - // Convert the buffer to GDT_Float64 type - typedef std::complex<float> RealType; - typedef double ScalarRealType; - - if (m_PxType->pixType == GDT_CInt32) - { - //std::cout << "Convert input File from GDT_CInt32 to GDT_CFloat32" << std::endl; - typedef std::complex<int> ComplexIntType; - - for (unsigned int itPxl = 0; itPxl < (unsigned int) (nbPixelToRead * m_NbBands); itPxl++) - { - ComplexIntType pxlValue = *(static_cast<ComplexIntType*>( static_cast<void*>(pBufferTemp)) + itPxl ); - - RealType pxlValueReal( static_cast<ScalarRealType>(pxlValue.real()), static_cast<ScalarRealType>(pxlValue.imag()) ); - - memcpy((void*) (&(p[itPxl*sizeof(RealType)])), (const void*) (&(pxlValueReal)), (size_t) (sizeof(RealType))); - } - } - else if (m_PxType->pixType == GDT_CInt16) - { - //std::cout << "Convert input File from GDT_CInt16 to GDT_CFloat32" << std::endl; - typedef std::complex<short> ComplexShortType; - - for (unsigned int itPxl = 0; itPxl < (unsigned int) (nbPixelToRead * m_NbBands); itPxl++) - { - ComplexShortType pxlValue = *(static_cast<ComplexShortType*>( static_cast<void*>(pBufferTemp)) + itPxl ); - - RealType pxlValueReal( static_cast<ScalarRealType>(pxlValue.real()), static_cast<ScalarRealType>(pxlValue.imag()) ); - - memcpy((void*) (&(p[itPxl*sizeof(RealType)])), (const void*) (&(pxlValueReal)), (size_t) (sizeof(RealType))); - } - } - //std::cout << "CONVERTED BUFFER:" <<std::endl; - //printDataBuffer(p, GDT_CFloat64, m_NbBands, lNbColumns*lNbLines); - delete[] pBufferTemp; - } - // In the indexed case, one has to retrieve the index image and the // color table, and translate p to a 4 components color values buffer - else*/ if (m_IsIndexed) + if (m_IsIndexed) { // TODO: This is a very special case and seems to be working only // for unsigned char pixels. There might be a gdal method to do @@ -346,8 +194,9 @@ void GDALImageIO::Read(void* buffer) std::streamoff step = static_cast<std::streamoff>(this->GetNumberOfComponents()) * static_cast<std::streamoff>(m_BytePerPixel); - - CPLErr lCrGdal = dataset->GetRasterBand(1)->RasterIO(GF_Read, + otbLogMacro(Debug,<<"GDAL reads ["<<lFirstColumn<<", "<<lFirstColumn+lNbColumns-1<<"]x["<<lFirstLine<<", "<<lFirstLine+lNbLines-1<<"] indexed color image of type "<<GDALGetDataTypeName(m_PxType->pixType)<<" from file "<<m_FileName); + otb::Stopwatch chrono = otb::Stopwatch::StartNew(); + CPLErr lCrGdal = dataset->GetRasterBand(1)->RasterIO(GF_Read, lFirstColumn, lFirstLine, lNbColumns, @@ -358,11 +207,16 @@ void GDALImageIO::Read(void* buffer) m_PxType->pixType, 0, 0); - if (lCrGdal == CE_Failure) + chrono.Stop(); + + if (lCrGdal == CE_Failure) { itkExceptionMacro(<< "Error while reading image (GDAL format) '" << m_FileName.c_str() << "' : " << CPLGetLastErrorMsg()); } + + otbLogMacro(Debug,<< "GDAL read took " << chrono.GetElapsedMilliseconds() << " ms") + // Interpret index as color std::streamoff cpt(0); GDALColorTable* colorTable = dataset->GetRasterBand(1)->GetColorTable(); @@ -394,19 +248,7 @@ void GDALImageIO::Read(void* buffer) } // keep it for the moment - //otbMsgDevMacro(<< "Number of bands inside input file: " << m_NbBands); - otbMsgDevMacro(<< "Parameters RasterIO : \n" - << " indX = " << lFirstColumn << "\n" - << " indY = " << lFirstLine << "\n" - << " sizeX = " << lNbColumns << "\n" - << " sizeY = " << lNbLines << "\n" - << " Buffer Size X = " << lNbColumnsRegion << "\n" - << " Buffer Size Y = " << lNbLinesRegion << "\n" - << " GDAL Data Type = " << GDALGetDataTypeName(m_PxType->pixType) << "\n" - << " nbBands = " << nbBands << "\n" - << " pixelOffset = " << pixelOffset << "\n" - << " lineOffset = " << lineOffset << "\n" - << " bandOffset = " << bandOffset ); + otbLogMacro(Debug,<<"GDAL reads ["<<lFirstColumn<<", "<<lFirstColumnRegion+lNbColumnsRegion-1<<"]x["<<lFirstLineRegion<<", "<<lFirstLineRegion+lNbLinesRegion-1<<"] x "<<nbBands<<" bands of type "<<GDALGetDataTypeName(m_PxType->pixType)<<" from file "<<m_FileName); otb::Stopwatch chrono = otb::Stopwatch::StartNew(); CPLErr lCrGdal = m_Dataset->GetDataSet()->RasterIO(GF_Read, @@ -425,8 +267,6 @@ void GDALImageIO::Read(void* buffer) lineOffset, bandOffset); chrono.Stop(); - otbMsgDevMacro(<< "RasterIO Read took " << chrono.GetElapsedMilliseconds() << " ms") - // Check if gdal call succeed if (lCrGdal == CE_Failure) { @@ -434,8 +274,10 @@ void GDALImageIO::Read(void* buffer) << m_FileName.c_str() << "' : " << CPLGetLastErrorMsg()); return; } - //printDataBuffer(p, m_PxType->pixType, m_NbBands, lNbColumnsRegion*lNbLinesRegion); - } + + otbLogMacro(Debug,<< "GDAL read took " << chrono.GetElapsedMilliseconds() << " ms") + + } } bool GDALImageIO::GetSubDatasetInfo(std::vector<std::string> &names, std::vector<std::string> &desc) @@ -456,8 +298,6 @@ bool GDALImageIO::GetSubDatasetInfo(std::vector<std::string> &names, std::vector std::string key, name; if (System::ParseHdfSubsetName(papszMetadata[cpt], key, name)) { - otbMsgDevMacro(<< "- key: " << key); - otbMsgDevMacro(<< "- name: " << name); // check if this is a dataset name if (key.find("_NAME") != std::string::npos) names.push_back(name); // check if this is a dataset descriptor @@ -609,8 +449,6 @@ void GDALImageIO::InternalReadImageInformation() std::string key, name; if (System::ParseHdfSubsetName(papszMetadata[cpt], key, name)) { - otbMsgDevMacro(<< "- key: " << key); - otbMsgDevMacro(<< "- name: " << name); // check if this is a dataset name if (key.find("_NAME") != std::string::npos) names.push_back(name); } @@ -618,7 +456,6 @@ void GDALImageIO::InternalReadImageInformation() } if (m_DatasetNumber < names.size()) { - otbMsgDevMacro(<< "Reading: " << names[m_DatasetNumber]); m_Dataset = GDALDriverManagerWrapper::GetInstance().Open(names[m_DatasetNumber]); } else @@ -643,8 +480,6 @@ void GDALImageIO::InternalReadImageInformation() m_OriginalDimensions.push_back(dataset->GetRasterXSize()); m_OriginalDimensions.push_back(dataset->GetRasterYSize()); - otbMsgDevMacro(<< "Original Dimensions of the input file: " << m_OriginalDimensions[0] << " x " << m_OriginalDimensions[1]); - // Get Number of Bands m_NbBands = dataset->GetRasterCount(); @@ -661,21 +496,13 @@ void GDALImageIO::InternalReadImageInformation() /*std::cout << "Overviews size of input file" << m_FileName << ": " << m_OverviewsSize.back().first << " x " << m_OverviewsSize.back().second << std::endl; */ - otbMsgDevMacro( << "Overviews size of input file" << m_FileName << ": " - << m_OverviewsSize.back().first << " x " << m_OverviewsSize.back().second); } - otbMsgDevMacro(<< "Number of Overviews inside input file: " << m_NumberOfOverviews); - otbMsgDevMacro(<< "Input file dimension: " << m_Dimensions[0] << ", " << m_Dimensions[1]); - otbMsgDevMacro(<< "Number of bands inside input file: " << m_NbBands); - this->SetNumberOfComponents(m_NbBands); // Set the number of dimensions (verify for the dim ) this->SetNumberOfDimensions(2); - otbMsgDevMacro(<< "Nb of Dimensions of the input file: " << m_NumberOfDimensions); - // Automatically set the Type to Binary for GDAL data this->SetFileTypeToBinary(); @@ -683,7 +510,7 @@ void GDALImageIO::InternalReadImageInformation() // Consider only the data type given by the first band // Maybe be could changed (to check) m_PxType->pixType = dataset->GetRasterBand(1)->GetRasterDataType(); - otbMsgDevMacro(<< "PixelType inside input file: "<< GDALGetDataTypeName(m_PxType->pixType) ); + if (m_PxType->pixType == GDT_Byte) { SetComponentType(UCHAR); @@ -809,7 +636,7 @@ void GDALImageIO::InternalReadImageInformation() // we are reading a complex data set into an image where the pixel // type is Vector<real>: we have to double the number of component // for that to work - otbMsgDevMacro( << "GDALtypeIO= Complex and IFReader::InternalPixelType= Scalar and IFReader::PixelType= Vector"); + otbLogMacro(Warning,<<"Encoding of file ("<<m_FileName<<") is complex but will be read as a VectorImage of scalar type, with twice the number of bands."); this->SetNumberOfComponents(m_NbBands*2); this->SetPixelType(VECTOR); } @@ -831,12 +658,6 @@ void GDALImageIO::InternalReadImageInformation() } } - /*** Parameters set by Internal Read function ***/ - otbMsgDevMacro( << "Pixel Type IFReader = " << GetPixelTypeAsString(this->GetPixelType()) ) - otbMsgDevMacro( << "Number of component IFReader = " << this->GetNumberOfComponents() ) - otbMsgDevMacro( << "Byte per pixel set = " << m_BytePerPixel ) - otbMsgDevMacro( << "Component Type set = " << GetComponentTypeAsString(this->GetComponentType()) ); - /*----------------------------------------------------------------------*/ /*-------------------------- METADATA ----------------------------------*/ /*----------------------------------------------------------------------*/ @@ -854,8 +675,6 @@ void GDALImageIO::InternalReadImageInformation() if(blockSizeX > 0 && blockSizeY > 0) { - otbMsgDevMacro(<< "Original blockSize: "<< blockSizeX << " x " << blockSizeY ); - blockSizeX = uint_ceildivpow2(blockSizeX,m_ResolutionFactor); if (m_Dataset->IsJPEG2000()) { @@ -868,8 +687,6 @@ void GDALImageIO::InternalReadImageInformation() blockSizeY = blockSizeY * (1 << m_ResolutionFactor); } - otbMsgDevMacro(<< "Decimated blockSize: "<< blockSizeX << " x " << blockSizeY ); - itk::EncapsulateMetaData<unsigned int>(dict, MetaDataKey::TileHintX, blockSizeX); itk::EncapsulateMetaData<unsigned int>(dict, MetaDataKey::TileHintY, blockSizeY); } @@ -948,7 +765,6 @@ void GDALImageIO::InternalReadImageInformation() } else { - otbMsgDevMacro( << "No projection => sensor model" ); // Special case for Jpeg2000 files : try to read the origin in the GML box if (m_Dataset->IsJPEG2000()) { @@ -1044,7 +860,7 @@ void GDALImageIO::InternalReadImageInformation() } else { - otbWarningMacro(<< "Incorrect geotransform (spacing = 0)!"); + otbLogMacro(Warning,<< "Geotransform reported by GDAL is invalid (spacing = 0)"); m_Spacing[0] = 1; m_Spacing[1] = 1; } @@ -1065,23 +881,6 @@ void GDALImageIO::InternalReadImageInformation() m_Origin[0] += 0.5*m_Spacing[0]; m_Origin[1] += 0.5*m_Spacing[1]; - // Dataset info - otbMsgDevMacro(<< "**** ReadImageInformation() DATASET INFO: ****" ); - otbMsgDevMacro(<< "Projection Ref: "<< dataset->GetProjectionRef() ); - double GT[6]; - if (dataset->GetGeoTransform(GT) == CE_None) - { - otbMsgDevMacro( <<"Geo Transform: "<< GT[0] << ", " << GT[1] << ", " - << GT[2] << ", " << GT[3] << ", " - << GT[4] << ", " << GT[5] ); - } - else - { - otbMsgDevMacro( << "No Geo Transform: "); - } - otbMsgDevMacro(<< "GCP Projection Ref: "<< dataset->GetGCPProjection() ); - otbMsgDevMacro(<< "GCP Count: " << dataset->GetGCPCount() ); - /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ @@ -1289,7 +1088,6 @@ bool GDALImageIO::CanWriteFile(const char* name) // First check the filename if (name == ITK_NULLPTR) { - itkDebugMacro(<< "No filename specified."); return false; } @@ -1307,7 +1105,7 @@ bool GDALImageIO::CanWriteFile(const char* name) if ( GDALGetMetadataItem( driver, GDAL_DCAP_CREATE, ITK_NULLPTR ) == ITK_NULLPTR && GDALGetMetadataItem( driver, GDAL_DCAP_CREATECOPY, ITK_NULLPTR ) == ITK_NULLPTR ) { - itkDebugMacro(<< "The driver " << GDALGetDriverShortName(driver) << " does not support writing"); + otbLogMacro(Warning,<< "GDAL driver " << GDALGetDriverShortName(driver) << " does not support writing"); return false; } return true; @@ -1321,7 +1119,6 @@ bool GDALImageIO::CanStreamWrite() if (driver == ITK_NULLPTR) { - itkDebugMacro(<< "Unable to instantiate driver " << gdalDriverShortName); m_CanStreamWrite = false; } if ( GDALGetMetadataItem( driver, GDAL_DCAP_CREATE, ITK_NULLPTR ) != ITK_NULLPTR ) @@ -1347,7 +1144,7 @@ void GDALImageIO::Write(const void* buffer) // Check if conversion succeed if (buffer == ITK_NULLPTR) { - itkExceptionMacro(<< "GDAL : Bad alloc"); + itkExceptionMacro(<< "Null buffer passed to GDALImageIO for writing."); return; } @@ -1373,18 +1170,7 @@ void GDALImageIO::Write(const void* buffer) // If driver supports streaming if (m_CanStreamWrite) { - - otbMsgDevMacro(<< "RasterIO Write requested region : " << this->GetIORegion() << - "\n, lFirstColumn =" << lFirstColumn << - "\n, lFirstLine =" << lFirstLine << - "\n, lNbColumns =" << lNbColumns << - "\n, lNbLines =" << lNbLines << - "\n, m_PxType =" << GDALGetDataTypeName(m_PxType->pixType) << - "\n, m_NbBands =" << m_NbBands << - "\n, m_BytePerPixel ="<< m_BytePerPixel << - "\n, Pixel offset =" << m_BytePerPixel * m_NbBands << // is nbComp * BytePerPixel - "\n, Line offset =" << m_BytePerPixel * m_NbBands * lNbColumns << // is pixelOffset * nbColumns - "\n, Band offset =" << m_BytePerPixel) // is BytePerPixel + otbLogMacro(Debug,<<"GDAL writes ["<<lFirstColumn<<", "<<lFirstColumn+lNbColumns-1<<"]x["<<lFirstLine<<", "<<lFirstLine+lNbLines-1<<"] x "<<m_NbBands<<" bands of type "<<GDALGetDataTypeName(m_PxType->pixType)<<" to file "<<m_FileName); otb::Stopwatch chrono = otb::Stopwatch::StartNew(); CPLErr lCrGdal = m_Dataset->GetDataSet()->RasterIO(GF_Write, @@ -1408,7 +1194,6 @@ void GDALImageIO::Write(const void* buffer) // Band offset is BytePerPixel m_BytePerPixel); chrono.Stop(); - otbMsgDevMacro(<< "RasterIO Write took " << chrono.GetElapsedMilliseconds() << " ms") // Check if writing succeed if (lCrGdal == CE_Failure) @@ -1416,6 +1201,9 @@ void GDALImageIO::Write(const void* buffer) itkExceptionMacro(<< "Error while writing image (GDAL format) '" << m_FileName.c_str() << "' : " << CPLGetLastErrorMsg()); } + + otbLogMacro(Debug,<< "GDAL write took " << chrono.GetElapsedMilliseconds() << " ms") + // Flush dataset cache m_Dataset->GetDataSet()->FlushCache(); } @@ -1582,55 +1370,6 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) if (m_CanStreamWrite) { GDALCreationOptionsType creationOptions = m_CreationOptions; -/* - // Force tile mode for TIFF format if no creation option are given - if( driverShortName == "GTiff" ) - { - if ( CreationOptionContains( "TILED=YES" ) ) - { - // User requested tiled TIFF explicitly - // - // Let GDAL set up the BLOCKXSIZE and BLOCKYSIZE - // or suppose the user have set it also along with TILED=YES - // This allows the user to have complete - // control over the tiling scheme - } - else if ( CreationOptionContains( "BLOCKYSIZE=" ) ) - { - // User did not set "TILED=YES" but set "BLOCKYSIZE=" - // -> He requested a stripped TIFF - } - else - { - // User did not specify "TILED=YES" nor "BLOCKYSIZE=?" - // Switch to TILED mode automatically, and choose BLOCKXSIZE and BLOCKYSIZE for him - - otbMsgDevMacro(<< "Enabling TIFF Tiled mode") - - // Use a fixed tile size - // Take as reference is a 256*256 short int 4 bands tile - const unsigned int ReferenceTileSizeInBytes = 256 * 256 * 4 * 2; - const unsigned int NbPixelPerTile = ReferenceTileSizeInBytes / m_BytePerPixel / m_NbBands; - const unsigned int IdealTileDimension = static_cast<unsigned int>( vcl_sqrt(static_cast<float>(NbPixelPerTile)) ); - - // Set tileDimension to the nearest power of two and aligned to - // 16 pixels (needed by TIFF spec) - unsigned int tileDimension = 16; - while(2*tileDimension < IdealTileDimension) - { - tileDimension*=2; - } - otbMsgDevMacro(<< "Tile dimension : " << tileDimension << " * " << tileDimension) - - std::ostringstream tileDimensionStr; - tileDimensionStr << tileDimension; - - creationOptions.push_back( "TILED=YES" ); - creationOptions.push_back( std::string("BLOCKXSIZE=") + tileDimensionStr.str() ); - creationOptions.push_back( std::string("BLOCKYSIZE=") + tileDimensionStr.str() ); - } - } -*/ m_Dataset = GDALDriverManagerWrapper::GetInstance().Create( driverShortName, GetGdalWriteImageFileName(driverShortName, m_FileName), @@ -1691,7 +1430,7 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) // If there is no ProjectionRef, and the GeoTransform is not the identity, // then saving also GCPs is undefined behavior for GDAL, and a WGS84 projection crs // is assigned arbitrarily - otbMsgDevMacro(<< "Skipping GCPs saving to prevent GDAL from assigning a WGS84 projection ref to the file") + otbLogMacro(Warning,<< "Skipping GCPs saving to prevent GDAL from assigning a WGS84 projref to file ("<<m_FileName<<")") } else { @@ -1802,7 +1541,6 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) unsigned int equalityPos = svalue.find_first_of('='); std::string tag = svalue.substr(0, equalityPos); std::string value = svalue.substr(equalityPos + 1); - otbMsgDevMacro(<< "Metadata: " << tag << "=" << value); dataset->SetMetadataItem(tag.c_str(), value.c_str(), ITK_NULLPTR); } } @@ -1810,24 +1548,6 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) // END - // Dataset info - otbMsgDevMacro( << "**** WriteImageInformation() DATASET INFO: ****" ); - otbMsgDevMacro( << "Projection Ref: "<<dataset->GetProjectionRef() ); - double GT[6]; - if (dataset->GetGeoTransform(GT) == CE_None) - { - otbMsgDevMacro( <<"Geo Transform: "<< GT[0] << ", " << GT[1] << ", " - << GT[2] << ", " << GT[3] << ", " - << GT[4] << ", " << GT[5] ); - } - else - { - otbMsgDevMacro( << "No Geo Transform: "); - } - - otbMsgDevMacro( << "GCP Projection Ref: "<< dataset->GetGCPProjection() ); - otbMsgDevMacro( << "GCP Count: " << dataset->GetGCPCount() ); - // Write no-data flags std::vector<bool> noDataValueAvailable; bool ret = itk::ExposeMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable); @@ -1926,7 +1646,6 @@ bool GDALImageIO::GetOriginFromGMLBox(std::vector<double> &origin) std::string gmlString = static_cast<std::string>(jp2Metadata.papszGMLMetadata[0]); gmlString.erase(0,18); // We need to remove first part to create a true xml stream - otbMsgDevMacro( << "XML extract from GML box: " << gmlString ); TiXmlDocument doc; doc.Parse(gmlString.c_str()); // Create xml doc from a string @@ -1942,13 +1661,8 @@ bool GDALImageIO::GetOriginFromGMLBox(std::vector<double> &origin) .FirstChild( "gml:limits" ) .FirstChild( "gml:GridEnvelope" ) .FirstChild( "gml:low").ToElement(); - if(originTag) + if(!originTag) { - otbMsgDevMacro( << "\t Origin (" << originTag->Value() <<" tag)= "<< originTag->GetText()); - } - else - { - otbMsgDevMacro( << "Didn't find the GML element which indicate the origin!" ); return false; } @@ -1963,8 +1677,6 @@ bool GDALImageIO::GetOriginFromGMLBox(std::vector<double> &origin) origin[0] += -1.0; origin[1] += -1.0; - otbMsgDevMacro( << "\t Origin from GML box: " << origin[0] << ", " << origin[1] ); - return true; } diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx index 87cc50b6e38b3de373d20c163872d5898b885666..c8d4fb2d0f13c9a9add354d34fbff848b2397100 100644 --- a/Modules/IO/ImageIO/include/otbImageFileReader.txx +++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx @@ -107,7 +107,6 @@ void ImageFileReader<TOutputImage, ConvertPixelTraits> ::SetImageIO( otb::ImageIOBase * imageIO) { - itkDebugMacro("setting ImageIO to " << imageIO ); if (this->m_ImageIO != imageIO ) { this->m_ImageIO = imageIO; @@ -207,12 +206,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> char * loadBuffer = new char[nbBytes]; - otbMsgDevMacro(<< "buffer size for ImageIO::read = " << nbBytes << " = \n" - << "ComponentSize ("<< this->m_ImageIO->GetComponentSize() << ") x " \ - << "Nb of Component ( max(" << this->m_ImageIO->GetNumberOfComponents() \ - << " , "<<m_BandList.size() << ") ) x " \ - << "Nb of Pixel to read (" << region.GetNumberOfPixels() << ")"); - this->m_ImageIO->Read(loadBuffer); if (m_FilenameHelper->BandRangeIsSet()) @@ -410,13 +403,13 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> if (m_FilenameHelper->ExtGEOMFileNameIsSet()) { otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName()); - otbMsgDevMacro(<< "Loading external kwl: "<< m_FilenameHelper->GetExtGEOMFileName()); + otbLogMacro(Info,<< "Loading kwl metadata from external geom file "<< m_FilenameHelper->GetExtGEOMFileName()); } // Case 2: attached geom (if present) else if (itksys::SystemTools::FileExists(attachedGeom)) { otb_kwl = ReadGeometryFromGEOMFile(attachedGeom); - otbMsgDevMacro(<< "Loading attached kwl"); + otbLogMacro(Info,<< "Loading kwl metadata from attached geom file "<<attachedGeom); } // Case 3: find an ossimPluginProjection // Case 4: find an ossimProjection @@ -424,7 +417,14 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> else { otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist,!m_FilenameHelper->GetSkipRpcTag()); - otbMsgDevMacro(<< "Loading internal kwl"); + if(!otb_kwl.Empty()) + { + otbLogMacro(Info,<< "Loading kwl metadata from official product in file "<<lFileNameOssimKeywordlist); + } + else + { + otbLogMacro(Info,<< "No kwl metadata found in file "<<lFileNameOssimKeywordlist); + } } // Don't add an empty ossim keyword list @@ -644,8 +644,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> fic_trouve = true; } - otbMsgDevMacro(<< "lFileNameGdal : " << GdalFileName.c_str()); - otbMsgDevMacro(<< "fic_trouve : " << fic_trouve); return (fic_trouve); } diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.txx b/Modules/IO/ImageIO/include/otbImageFileWriter.txx index b1472291f1ae216f302757ad00b69bfd161b3630..907da0d9bd562a6954e2978a34a38830f671de09 100644 --- a/Modules/IO/ImageIO/include/otbImageFileWriter.txx +++ b/Modules/IO/ImageIO/include/otbImageFileWriter.txx @@ -99,7 +99,6 @@ ImageFileWriter<TInputImage> typedef NumberOfDivisionsStrippedStreamingManager<TInputImage> NumberOfDivisionsStrippedStreamingManagerType; typename NumberOfDivisionsStrippedStreamingManagerType::Pointer streamingManager = NumberOfDivisionsStrippedStreamingManagerType::New(); streamingManager->SetNumberOfDivisions(nbDivisions); - m_StreamingManager = streamingManager; } @@ -111,7 +110,6 @@ ImageFileWriter<TInputImage> typedef NumberOfDivisionsTiledStreamingManager<TInputImage> NumberOfDivisionsTiledStreamingManagerType; typename NumberOfDivisionsTiledStreamingManagerType::Pointer streamingManager = NumberOfDivisionsTiledStreamingManagerType::New(); streamingManager->SetNumberOfDivisions(nbDivisions); - m_StreamingManager = streamingManager; } @@ -123,7 +121,6 @@ ImageFileWriter<TInputImage> typedef NumberOfLinesStrippedStreamingManager<TInputImage> NumberOfLinesStrippedStreamingManagerType; typename NumberOfLinesStrippedStreamingManagerType::Pointer streamingManager = NumberOfLinesStrippedStreamingManagerType::New(); streamingManager->SetNumberOfLinesPerStrip(nbLinesPerStrip); - m_StreamingManager = streamingManager; } @@ -136,7 +133,6 @@ ImageFileWriter<TInputImage> typename RAMDrivenStrippedStreamingManagerType::Pointer streamingManager = RAMDrivenStrippedStreamingManagerType::New(); streamingManager->SetAvailableRAMInMB(availableRAM); streamingManager->SetBias(bias); - m_StreamingManager = streamingManager; } @@ -147,8 +143,7 @@ ImageFileWriter<TInputImage> { typedef TileDimensionTiledStreamingManager<TInputImage> TileDimensionTiledStreamingManagerType; typename TileDimensionTiledStreamingManagerType::Pointer streamingManager = TileDimensionTiledStreamingManagerType::New(); - streamingManager->SetTileDimension(tileDimension); - + streamingManager->SetTileDimension(tileDimension); m_StreamingManager = streamingManager; } @@ -238,7 +233,6 @@ void ImageFileWriter<TInputImage> ::SetIORegion(const itk::ImageIORegion& region) { - itkDebugMacro("setting IORegion to " << region); if (m_IORegion != region) { m_IORegion = region; @@ -289,7 +283,7 @@ ImageFileWriter<TInputImage> /** Parse streaming modes */ if(m_FilenameHelper->StreamingTypeIsSet()) { - itkWarningMacro(<<"Streaming configuration through extended filename is used. Any previous streaming configuration (ram value, streaming mode ...) will be ignored."); + otbLogMacro(Warning,<<"Streaming configuration through extended filename is used. Any previous streaming configuration (ram value, streaming mode ...) will be ignored."); std::string type = m_FilenameHelper->GetStreamingType(); @@ -311,11 +305,11 @@ ImageFileWriter<TInputImage> { if(sizemode != "auto") { - itkWarningMacro(<<"In auto streaming type, the sizemode option will be ignored."); + otbLogMacro(Warning,<<"In auto streaming type, the sizemode option will be ignored."); } if(sizevalue == 0.) { - itkWarningMacro("sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use the default value"); + otbLogMacro(Warning,<<"sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use the default value"); } this->SetAutomaticAdaptativeStreaming(sizevalue); } @@ -325,7 +319,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use the default value"); + otbLogMacro(Warning,<<"sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use the default value"); } this->SetAutomaticTiledStreaming(sizevalue); } @@ -333,7 +327,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); + otbLogMacro(Warning,<<"Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); } this->SetNumberOfDivisionsTiledStreaming(static_cast<unsigned int>(sizevalue)); } @@ -341,7 +335,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("Streaming sizemode is set to height but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); + otbLogMacro(Warning,<<"Streaming sizemode is set to height but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); } this->SetTileDimensionTiledStreaming(static_cast<unsigned int>(sizevalue)); @@ -353,7 +347,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("sizemode is auto but sizevalue is 0. Value will be fetched from configuration file if any, or from cmake configuration otherwise."); + otbLogMacro(Warning,<<"sizemode is auto but sizevalue is 0. Value will be fetched from configuration file if any, or from cmake configuration otherwise."); } this->SetAutomaticStrippedStreaming(sizevalue); @@ -362,7 +356,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); + otbLogMacro(Warning,<<"Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); } this->SetNumberOfDivisionsStrippedStreaming(static_cast<unsigned int>(sizevalue)); } @@ -370,7 +364,7 @@ ImageFileWriter<TInputImage> { if(sizevalue == 0.) { - itkWarningMacro("Streaming sizemode is set to height but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); + otbLogMacro(Warning,<<"Streaming sizemode is set to height but sizevalue is 0. This will result in upredicted behaviour. Please consider setting the sizevalue by using &streaming:sizevalue=x."); } this->SetNumberOfLinesStrippedStreaming(static_cast<unsigned int>(sizevalue)); } @@ -380,7 +374,7 @@ ImageFileWriter<TInputImage> { if(sizemode!="" || sizevalue!=0.) { - itkWarningMacro("Streaming is explicitly disabled, sizemode and sizevalue will be ignored."); + otbLogMacro(Warning,<<"Streaming is explicitly disabled, sizemode and sizevalue will be ignored."); } this->SetNumberOfDivisionsTiledStreaming(0); } @@ -389,7 +383,7 @@ ImageFileWriter<TInputImage> { if(m_FilenameHelper->StreamingSizeValueIsSet() || m_FilenameHelper->StreamingSizeModeIsSet()) { - itkWarningMacro(<<"No streaming type is set, streaming sizemode and sizevalue will be ignored."); + otbLogMacro(Warning,<<"No streaming type is set, streaming sizemode and sizevalue will be ignored."); } } @@ -418,8 +412,6 @@ ImageFileWriter<TInputImage> if (m_ImageIO.IsNull()) //try creating via factory { - itkDebugMacro(<< "Attempting factory creation of ImageIO for file: " - << m_FileName); this->SetImageIO(ImageIOFactory::CreateImageIO(m_FileName.c_str(), otb::ImageIOFactory::WriteMode)); @@ -429,13 +421,8 @@ ImageFileWriter<TInputImage> { if (!m_ImageIO->CanWriteFile(m_FileName.c_str())) { - itkDebugMacro(<< "ImageIO exists but doesn't know how to write file:" - << m_FileName); - if (m_FactorySpecifiedImageIO) { - itkDebugMacro(<< "Attempting creation of ImageIO with a factory for file:" - << m_FileName); m_ImageIO = ImageIOFactory::CreateImageIO(m_FileName.c_str(), otb::ImageIOFactory::WriteMode); m_FactorySpecifiedImageIO = true; @@ -514,7 +501,7 @@ ImageFileWriter<TInputImage> e.SetDataObject(inputPtr); throw e; } - otbMsgDevMacro(<< "inputRegion " << inputRegion); + otbLogMacro(Info,<<"Writing user defined region ["<<start[0]<<", "<<start[0]+size[0]-1<<"]x["<<start[1]<<", "<<start[1]+size[1]<<"]"); } /** @@ -526,9 +513,8 @@ ImageFileWriter<TInputImage> /** Control if the ImageIO is CanStreamWrite */ if (m_ImageIO->CanStreamWrite() == false) { - otbWarningMacro( - << "The ImageFactory selected for the image file <" << m_FileName.c_str() << - "> does not support streaming."); + otbLogMacro(Warning,<<"The file format of " << m_FileName << + " does not support streaming. All data will be loaded to memory"); this->SetNumberOfDivisionsStrippedStreaming(1); } @@ -537,12 +523,14 @@ ImageFileWriter<TInputImage> * Not sure that if this modification is needed */ else if (inputPtr->GetBufferedRegion() == inputRegion) { - otbMsgDevMacro(<< "Buffered region is the largest possible region, there is no need for streaming."); + otbLogMacro(Debug,<< "Buffered region is the largest possible region, there is no need for streaming."); this->SetNumberOfDivisionsStrippedStreaming(1); } m_StreamingManager->PrepareStreaming(inputPtr, inputRegion); m_NumberOfDivisions = m_StreamingManager->GetNumberOfSplits(); - otbMsgDebugMacro(<< "Number Of Stream Divisions : " << m_NumberOfDivisions); + + const auto firstSplitSize = m_StreamingManager->GetSplit(0).GetSize(); + otbLogMacro(Info,<<"File "<<m_FileName<<" will be written in "<<m_NumberOfDivisions<<" blocks of "<<firstSplitSize[0]<<"x"<<firstSplitSize[1]<<" pixels"); /** * Loop over the number of pieces, execute the upstream pipeline on each @@ -612,7 +600,7 @@ ImageFileWriter<TInputImage> } else { - itkWarningMacro(<< "Could not get the source process object. Progress report might be buggy"); + otbLogMacro(Warning,<< "Could not get the source process object. Progress report might be buggy"); } for (m_CurrentDivision = 0; @@ -746,9 +734,6 @@ ImageFileWriter<TInputImage> { if ( m_NumberOfDivisions > 1 || m_UserSpecifiedIORegion) { - itkDebugMacro("Requested stream region does not match generated output"); - itkDebugMacro("input filter may not support streaming well"); - cacheImage = InputImageType::New(); cacheImage->CopyInformation(input); diff --git a/Modules/IO/TestKernel/include/otbReadDataFile.h b/Modules/IO/TestKernel/include/otbReadDataFile.h new file mode 100644 index 0000000000000000000000000000000000000000..0e7174be6ec50038bb217f4248cbd5be604d6566 --- /dev/null +++ b/Modules/IO/TestKernel/include/otbReadDataFile.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbStringUtils.h" +#include "otb_boost_string_header.h" + +#include "itkListSample.h" +#include <fstream> +#include <string> +#include <algorithm> + +namespace otb +{ +/** Utility function to read the data file letter.scale, a CSV type file + * (whitespace separators) with the letter index in first column, followed by + * 16 descriptors. Each descriptor is a pair 'index:value' + */ +template <typename TInput, typename TTarget> +bool ReadDataFile( + const std::string & infname, + itk::SmartPointer<itk::Statistics::ListSample<TInput> > samples, + itk::SmartPointer<itk::Statistics::ListSample<TTarget> > labels) +{ + typedef typename itk::Statistics::ListSample<TInput>::MeasurementType IValueType; + typedef typename itk::Statistics::ListSample<TTarget>::MeasurementType TValueType; + + std::ifstream ifs; + ifs.open(infname.c_str()); + + if(!ifs) + { + std::cout<<"Could not read file "<<infname<<std::endl; + return false; + } + + labels->SetMeasurementVectorSize(1); + unsigned int nbfeatures = 0; + + while (!ifs.eof()) + { + std::string line; + std::getline(ifs, line); + boost::algorithm::trim(line); + + if(nbfeatures == 0) + { + nbfeatures = std::count(line.begin(),line.end(),' '); + samples->SetMeasurementVectorSize(nbfeatures); + } + + if(line.size()>1) + { + TInput sample; + itk::NumericTraits<TInput>::SetLength(sample, nbfeatures); + + std::string::size_type pos = line.find_first_of(" ", 0); + + // Parse label + TTarget label; + itk::NumericTraits<TTarget>::SetLength(label,1); + label[0] = boost::lexical_cast<TValueType>(line.substr(0, pos)); + + bool endOfLine = false; + unsigned int id = 0; + + while(!endOfLine) + { + std::string::size_type nextpos = line.find_first_of(" ", pos+1); + if(nextpos == std::string::npos) + { + endOfLine = true; + nextpos = line.size(); + } + + std::string::size_type semicolonpos = line.find_first_of(":", pos+1, nextpos-pos-1); + if (semicolonpos == std::string::npos) + { + id++; + sample[id - 1] = boost::lexical_cast<IValueType>(line.substr(pos+1,nextpos-pos-1)); + } + else + { + id = boost::lexical_cast<unsigned int>(line.substr(pos+1,semicolonpos-pos-1)); + sample[id - 1] = boost::lexical_cast<IValueType>( + line.substr(semicolonpos+1,nextpos-semicolonpos-1)); + } + pos = nextpos; + + } + samples->PushBack(sample); + labels->PushBack(label); + } + } + + ifs.close(); + return true; +} + +} // end of namespace otb diff --git a/Modules/Learning/DimensionalityReductionLearning/CMakeLists.txt b/Modules/Learning/DimensionalityReductionLearning/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..79b6f276d592e5f9f1c41c03ff95589982b8cb76 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) +# +# This file is part of Orfeo Toolbox +# +# https://www.orfeo-toolbox.org/ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +project(OTBDimensionalityReduction) + +otb_module_impl() diff --git a/Modules/Learning/DimensionalityReductionLearning/README.md b/Modules/Learning/DimensionalityReductionLearning/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a46b8fbf8af741f44690a747f973b08a5114e2d0 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/README.md @@ -0,0 +1,25 @@ +This module contains a new dimensionality reduction framework for the Orfeo Toolbox. + +The framework is based on Machine learning models and a dimensionality reduction algorithm +can be trained and used using the model class, in the same fashion as Machine Learning Models +for Classification (supervised or unspervised) and Regression. + +The algorithms featured in the module are (27/06/2017) : + - autoencoders and multi layer autoencoders, with several regularization options + - PCA + - SOM + + Autoencoders and PCA models are using Shark ML library, while SOM model is based on the SOM classes of the OTB. + + More specifically, the module contains : + + - Autoencoder models, PCA models and SOM models, with methods for training, serialization and prediction (i.e. reduction) + - A Dimensionality Reduction Model Factory and a factories for each model, which allow the user to create objects of the model classes + - A (OTB ImageToImage) filter that can be used to perform dimensionality reduction on an image. This filter supports threading and streaming + - An application for training the models according to a shapefile + - An application for using a trained model on a shapefile + - An application for using a trained model on an image (using the filter) + + /!\ Work In Progress /!\ + + diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.h b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.h new file mode 100644 index 0000000000000000000000000000000000000000..14205f0cd81aa2053d22b7bf90bfc78b5bebfe39 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbAutoencoderModel_h +#define otbAutoencoderModel_h + +#include "otbMachineLearningModelTraits.h" +#include "otbMachineLearningModel.h" +#include <fstream> + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#pragma GCC diagnostic ignored "-Wsign-compare" +#endif +#include "otb_shark.h" +#include <shark/Algorithms/StoppingCriteria/AbstractStoppingCriterion.h> +#include <shark/Models/FFNet.h> +#include <shark/Models/Autoencoder.h> +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +namespace otb +{ +/** + * \class AutoencoderModel + * + * Autoencoder model wrapper class + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, class NeuronType> +class ITK_EXPORT AutoencoderModel + : public MachineLearningModel< + itk::VariableLengthVector< TInputValue>, + itk::VariableLengthVector< TInputValue> > +{ +public: + typedef AutoencoderModel Self; + typedef MachineLearningModel< + itk::VariableLengthVector< TInputValue>, + itk::VariableLengthVector< TInputValue> > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::InputValueType InputValueType; + typedef typename Superclass::InputSampleType InputSampleType; + typedef typename Superclass::InputListSampleType InputListSampleType; + typedef typename InputListSampleType::Pointer ListSamplePointerType; + typedef typename Superclass::TargetValueType TargetValueType; + typedef typename Superclass::TargetSampleType TargetSampleType; + typedef typename Superclass::TargetListSampleType TargetListSampleType; + + /// Confidence map related typedefs + typedef typename Superclass::ConfidenceValueType ConfidenceValueType; + typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType; + typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType; + + /// Neural network related typedefs + typedef shark::Autoencoder<NeuronType,shark::LinearNeuron> OutAutoencoderType; + typedef shark::Autoencoder<NeuronType,NeuronType> AutoencoderType; + typedef shark::FFNet<NeuronType,shark::LinearNeuron> NetworkType; + + itkNewMacro(Self); + itkTypeMacro(AutoencoderModel, DimensionalityReductionModel); + + itkGetMacro(NumberOfHiddenNeurons,itk::Array<unsigned int>); + itkSetMacro(NumberOfHiddenNeurons,itk::Array<unsigned int>); + + itkGetMacro(NumberOfIterations,unsigned int); + itkSetMacro(NumberOfIterations,unsigned int); + + itkGetMacro(NumberOfIterationsFineTuning,unsigned int); + itkSetMacro(NumberOfIterationsFineTuning,unsigned int); + + itkGetMacro(Epsilon,double); + itkSetMacro(Epsilon,double); + + itkGetMacro(InitFactor,double); + itkSetMacro(InitFactor,double); + + itkGetMacro(Regularization,itk::Array<double>); + itkSetMacro(Regularization,itk::Array<double>); + + itkGetMacro(Noise,itk::Array<double>); + itkSetMacro(Noise,itk::Array<double>); + + itkGetMacro(Rho,itk::Array<double>); + itkSetMacro(Rho,itk::Array<double>); + + itkGetMacro(Beta,itk::Array<double>); + itkSetMacro(Beta,itk::Array<double>); + + itkGetMacro(WriteLearningCurve,bool); + itkSetMacro(WriteLearningCurve,bool); + + itkSetMacro(WriteWeights, bool); + itkGetMacro(WriteWeights, bool); + + itkGetMacro(LearningCurveFileName,std::string); + itkSetMacro(LearningCurveFileName,std::string); + + bool CanReadFile(const std::string & filename); + bool CanWriteFile(const std::string & filename); + + void Save(const std::string & filename, const std::string & name="") ITK_OVERRIDE; + void Load(const std::string & filename, const std::string & name="") ITK_OVERRIDE; + + void Train() ITK_OVERRIDE; + + template <class T, class Autoencoder> + void TrainOneLayer( + shark::AbstractStoppingCriterion<T> & criterion, + Autoencoder &, + unsigned int, + shark::Data<shark::RealVector> &, + std::ostream&); + + template <class T, class Autoencoder> + void TrainOneSparseLayer( + shark::AbstractStoppingCriterion<T> & criterion, + Autoencoder &, + unsigned int, + shark::Data<shark::RealVector> &, + std::ostream&); + + template <class T> + void TrainNetwork( + shark::AbstractStoppingCriterion<T> & criterion, + shark::Data<shark::RealVector> &, + std::ostream&); + +protected: + AutoencoderModel(); + ~AutoencoderModel() ITK_OVERRIDE; + + virtual TargetSampleType DoPredict( + const InputSampleType& input, + ConfidenceValueType * quality = ITK_NULLPTR) const; + + virtual void DoPredictBatch( + const InputListSampleType *, + const unsigned int & startIndex, + const unsigned int & size, + TargetListSampleType *, + ConfidenceListSampleType * quality = ITK_NULLPTR) const; + +private: + /** Internal Network */ + NetworkType m_Net; + itk::Array<unsigned int> m_NumberOfHiddenNeurons; + /** Training parameters */ + unsigned int m_NumberOfIterations; // stop the training after a fixed number of iterations + unsigned int m_NumberOfIterationsFineTuning; // stop the fine tuning after a fixed number of iterations + double m_Epsilon; // Stops the training when the training error seems to converge + itk::Array<double> m_Regularization; // L2 Regularization parameter + itk::Array<double> m_Noise; // probability for an input to be set to 0 (denosing autoencoder) + itk::Array<double> m_Rho; // Sparsity parameter + itk::Array<double> m_Beta; // Sparsity regularization parameter + double m_InitFactor; // Weight initialization factor (the weights are intialized at m_initfactor/sqrt(inputDimension) ) + + bool m_WriteLearningCurve; // Flag for writting the learning curve into a txt file + std::string m_LearningCurveFileName; // Name of the output learning curve printed after training + bool m_WriteWeights; +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbAutoencoderModel.txx" +#endif + +#endif + diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.txx new file mode 100644 index 0000000000000000000000000000000000000000..33f1c28e247c43f80ac28a1d608b1c15967c6a5e --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModel.txx @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbAutoencoderModel_txx +#define otbAutoencoderModel_txx + +#include "otbAutoencoderModel.h" +#include "otbMacro.h" + +#include <fstream> + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#endif +#include "otbSharkUtils.h" +//include train function +#include <shark/ObjectiveFunctions/ErrorFunction.h> +#include <shark/ObjectiveFunctions/SparseAutoencoderError.h>//the error function performing the regularisation of the hidden neurons + +#include <shark/Algorithms/GradientDescent/Rprop.h>// the RProp optimization algorithm +#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> // squared loss used for regression +#include <shark/ObjectiveFunctions/Regularizer.h> //L2 regulariziation +#include <shark/Models/ImpulseNoiseModel.h> //noise source to corrupt the inputs +#include <shark/Models/ConcatenatedModel.h>//to concatenate the noise with the model + +#include <shark/Algorithms/StoppingCriteria/MaxIterations.h> //A simple stopping criterion that stops after a fixed number of iterations +#include <shark/Algorithms/StoppingCriteria/TrainingProgress.h> //Stops when the algorithm seems to converge, Tracks the progress of the training error over a period of time + +#include <shark/Algorithms/GradientDescent/SteepestDescent.h> +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +namespace otb +{ + +template <class TInputValue, class NeuronType> +AutoencoderModel<TInputValue,NeuronType>::AutoencoderModel() +{ + this->m_IsDoPredictBatchMultiThreaded = true; + this->m_WriteLearningCurve = false; +} + +template <class TInputValue, class NeuronType> +AutoencoderModel<TInputValue,NeuronType>::~AutoencoderModel() +{ +} + +template <class TInputValue, class NeuronType> +void +AutoencoderModel<TInputValue,NeuronType> +::Train() +{ + std::vector<shark::RealVector> features; + Shark::ListSampleToSharkVector(this->GetInputListSample(), features); + shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features ); + shark::Data<shark::RealVector> inputSamples_copy = inputSamples; + + std::ofstream ofs; + if (this->m_WriteLearningCurve == true) + { + ofs.open(m_LearningCurveFileName); + ofs << "learning curve" << std::endl; + } + + // Initialization of the feed forward neural network + std::vector<size_t> layers; + layers.push_back(shark::dataDimension(inputSamples)); + for (unsigned int i = 0 ; i < m_NumberOfHiddenNeurons.Size(); ++i) + { + layers.push_back(m_NumberOfHiddenNeurons[i]); + } + + for (unsigned int i = std::max(0,static_cast<int>(m_NumberOfHiddenNeurons.Size()-1)) ; i > 0; --i) + { + layers.push_back(m_NumberOfHiddenNeurons[i-1]); + } + + layers.push_back(shark::dataDimension(inputSamples)); + m_Net.setStructure(layers); + shark::initRandomNormal(m_Net,0.1); + + // Training of the first Autoencoder (first and last layer of the FF network) + if (m_Epsilon > 0) + { + shark::TrainingProgress<> criterion(5,m_Epsilon); + + OutAutoencoderType net; + // Shark doesn't allow to train a layer using a sparsity term AND a noisy input. + if (m_Noise[0] != 0) + { + TrainOneLayer(criterion, net, 0, inputSamples, ofs); + } + else + { + TrainOneSparseLayer(criterion, net, 0, inputSamples, ofs); + } + criterion.reset(); + } + else + { + shark::MaxIterations<> criterion(m_NumberOfIterations); + + OutAutoencoderType net; + // Shark doesn't allow to train a layer using a sparsity term AND a noisy input. + if (m_Noise[0] != 0) + { + TrainOneLayer(criterion, net, 0, inputSamples, ofs); + otbMsgDevMacro(<< "m_Noise " << m_Noise[0]); + } + else + { + TrainOneSparseLayer(criterion, net, 0, inputSamples, ofs); + } + criterion.reset(); + } + + // Training of the other autoencoders + if (m_Epsilon > 0) + { + shark::TrainingProgress<> criterion(5,m_Epsilon); + + for (unsigned int i = 1 ; i < m_NumberOfHiddenNeurons.Size(); ++i) + { + AutoencoderType net; + // Shark doesn't allow to train a layer using a sparsity term AND a noisy input. + if (m_Noise[i] != 0) + { + TrainOneLayer(criterion, net, i, inputSamples, ofs); + } + else + { + TrainOneSparseLayer(criterion, net, i, inputSamples, ofs); + } + criterion.reset(); + } + } + else + { + shark::MaxIterations<> criterion(m_NumberOfIterations); + + for (unsigned int i = 1 ; i < m_NumberOfHiddenNeurons.Size(); ++i) + { + AutoencoderType net; + // Shark doesn't allow to train a layer using a sparsity term AND a noisy input. + if (m_Noise[i] != 0) + { + TrainOneLayer(criterion, net, i, inputSamples, ofs); + otbMsgDevMacro(<< "m_Noise " << m_Noise[0]); + } + else + { + TrainOneSparseLayer( criterion, net, i, inputSamples, ofs); + } + criterion.reset(); + } + } + if (m_NumberOfIterationsFineTuning > 0) + { + shark::MaxIterations<> criterion(m_NumberOfIterationsFineTuning); + TrainNetwork(criterion, inputSamples_copy, ofs); + } + this->SetDimension(m_NumberOfHiddenNeurons[m_NumberOfHiddenNeurons.Size()-1]); +} + +template <class TInputValue, class NeuronType> +template <class T, class Autoencoder> +void +AutoencoderModel<TInputValue,NeuronType> +::TrainOneLayer( + shark::AbstractStoppingCriterion<T> & criterion, + Autoencoder & net, + unsigned int layer_index, + shark::Data<shark::RealVector> &samples, + std::ostream& File) +{ + otbMsgDevMacro(<< "Noise " << m_Noise[layer_index]); + std::size_t inputs = dataDimension(samples); + net.setStructure(inputs, m_NumberOfHiddenNeurons[layer_index]); + initRandomUniform(net,-m_InitFactor*std::sqrt(1.0/inputs),m_InitFactor*std::sqrt(1.0/inputs)); + + shark::ImpulseNoiseModel noise(inputs,m_Noise[layer_index],1.0); //set an input pixel with probability m_Noise to 0 + shark::ConcatenatedModel<shark::RealVector,shark::RealVector> model = noise>> net; + shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples);//labels identical to inputs + shark::SquaredLoss<shark::RealVector> loss; + shark::ErrorFunction error(trainSet, &model, &loss); + + shark::TwoNormRegularizer regularizer(error.numberOfVariables()); + error.setRegularizer(m_Regularization[layer_index],®ularizer); + + shark::IRpropPlusFull optimizer; + error.init(); + optimizer.init(error); + + otbMsgDevMacro(<<"Error before training : " << optimizer.solution().value); + if (this->m_WriteLearningCurve == true) + { + File << "end layer" << std::endl; + } + + unsigned int i=0; + do + { + i++; + optimizer.step(error); + if (this->m_WriteLearningCurve == true) + { + File << optimizer.solution().value << std::endl; + } + otbMsgDevMacro(<<"Error after " << i << " iterations : " << optimizer.solution().value); + } while( !criterion.stop( optimizer.solution() ) ); + + net.setParameterVector(optimizer.solution().point); + m_Net.setLayer(layer_index,net.encoderMatrix(),net.hiddenBias()); // Copy the encoder in the FF neural network + m_Net.setLayer( m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index,net.decoderMatrix(),net.outputBias()); // Copy the decoder in the FF neural network + samples = net.encode(samples); +} + +template <class TInputValue, class NeuronType> +template <class T, class Autoencoder> +void AutoencoderModel<TInputValue,NeuronType>::TrainOneSparseLayer( + shark::AbstractStoppingCriterion<T> & criterion, + Autoencoder & net, + unsigned int layer_index, + shark::Data<shark::RealVector> &samples, + std::ostream& File) +{ + //AutoencoderType net; + std::size_t inputs = dataDimension(samples); + net.setStructure(inputs, m_NumberOfHiddenNeurons[layer_index]); + + shark::initRandomUniform(net,-m_InitFactor*std::sqrt(1.0/inputs),m_InitFactor*std::sqrt(1.0/inputs)); + + // Idea : set the initials value for the output weights higher than the input weights + + shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples);//labels identical to inputs + shark::SquaredLoss<shark::RealVector> loss; + shark::SparseAutoencoderError error(trainSet,&net, &loss, m_Rho[layer_index], m_Beta[layer_index]); + + shark::TwoNormRegularizer regularizer(error.numberOfVariables()); + error.setRegularizer(m_Regularization[layer_index],®ularizer); + shark::IRpropPlusFull optimizer; + error.init(); + optimizer.init(error); + + otbMsgDevMacro(<<"Error before training : " << optimizer.solution().value); + unsigned int i=0; + do + { + i++; + optimizer.step(error); + otbMsgDevMacro(<<"Error after " << i << " iterations : " << optimizer.solution().value); + if (this->m_WriteLearningCurve == true) + { + File << optimizer.solution().value << std::endl; + } + } while( !criterion.stop( optimizer.solution() ) ); + if (this->m_WriteLearningCurve == true) + { + File << "end layer" << std::endl; + } + net.setParameterVector(optimizer.solution().point); + m_Net.setLayer(layer_index,net.encoderMatrix(),net.hiddenBias()); // Copy the encoder in the FF neural network + m_Net.setLayer( m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index,net.decoderMatrix(),net.outputBias()); // Copy the decoder in the FF neural network + samples = net.encode(samples); +} + +template <class TInputValue, class NeuronType> +template <class T> +void +AutoencoderModel<TInputValue,NeuronType> +::TrainNetwork( + shark::AbstractStoppingCriterion<T> & criterion, + shark::Data<shark::RealVector> &samples, + std::ostream& File) +{ + //labels identical to inputs + shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples); + shark::SquaredLoss<shark::RealVector> loss; + + shark::ErrorFunction error(trainSet, &m_Net, &loss); + shark::TwoNormRegularizer regularizer(error.numberOfVariables()); + error.setRegularizer(m_Regularization[0],®ularizer); + + shark::IRpropPlusFull optimizer; + error.init(); + optimizer.init(error); + otbMsgDevMacro(<<"Error before training : " << optimizer.solution().value); + unsigned int i=0; + while( !criterion.stop( optimizer.solution() ) ) + { + i++; + optimizer.step(error); + otbMsgDevMacro(<<"Error after " << i << " iterations : " << optimizer.solution().value); + if (this->m_WriteLearningCurve == true) + { + File << optimizer.solution().value << std::endl; + } + } +} + +template <class TInputValue, class NeuronType> +bool +AutoencoderModel<TInputValue,NeuronType> +::CanReadFile(const std::string & filename) +{ + try + { + this->Load(filename); + m_Net.name(); + } + catch(...) + { + return false; + } + return true; +} + +template <class TInputValue, class NeuronType> +bool +AutoencoderModel<TInputValue,NeuronType> +::CanWriteFile(const std::string & /*filename*/) +{ + return true; +} + +template <class TInputValue, class NeuronType> +void +AutoencoderModel<TInputValue,NeuronType> +::Save(const std::string & filename, const std::string & /*name*/) +{ + otbMsgDevMacro(<< "saving model ..."); + std::ofstream ofs(filename); + ofs << m_Net.name() << std::endl; // the first line of the model file contains a key + shark::TextOutArchive oa(ofs); + oa << m_Net; + ofs.close(); + + if (this->m_WriteWeights == true) // output the map vectors in a txt file + { + std::ofstream otxt(filename+".txt"); + for (unsigned int i = 0 ; i < m_Net.layerMatrices().size(); ++i) + { + otxt << "layer " << i << std::endl; + otxt << m_Net.layerMatrix(i) << std::endl; + otxt << m_Net.bias(i) << std::endl; + otxt << std::endl; + } + } +} + +template <class TInputValue, class NeuronType> +void +AutoencoderModel<TInputValue,NeuronType> +::Load(const std::string & filename, const std::string & /*name*/) +{ + NetworkType net; + std::ifstream ifs(filename); + char autoencoder[256]; + ifs.getline(autoencoder,256); + std::string autoencoderstr(autoencoder); + + if (autoencoderstr != net.name()){ + itkExceptionMacro(<< "Error opening " << filename.c_str() ); + } + shark::TextInArchive ia(ifs); + ia >> m_Net; + ifs.close(); + + // This gives us the dimension if we keep the encoder and decoder + size_t feature_layer_index = m_Net.layerMatrices().size()/2; + // number of neurons in the feature layer (second dimension of the first decoder weight matrix) + this->SetDimension(m_Net.layerMatrix(feature_layer_index).size2()); +} + +template <class TInputValue, class NeuronType> +typename AutoencoderModel<TInputValue,NeuronType>::TargetSampleType +AutoencoderModel<TInputValue,NeuronType> +::DoPredict(const InputSampleType & value, ConfidenceValueType * /*quality*/) const +{ + shark::RealVector samples(value.Size()); + for(size_t i = 0; i < value.Size();i++) + { + samples[i]=value[i]; + } + + std::vector<shark::RealVector> features; + features.push_back(samples); + + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + + // features layer for a network containing the encoder and decoder part + data = m_Net.evalLayer( m_Net.layerMatrices().size()/2-1 ,data); + TargetSampleType target; + target.SetSize(this->m_Dimension); + + for(unsigned int a = 0; a < this->m_Dimension; ++a) + { + target[a]=data.element(0)[a]; + } + return target; +} + +template <class TInputValue, class NeuronType> +void +AutoencoderModel<TInputValue,NeuronType> +::DoPredictBatch( + const InputListSampleType *input, + const unsigned int & startIndex, + const unsigned int & size, + TargetListSampleType * targets, + ConfidenceListSampleType * /*quality*/) const +{ + std::vector<shark::RealVector> features; + Shark::ListSampleRangeToSharkVector(input, features,startIndex,size); + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + TargetSampleType target; + // features layer for a network containing the encoder and decoder part + data = m_Net.evalLayer( m_Net.layerMatrices().size()/2-1 ,data); + + unsigned int id = startIndex; + target.SetSize(this->m_Dimension); + + for(const auto& p : data.elements()) + { + for(unsigned int a = 0; a < this->m_Dimension; ++a) + { + target[a]=p[a]; + } + targets->SetMeasurementVector(id,target); + ++id; + } +} + +} // namespace otb + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.h b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..711711ca4b5afd0a9d1864cc7b300dd56d40db64 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbAutoencoderModelFactory_h +#define otbAutoencoderModelFactory_h + +#include "itkObjectFactoryBase.h" +#include "itkImageIOBase.h" + +namespace otb +{ + +/** + * \class AutoencoderModelFactory + * + * Factory for AutoencoderModel + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, class TTargetValue, class NeuronType> +class ITK_EXPORT AutoencoderModelFactory : public itk::ObjectFactoryBase +{ +public: + /** Standard class typedefs. */ + typedef AutoencoderModelFactory Self; + typedef itk::ObjectFactoryBase Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Class methods used to interface with the registered factories. */ + const char* GetITKSourceVersion(void) const ITK_OVERRIDE; + const char* GetDescription(void) const ITK_OVERRIDE; + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(AutoencoderModelFactory, itk::ObjectFactoryBase); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) + { + Pointer AEFactory = AutoencoderModelFactory::New(); + itk::ObjectFactoryBase::RegisterFactory(AEFactory); + } + +protected: + AutoencoderModelFactory(); + ~AutoencoderModelFactory() ITK_OVERRIDE; + +private: + AutoencoderModelFactory(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented +}; + +} //namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbAutoencoderModelFactory.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.txx new file mode 100644 index 0000000000000000000000000000000000000000..c55f718a622ccd6ecc9632bd8cac7b9aa38c78bf --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbAutoencoderModelFactory.txx @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbAutoencoderModelFactory_txx +#define otbAutoencoderModelFactory_txx + +#include "otbAutoencoderModelFactory.h" +#include "otbAutoencoderModel.h" + +#include "itkCreateObjectFunction.h" +#include "itkVersion.h" + +namespace otb +{ +template <class TInputValue, class TOutputValue, class NeuronType> +AutoencoderModelFactory<TInputValue,TOutputValue, NeuronType>::AutoencoderModelFactory() +{ + std::string classOverride = std::string("DimensionalityReductionModel"); + std::string subclass = std::string("AutoencoderModel"); + + this->RegisterOverride( + classOverride.c_str(), + subclass.c_str(), + "Shark AE ML Model", + 1, + itk::CreateObjectFunction<AutoencoderModel<TInputValue,NeuronType > >::New()); +} + +template <class TInputValue, class TOutputValue, class NeuronType> +AutoencoderModelFactory<TInputValue,TOutputValue, NeuronType>::~AutoencoderModelFactory() +{ +} + +template <class TInputValue, class TOutputValue, class NeuronType> +const char* +AutoencoderModelFactory<TInputValue,TOutputValue, NeuronType>::GetITKSourceVersion(void) const +{ + return ITK_SOURCE_VERSION; +} + +template <class TInputValue, class TOutputValue, class NeuronType> +const char* +AutoencoderModelFactory<TInputValue,TOutputValue, NeuronType>::GetDescription() const +{ + return "Autoencoder model factory"; +} + +} // end namespace otb + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.h b/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..9bbd28bc0b9ebbe7561bb19ca5f6df5b398a082b --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbDimensionalityReductionModelFactory_h +#define otbDimensionalityReductionModelFactory_h + +#include "otbMachineLearningModelFactoryBase.h" +#include "otbMachineLearningModel.h" + +namespace otb +{ +/** \class MachineLearningModelFactory + * \brief Creation of object instance using object factory. + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, class TOutputValue> +class DimensionalityReductionModelFactory : public MachineLearningModelFactoryBase +{ +public: + /** Standard class typedefs. */ + typedef DimensionalityReductionModelFactory Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Class Methods used to interface with the registered factories */ + + /** Run-time type information (and related methods). */ + itkTypeMacro(DimensionalityReductionModelFactory, itk::Object); + + /** Convenient typedefs. */ + typedef otb::MachineLearningModel< + itk::VariableLengthVector< TInputValue >, + itk::VariableLengthVector< TOutputValue> > DimensionalityReductionModelType; + typedef typename DimensionalityReductionModelType::Pointer DimensionalityReductionModelTypePointer; + + /** Mode in which the files is intended to be used */ + typedef enum { ReadMode, WriteMode } FileModeType; + + /** Create the appropriate MachineLearningModel depending on the particulars of the file. */ + static DimensionalityReductionModelTypePointer CreateDimensionalityReductionModel(const std::string& path, FileModeType mode); + + static void CleanFactories(); + +protected: + DimensionalityReductionModelFactory(); + ~DimensionalityReductionModelFactory() ITK_OVERRIDE; + +private: + DimensionalityReductionModelFactory(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + /** Register Built-in factories */ + static void RegisterBuiltInFactories(); + + /** Register a single factory, ensuring it has not been registered + * twice */ + static void RegisterFactory(itk::ObjectFactoryBase * factory); +}; + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbDimensionalityReductionModelFactory.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.txx new file mode 100644 index 0000000000000000000000000000000000000000..451fce5b7c7b8ff866d3a921a883682c4e3426a8 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbDimensionalityReductionModelFactory.txx @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbDimensionalityReductionModelFactory_txx +#define otbDimensionalityReductionModelFactory_txx + +#include "otbDimensionalityReductionModelFactory.h" +#include "otbConfigure.h" + +#include "otbSOMModelFactory.h" + +#ifdef OTB_USE_SHARK +#include "otbAutoencoderModelFactory.h" +#include "otbPCAModelFactory.h" +#endif + +#include "itkMutexLockHolder.h" + +namespace otb +{ + +template <class TInputValue, class TTargetValue> +using LogAutoencoderModelFactory = AutoencoderModelFactory<TInputValue, TTargetValue, shark::LogisticNeuron> ; + +template <class TInputValue, class TTargetValue> +using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2> ; + +template <class TInputValue, class TTargetValue> +using SOM3DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 3> ; + +template <class TInputValue, class TTargetValue> +using SOM4DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 4> ; + +template <class TInputValue, class TTargetValue> +using SOM5DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 5> ; + + +template <class TInputValue, class TOutputValue> +typename DimensionalityReductionModelFactory<TInputValue,TOutputValue>::DimensionalityReductionModelTypePointer +DimensionalityReductionModelFactory<TInputValue,TOutputValue> +::CreateDimensionalityReductionModel(const std::string& path, FileModeType mode) +{ + RegisterBuiltInFactories(); + + std::list<DimensionalityReductionModelTypePointer> possibleDimensionalityReductionModel; + std::list<LightObject::Pointer> allobjects = + itk::ObjectFactoryBase::CreateAllInstance("DimensionalityReductionModel"); + + for(std::list<LightObject::Pointer>::iterator i = allobjects.begin(); + i != allobjects.end(); ++i) + { + DimensionalityReductionModelType* io = + dynamic_cast<DimensionalityReductionModelType*>(i->GetPointer()); + if(io) + { + possibleDimensionalityReductionModel.push_back(io); + } + else + { + std::cerr << "Error DimensionalityReductionModel Factory did not return an DimensionalityReductionModel: " + << (*i)->GetNameOfClass() + << std::endl; + } + } + + for(typename std::list<DimensionalityReductionModelTypePointer>::iterator k = possibleDimensionalityReductionModel.begin(); + k != possibleDimensionalityReductionModel.end(); ++k) + { + if( mode == ReadMode ) + { + if((*k)->CanReadFile(path)) + { + return *k; + } + } + else if( mode == WriteMode ) + { + if((*k)->CanWriteFile(path)) + { + return *k; + } + } + } + return ITK_NULLPTR; +} + +template <class TInputValue, class TOutputValue> +void +DimensionalityReductionModelFactory<TInputValue,TOutputValue> +::RegisterBuiltInFactories() +{ + itk::MutexLockHolder<itk::SimpleMutexLock> lockHolder(mutex); + + RegisterFactory(SOM2DModelFactory<TInputValue,TOutputValue>::New()); + RegisterFactory(SOM3DModelFactory<TInputValue,TOutputValue>::New()); + RegisterFactory(SOM4DModelFactory<TInputValue,TOutputValue>::New()); + RegisterFactory(SOM5DModelFactory<TInputValue,TOutputValue>::New()); + +#ifdef OTB_USE_SHARK + RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New()); + RegisterFactory(LogAutoencoderModelFactory<TInputValue,TOutputValue>::New()); +#endif +} + +template <class TInputValue, class TOutputValue> +void +DimensionalityReductionModelFactory<TInputValue,TOutputValue> +::RegisterFactory(itk::ObjectFactoryBase * factory) +{ + // Unregister any previously registered factory of the same class + // Might be more intensive but static bool is not an option due to + // ld error. + itk::ObjectFactoryBase::UnRegisterFactory(factory); + itk::ObjectFactoryBase::RegisterFactory(factory); +} + +template <class TInputValue, class TOutputValue> +void +DimensionalityReductionModelFactory<TInputValue,TOutputValue> +::CleanFactories() +{ + itk::MutexLockHolder<itk::SimpleMutexLock> lockHolder(mutex); + + std::list<itk::ObjectFactoryBase*> factories = itk::ObjectFactoryBase::GetRegisteredFactories(); + std::list<itk::ObjectFactoryBase*>::iterator itFac; + + for (itFac = factories.begin(); itFac != factories.end() ; ++itFac) + { + // SOM 5D + SOM5DModelFactory<TInputValue,TOutputValue> *som5dFactory = + dynamic_cast<SOM5DModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (som5dFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(som5dFactory); + continue; + } + // SOM 4D + SOM4DModelFactory<TInputValue,TOutputValue> *som4dFactory = + dynamic_cast<SOM4DModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (som4dFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(som4dFactory); + continue; + } + // SOM 3D + SOM3DModelFactory<TInputValue,TOutputValue> *som3dFactory = + dynamic_cast<SOM3DModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (som3dFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(som3dFactory); + continue; + } + // SOM 2D + SOM2DModelFactory<TInputValue,TOutputValue> *som2dFactory = + dynamic_cast<SOM2DModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (som2dFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(som2dFactory); + continue; + } +#ifdef OTB_USE_SHARK + // Autoencoder + LogAutoencoderModelFactory<TInputValue,TOutputValue> *aeFactory = + dynamic_cast<LogAutoencoderModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (aeFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(aeFactory); + continue; + } + // PCA + PCAModelFactory<TInputValue,TOutputValue> *pcaFactory = + dynamic_cast<PCAModelFactory<TInputValue,TOutputValue> *>(*itFac); + if (pcaFactory) + { + itk::ObjectFactoryBase::UnRegisterFactory(pcaFactory); + continue; + } +#endif + } +} + +} // end namespace otb + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.h b/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..d5538c1700538d6e77adb78c0358108e9730ce73 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbImageDimensionalityReduction_h +#define otbImageDimensionalityReduction_h + +#include "itkImageToImageFilter.h" +#include "otbMachineLearningModel.h" +#include "otbImage.h" + +namespace otb +{ +/** \class ImageClassificationFilter + * \brief This filter performs the classification of a VectorImage using a Model. + * + * This filter is streamed and threaded, allowing to classify huge images + * while fully using several core. + * + * \sa Classifier + * \ingroup Streamed + * \ingroup Threaded + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputImage, class TOutputImage, class TMaskImage = TOutputImage> +class ITK_EXPORT ImageDimensionalityReductionFilter + : public itk::ImageToImageFilter<TInputImage, TOutputImage> +{ +public: + /** Standard typedefs */ + typedef ImageDimensionalityReductionFilter Self; + typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Type macro */ + itkNewMacro(Self); + + /** Creation through object factory macro */ + itkTypeMacro(ImageDimensionalityReductionFilter, ImageToImageFilter); + + typedef TInputImage InputImageType; + typedef typename InputImageType::ConstPointer InputImageConstPointerType; + typedef typename InputImageType::InternalPixelType ValueType; + + typedef TMaskImage MaskImageType; + typedef typename MaskImageType::ConstPointer MaskImageConstPointerType; + typedef typename MaskImageType::Pointer MaskImagePointerType; + + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointerType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::InternalPixelType LabelType; + + typedef MachineLearningModel<itk::VariableLengthVector<ValueType>, itk::VariableLengthVector<LabelType>> ModelType; + typedef typename ModelType::Pointer ModelPointerType; + + typedef otb::Image<double> ConfidenceImageType; + typedef typename ConfidenceImageType::Pointer ConfidenceImagePointerType; + + /** Set/Get the model */ + itkSetObjectMacro(Model, ModelType); + itkGetObjectMacro(Model, ModelType); + + /** Set/Get the default label */ + itkSetMacro(DefaultLabel, LabelType); + itkGetMacro(DefaultLabel, LabelType); + + /** Set/Get the confidence map flag */ + itkSetMacro(UseConfidenceMap, bool); + itkGetMacro(UseConfidenceMap, bool); + + itkSetMacro(BatchMode, bool); + itkGetMacro(BatchMode, bool); + itkBooleanMacro(BatchMode); + + /** + * If set, only pixels within the mask will be classified. + * All pixels with a value greater than 0 in the mask, will be classified. + * \param mask The input mask. + */ + void SetInputMask(const MaskImageType * mask); + + /** + * Get the input mask. + * \return The mask. + */ + const MaskImageType * GetInputMask(void); + + /** + * Get the output confidence map + */ + ConfidenceImageType * GetOutputConfidence(void); + +protected: + /** Constructor */ + ImageDimensionalityReductionFilter(); + /** Destructor */ + ~ImageDimensionalityReductionFilter() ITK_OVERRIDE {} + + /** Generate output information */ + virtual void GenerateOutputInformation(); + + /** Threaded generate data */ + void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) ITK_OVERRIDE; + void ClassicThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId); + void BatchThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId); + /** Before threaded generate data */ + void BeforeThreadedGenerateData() ITK_OVERRIDE; + /**PrintSelf method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE; + +private: + ImageDimensionalityReductionFilter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + /** The model used for classification */ + ModelPointerType m_Model; + /** Default label for invalid pixels (when using a mask) */ + LabelType m_DefaultLabel; + /** Flag to produce the confidence map (if the model supports it) */ + bool m_UseConfidenceMap; + bool m_BatchMode; +}; +} // End namespace otb +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbImageDimensionalityReductionFilter.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..140a8cd874e3555f73d985e6234c926c93e04993 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbImageDimensionalityReductionFilter.txx @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbImageDimensionalityReductionFilter_txx +#define otbImageDimensionalityReductionFilter_txx + +#include "otbImageDimensionalityReductionFilter.h" +#include "itkImageRegionIterator.h" +#include "itkProgressReporter.h" + +namespace otb +{ +/** + * Constructor + */ +template <class TInputImage, class TOutputImage, class TMaskImage> +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::ImageDimensionalityReductionFilter() +{ + this->SetNumberOfIndexedInputs(2); + this->SetNumberOfRequiredInputs(1); + + this->SetNumberOfRequiredOutputs(2); + this->SetNthOutput(0,TOutputImage::New()); + this->SetNthOutput(1,ConfidenceImageType::New()); + m_UseConfidenceMap = false; + m_BatchMode = true; +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::SetInputMask(const MaskImageType * mask) +{ + this->itk::ProcessObject::SetNthInput(1, const_cast<MaskImageType *>(mask)); +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +const typename ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::MaskImageType * +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::GetInputMask() +{ + if (this->GetNumberOfInputs() < 2) + { + return ITK_NULLPTR; + } + return static_cast<const MaskImageType *>(this->itk::ProcessObject::GetInput(1)); +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +typename ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::ConfidenceImageType * +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::GetOutputConfidence() +{ + if (this->GetNumberOfOutputs() < 2) + { + return ITK_NULLPTR; + } + return static_cast<ConfidenceImageType *>(this->itk::ProcessObject::GetOutput(1)); +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::BeforeThreadedGenerateData() +{ + if(m_BatchMode) + { + #ifdef _OPENMP + // OpenMP will take care of threading + this->SetNumberOfThreads(1); + #endif + } +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::ClassicThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) +{ + // Get the input pointers + InputImageConstPointerType inputPtr = this->GetInput(); + MaskImageConstPointerType inputMaskPtr = this->GetInputMask(); + OutputImagePointerType outputPtr = this->GetOutput(); + ConfidenceImagePointerType confidencePtr = this->GetOutputConfidence(); + + // Progress reporting + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + // Define iterators + typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType; + typedef itk::ImageRegionIterator<OutputImageType> OutputIteratorType; + + InputIteratorType inIt(inputPtr, outputRegionForThread); + OutputIteratorType outIt(outputPtr, outputRegionForThread); + + // Walk the part of the image + for (inIt.GoToBegin(), outIt.GoToBegin(); !inIt.IsAtEnd() && !outIt.IsAtEnd(); ++inIt, ++outIt) + { + // Classifify + outIt.Set(m_Model->Predict(inIt.Get())); + progress.CompletedPixel(); + } +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage>::GenerateOutputInformation() +{ + Superclass::GenerateOutputInformation(); + if (!m_Model) + { + itkGenericExceptionMacro(<< "No model for dimensionality reduction"); + } + this->GetOutput()->SetNumberOfComponentsPerPixel( m_Model->GetDimension() ); +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::BatchThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) +{ + // Get the input pointers + InputImageConstPointerType inputPtr = this->GetInput(); + MaskImageConstPointerType inputMaskPtr = this->GetInputMask(); + OutputImagePointerType outputPtr = this->GetOutput(); + ConfidenceImagePointerType confidencePtr = this->GetOutputConfidence(); + + // Progress reporting + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + // Define iterators + typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType; + typedef itk::ImageRegionIterator<OutputImageType> OutputIteratorType; + + InputIteratorType inIt(inputPtr, outputRegionForThread); + OutputIteratorType outIt(outputPtr, outputRegionForThread); + + typedef typename ModelType::InputSampleType InputSampleType; + typedef typename ModelType::InputListSampleType InputListSampleType; + typedef typename ModelType::TargetValueType TargetValueType; + typedef typename ModelType::TargetListSampleType TargetListSampleType; + + typename InputListSampleType::Pointer samples = InputListSampleType::New(); + unsigned int num_features = inputPtr->GetNumberOfComponentsPerPixel(); + samples->SetMeasurementVectorSize(num_features); + InputSampleType sample(num_features); + + // Fill the samples + for (inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt) + { + typename InputImageType::PixelType pix = inIt.Get(); + for(size_t feat=0; feat<num_features; ++feat) + { + sample[feat]=pix[feat]; + } + samples->PushBack(sample); + } + //Make the batch prediction + typename TargetListSampleType::Pointer labels; + + // This call is threadsafe + labels = m_Model->PredictBatch(samples); + + // Set the output values + typename TargetListSampleType::ConstIterator labIt = labels->Begin(); + for (outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt) + { + itk::VariableLengthVector<TargetValueType> labelValue; + labelValue = labIt.GetMeasurementVector(); + ++labIt; + outIt.Set(labelValue); + progress.CompletedPixel(); + } +} + +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) +{ + if(m_BatchMode) + { + this->BatchThreadedGenerateData(outputRegionForThread, threadId); + } + else + { + this->ClassicThreadedGenerateData(outputRegionForThread, threadId); + } +} + +/** + * PrintSelf Method + */ +template <class TInputImage, class TOutputImage, class TMaskImage> +void +ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // End namespace otb +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.h b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.h new file mode 100644 index 0000000000000000000000000000000000000000..dd8f7a6992b1b3898608c90b47ead64db1a45c8a --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbPCAModel_h +#define otbPCAModel_h + +#include "otbMachineLearningModelTraits.h" +#include "otbMachineLearningModel.h" + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#pragma GCC diagnostic ignored "-Wsign-compare" +#endif +#include "otb_shark.h" +#include <shark/Algorithms/Trainers/PCA.h> +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +namespace otb +{ + +/** \class PCAModel + * + * This class wraps a PCA model implemented by Shark, in a otb::MachineLearningModel + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue> +class ITK_EXPORT PCAModel + : public MachineLearningModel< + itk::VariableLengthVector< TInputValue >, + itk::VariableLengthVector< TInputValue > > +{ +public: + typedef PCAModel Self; + typedef MachineLearningModel< + itk::VariableLengthVector< TInputValue >, + itk::VariableLengthVector< TInputValue> > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::InputValueType InputValueType; + typedef typename Superclass::InputSampleType InputSampleType; + typedef typename Superclass::InputListSampleType InputListSampleType; + typedef typename InputListSampleType::Pointer ListSamplePointerType; + typedef typename Superclass::TargetValueType TargetValueType; + typedef typename Superclass::TargetSampleType TargetSampleType; + typedef typename Superclass::TargetListSampleType TargetListSampleType; + + // Confidence map related typedefs + typedef typename Superclass::ConfidenceValueType ConfidenceValueType; + typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType; + typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType; + + itkNewMacro(Self); + itkTypeMacro(PCAModel, DimensionalityReductionModel); + + itkSetMacro(DoResizeFlag,bool); + + itkSetMacro(WriteEigenvectors, bool); + itkGetMacro(WriteEigenvectors, bool); + + bool CanReadFile(const std::string & filename); + bool CanWriteFile(const std::string & filename); + + void Save(const std::string & filename, const std::string & name="") ITK_OVERRIDE; + void Load(const std::string & filename, const std::string & name="") ITK_OVERRIDE; + + void Train() ITK_OVERRIDE; + +protected: + PCAModel(); + ~PCAModel() ITK_OVERRIDE; + + virtual TargetSampleType DoPredict( + const InputSampleType& input, + ConfidenceValueType * quality = ITK_NULLPTR) const; + + virtual void DoPredictBatch( + const InputListSampleType *, + const unsigned int & startIndex, + const unsigned int & size, + TargetListSampleType *, + ConfidenceListSampleType * quality = ITK_NULLPTR) const ITK_OVERRIDE; + +private: + shark::LinearModel<> m_Encoder; + shark::LinearModel<> m_Decoder; + shark::PCA m_PCA; + bool m_DoResizeFlag; + bool m_WriteEigenvectors; +}; +} // end namespace otb + + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbPCAModel.txx" +#endif + + +#endif + diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.txx new file mode 100644 index 0000000000000000000000000000000000000000..9f39326a21bc5f1980a49d80ecdaea55b42a450a --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModel.txx @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbPCAModel_txx +#define otbPCAModel_txx + +#include "otbPCAModel.h" + +#include <fstream> +#include "itkMacro.h" +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#endif +#include "otbSharkUtils.h" +//include train function +#include <shark/ObjectiveFunctions/ErrorFunction.h> +#include <shark/Algorithms/GradientDescent/Rprop.h>// the RProp optimization algorithm +#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> // squared loss used for regression +#include <shark/ObjectiveFunctions/Regularizer.h> //L2 regulariziation +#include <shark/ObjectiveFunctions/ErrorFunction.h> +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +namespace otb +{ + +template <class TInputValue> +PCAModel<TInputValue>::PCAModel() +{ + this->m_IsDoPredictBatchMultiThreaded = true; + this->m_Dimension = 0; +} + +template <class TInputValue> +PCAModel<TInputValue>::~PCAModel() +{ +} + +template <class TInputValue> +void +PCAModel<TInputValue>::Train() +{ + std::vector<shark::RealVector> features; + + Shark::ListSampleToSharkVector(this->GetInputListSample(), features); + + shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features ); + m_PCA.setData(inputSamples); + m_PCA.encoder(m_Encoder, this->m_Dimension); + m_PCA.decoder(m_Decoder, this->m_Dimension); +} + +template <class TInputValue> +bool +PCAModel<TInputValue>::CanReadFile(const std::string & filename) +{ + try + { + this->Load(filename); + m_Encoder.name(); + } + catch(...) + { + return false; + } + return true; +} + +template <class TInputValue> +bool PCAModel<TInputValue>::CanWriteFile(const std::string & /*filename*/) +{ + return true; +} + +template <class TInputValue> +void +PCAModel<TInputValue>::Save(const std::string & filename, const std::string & /*name*/) +{ + std::ofstream ofs(filename); + ofs << "pca" << std::endl; //first line + shark::TextOutArchive oa(ofs); + m_Encoder.write(oa); + ofs.close(); + + if (this->m_WriteEigenvectors == true) // output the map vectors in a txt file + { + std::ofstream otxt(filename+".txt"); + + otxt << "Eigenvectors : " << m_PCA.eigenvectors() << std::endl; + otxt << "Eigenvalues : " << m_PCA.eigenvalues() << std::endl; + + std::vector<shark::RealVector> features; + + shark::SquaredLoss<shark::RealVector> loss; + Shark::ListSampleToSharkVector(this->GetInputListSample(), features); + shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features ); + otxt << "Reconstruction error : " << + loss.eval(inputSamples,m_Decoder(m_Encoder(inputSamples))) << std::endl; + otxt.close(); + } +} + +template <class TInputValue> +void +PCAModel<TInputValue>::Load(const std::string & filename, const std::string & /*name*/) +{ + std::ifstream ifs(filename); + char encoder[256]; + ifs.getline(encoder,256); + std::string encoderstr(encoder); + + if (encoderstr != "pca"){ + itkExceptionMacro(<< "Error opening " << filename.c_str() ); + } + shark::TextInArchive ia(ifs); + m_Encoder.read(ia); + ifs.close(); + if (this->m_Dimension ==0) + { + this->m_Dimension = m_Encoder.outputSize(); + } + + auto eigenvectors = m_Encoder.matrix(); + eigenvectors.resize(this->m_Dimension,m_Encoder.inputSize()); + + m_Encoder.setStructure(eigenvectors, m_Encoder.offset() ); +} + +template <class TInputValue> +typename PCAModel<TInputValue>::TargetSampleType +PCAModel<TInputValue>::DoPredict(const InputSampleType & value, ConfidenceValueType * /*quality*/) const +{ + shark::RealVector samples(value.Size()); + for(size_t i = 0; i < value.Size();i++) + { + samples[i]=value[i]; + } + + std::vector<shark::RealVector> features; + features.push_back(samples); + + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + + data = m_Encoder(data); + TargetSampleType target; + target.SetSize(this->m_Dimension); + + for(unsigned int a = 0; a < this->m_Dimension; ++a){ + target[a]=data.element(0)[a]; + } + return target; +} + +template <class TInputValue> +void PCAModel<TInputValue> +::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * /*quality*/) const +{ + std::vector<shark::RealVector> features; + Shark::ListSampleRangeToSharkVector(input, features,startIndex,size); + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + TargetSampleType target; + data = m_Encoder(data); + unsigned int id = startIndex; + target.SetSize(this->m_Dimension); + for(const auto& p : data.elements()) + { + for(unsigned int a = 0; a < this->m_Dimension; ++a) + { + target[a]=p[a]; + } + targets->SetMeasurementVector(id,target); + ++id; + } +} + +} // namespace otb +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.h b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..d30a2c4663f0e9b44afc66045ffd1bd24b89dffc --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbPCAModelFactory_h +#define otbPCAModelFactory_h + +#include "itkObjectFactoryBase.h" +#include "itkImageIOBase.h" + +namespace otb +{ + +/** \class PCAModelFactory + * + * Factory for the PCAModel + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, class TTargetValue> +class ITK_EXPORT PCAModelFactory : public itk::ObjectFactoryBase +{ +public: + /** Standard class typedefs. */ + typedef PCAModelFactory Self; + typedef itk::ObjectFactoryBase Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Class methods used to interface with the registered factories. */ + const char* GetITKSourceVersion(void) const ITK_OVERRIDE; + const char* GetDescription(void) const ITK_OVERRIDE; + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(PCAModelFactory, itk::ObjectFactoryBase); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) + { + Pointer PCAFactory = PCAModelFactory::New(); + itk::ObjectFactoryBase::RegisterFactory(PCAFactory); + } + +protected: + PCAModelFactory(); + ~PCAModelFactory() ITK_OVERRIDE; + +private: + PCAModelFactory(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented +}; + +} //namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbPCAModelFactory.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.txx new file mode 100644 index 0000000000000000000000000000000000000000..ab31accbe01b926a1d4ca57b4f23b3fc813cd931 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbPCAModelFactory.txx @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbPCAFactory_txx +#define otbPCAFactory_txx + +#include "otbPCAModelFactory.h" + +#include "itkCreateObjectFunction.h" +#include "otbPCAModel.h" +#include "itkVersion.h" + +namespace otb +{ + +template <class TInputValue, class TOutputValue> +PCAModelFactory<TInputValue,TOutputValue>::PCAModelFactory() +{ + std::string classOverride = std::string("DimensionalityReductionModel"); + std::string subclass = std::string("PCAModel"); + + this->RegisterOverride( + classOverride.c_str(), + subclass.c_str(), + "Shark PCA ML Model", + 1, + itk::CreateObjectFunction<PCAModel<TInputValue>>::New()); +} + +template <class TInputValue, class TOutputValue> +PCAModelFactory<TInputValue,TOutputValue>::~PCAModelFactory() +{ +} + +template <class TInputValue, class TOutputValue> +const char* PCAModelFactory<TInputValue,TOutputValue>::GetITKSourceVersion(void) const +{ + return ITK_SOURCE_VERSION; +} + +template <class TInputValue, class TOutputValue> +const char* PCAModelFactory<TInputValue,TOutputValue>::GetDescription() const +{ + return "PCA model factory"; +} + +} // end namespace otb + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.h b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.h new file mode 100644 index 0000000000000000000000000000000000000000..7f6fb2b08e4a4f0a2e443e90549e1a6461b31d10 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbSOMModel_h +#define otbSOMModel_h + +#include "otbSOMMap.h" + +#include "itkEuclideanDistanceMetric.h" // the distance function + +#include "otbCzihoSOMLearningBehaviorFunctor.h" +#include "otbCzihoSOMNeighborhoodBehaviorFunctor.h" + +#include "otbMachineLearningModelTraits.h" +#include "otbMachineLearningModel.h" + +namespace otb +{ + +/** \class SOMModel + * MachineLearningModel for Self-Organizing Map + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, unsigned int MapDimension> +class ITK_EXPORT SOMModel + : public MachineLearningModel< + itk::VariableLengthVector< TInputValue >, + itk::VariableLengthVector< TInputValue > > +{ +public: + typedef SOMModel Self; + typedef MachineLearningModel< + itk::VariableLengthVector< TInputValue >, + itk::VariableLengthVector< TInputValue > > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::InputValueType InputValueType; + typedef typename Superclass::InputSampleType InputSampleType; + typedef typename Superclass::InputListSampleType InputListSampleType; + typedef typename InputListSampleType::Pointer ListSamplePointerType; + typedef typename Superclass::TargetValueType TargetValueType; + typedef typename Superclass::TargetSampleType TargetSampleType; + typedef typename Superclass::TargetListSampleType TargetListSampleType; + + // Confidence map related typedefs + typedef typename Superclass::ConfidenceValueType ConfidenceValueType; + typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType; + typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType; + + typedef SOMMap< + itk::VariableLengthVector<TInputValue>, + itk::Statistics::EuclideanDistanceMetric< + itk::VariableLengthVector<TInputValue> >, + MapDimension> MapType; + typedef typename MapType::SizeType SizeType; + typedef typename MapType::SpacingType SpacingType; + + typedef Functor::CzihoSOMLearningBehaviorFunctor SOMLearningBehaviorFunctorType; + typedef Functor::CzihoSOMNeighborhoodBehaviorFunctor SOMNeighborhoodBehaviorFunctorType; + + itkNewMacro(Self); + itkTypeMacro(SOMModel, DimensionalityReductionModel); + + /** Accessors */ + itkSetMacro(NumberOfIterations, unsigned int); + itkGetMacro(NumberOfIterations, unsigned int); + itkSetMacro(BetaInit, double); + itkGetMacro(BetaInit, double); + itkSetMacro(WriteMap, bool); + itkGetMacro(WriteMap, bool); + itkSetMacro(BetaEnd, double); + itkGetMacro(BetaEnd, double); + itkSetMacro(MinWeight, InputValueType); + itkGetMacro(MinWeight, InputValueType); + itkSetMacro(MaxWeight, InputValueType); + itkGetMacro(MaxWeight, InputValueType); + itkSetMacro(MapSize, SizeType); + itkGetMacro(MapSize, SizeType); + itkSetMacro(NeighborhoodSizeInit, SizeType); + itkGetMacro(NeighborhoodSizeInit, SizeType); + itkSetMacro(RandomInit, bool); + itkGetMacro(RandomInit, bool); + itkSetMacro(Seed, unsigned int); + itkGetMacro(Seed, unsigned int); + + bool CanReadFile(const std::string & filename); + bool CanWriteFile(const std::string & filename); + + void Save(const std::string & filename, const std::string & name="") ; + void Load(const std::string & filename, const std::string & name="") ; + + void Train() ITK_OVERRIDE; + +protected: + SOMModel(); + ~SOMModel() ITK_OVERRIDE; + +private: + typename MapType::Pointer m_SOMMap; + + virtual TargetSampleType DoPredict( + const InputSampleType& input, + ConfidenceValueType * quality = ITK_NULLPTR) const; + + /** Map size (width, height) */ + SizeType m_MapSize; + /** Number of iterations */ + unsigned int m_NumberOfIterations; + /** Initial learning coefficient */ + double m_BetaInit; + /** Final learning coefficient */ + double m_BetaEnd; + /** Initial neighborhood size */ + SizeType m_NeighborhoodSizeInit; + /** Minimum initial neuron weights */ + InputValueType m_MinWeight; + /** Maximum initial neuron weights */ + InputValueType m_MaxWeight; + /** Random initialization bool */ + bool m_RandomInit; + /** Seed for random initialization */ + unsigned int m_Seed; + /** Behavior of the Learning weightening (link to the beta coefficient) */ + SOMLearningBehaviorFunctorType m_BetaFunctor; + /** Behavior of the Neighborhood extent */ + SOMNeighborhoodBehaviorFunctorType m_NeighborhoodSizeFunctor; + /** Write the SOM Map vectors in a txt file */ + bool m_WriteMap; +}; + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbSOMModel.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.txx new file mode 100644 index 0000000000000000000000000000000000000000..e1d7dc3fc6251abbdbd3aa210cd3c3ebced903d8 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModel.txx @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbSOMModel_txx +#define otbSOMModel_txx + +#include "otbSOMModel.h" +#include "otbSOM.h" + +#include "itkMacro.h" +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" +#include "itkImage.h" + +#include <fstream> + +namespace otb +{ + +namespace internal +{ +template<typename T> +std::ostream& BinaryWrite(std::ostream& stream, const T& value) +{ + return stream.write(reinterpret_cast<const char*>(&value), sizeof(T)); +} + +std::ostream& BinaryWriteString(std::ofstream& stream, const std::string& value) +{ + return stream.write(value.c_str(), value.length()); +} + +template<typename T> +std::istream & BinaryRead(std::istream& stream, T& value) +{ + return stream.read(reinterpret_cast<char*>(&value), sizeof(T)); +} +} // end of namespace internal + +template <class TInputValue, unsigned int MapDimension> +SOMModel<TInputValue, MapDimension>::SOMModel() +{ + this->m_Dimension = MapType::ImageDimension; +} + +template <class TInputValue, unsigned int MapDimension> +SOMModel<TInputValue, MapDimension>::~SOMModel() +{ +} + +template <class TInputValue, unsigned int MapDimension> +void +SOMModel<TInputValue, MapDimension>::Train() +{ + typedef otb::SOM<InputListSampleType, MapType> EstimatorType; + typename EstimatorType::Pointer estimator = EstimatorType::New(); + estimator->SetListSample(this->GetInputListSample()); + estimator->SetMapSize(m_MapSize); + estimator->SetNeighborhoodSizeInit(m_NeighborhoodSizeInit); + estimator->SetNumberOfIterations(m_NumberOfIterations); + estimator->SetBetaInit(m_BetaInit); + estimator->SetBetaEnd(m_BetaEnd); + estimator->SetMaxWeight(m_MaxWeight); + estimator->Update(); + m_SOMMap = estimator->GetOutput(); +} + +template <class TInputValue, unsigned int MapDimension> +bool +SOMModel<TInputValue, MapDimension>::CanReadFile(const std::string & filename) +{ + try + { + this->Load(filename); + } + catch(...) + { + return false; + } + return true; +} + +template <class TInputValue, unsigned int MapDimension> +bool +SOMModel<TInputValue, MapDimension>::CanWriteFile(const std::string & /*filename*/) +{ + return true; +} + +template <class TInputValue, unsigned int MapDimension> +void +SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, const std::string & /*name*/) +{ + itk::ImageRegionConstIterator<MapType> inputIterator(m_SOMMap,m_SOMMap->GetLargestPossibleRegion()); + inputIterator.GoToBegin(); + std::ofstream ofs(filename, std::ios::binary); + internal::BinaryWriteString(ofs,"som"); + internal::BinaryWrite(ofs,static_cast<unsigned int>(MapDimension)); + SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ; + for (size_t i=0;i<MapDimension;i++) + { + internal::BinaryWrite(ofs,size[i]); + } + + internal::BinaryWrite(ofs,inputIterator.Get().GetNumberOfElements()); + while(!inputIterator.IsAtEnd()) + { + InputSampleType vect = inputIterator.Get(); + for (size_t i=0;i<vect.GetNumberOfElements();i++) + { + internal::BinaryWrite(ofs,vect[i]); + } + ++inputIterator; + } + ofs.close(); + + // output the map vectors in a txt file + if (this->m_WriteMap == true) + { + std::ofstream otxt(filename+".txt"); + inputIterator.GoToBegin(); + while(!inputIterator.IsAtEnd()) + { + InputSampleType vect = inputIterator.Get(); + for (size_t i=0;i<vect.GetNumberOfElements();i++) + { + otxt << vect[i] << " "; + } + otxt << std::endl; + ++inputIterator; + } + otxt.close(); + } +} + +template <class TInputValue, unsigned int MapDimension> +void +SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, const std::string & /*name*/) +{ + std::ifstream ifs(filename, std::ios::binary); + + /** Read the model key (should be som) */ + char s[]=" "; + for (int i=0; i<3; i++) + { + internal::BinaryRead(ifs,s[i]); + } + std::string modelType(s); + /** Read the dimension of the map (should be equal to MapDimension) */ + + unsigned int dimension; + internal::BinaryRead(ifs,dimension); + if (modelType != "som" || dimension != MapDimension) + { + itkExceptionMacro(<< "Error opening " << filename.c_str() ); + } + + SizeType size; + itk::Index< MapDimension > index; + for (unsigned int i=0 ; i<MapDimension; i++) + { + internal::BinaryRead(ifs,size[i]); + index[i]=0; + } + unsigned int numberOfElements; + internal::BinaryRead(ifs,numberOfElements); + m_SOMMap = MapType::New(); + typename MapType::RegionType region; + region.SetSize( size ); + m_SOMMap->SetNumberOfComponentsPerPixel(numberOfElements); + region.SetIndex( index ); + m_SOMMap->SetRegions( region ); + m_SOMMap->Allocate(); + + itk::ImageRegionIterator<MapType> outputIterator(m_SOMMap,region); + outputIterator.GoToBegin(); + std::string value; + while(!outputIterator.IsAtEnd()) + { + InputSampleType vect(numberOfElements); + for (unsigned int i=0 ; i<numberOfElements; i++) + { + // InputValue type is not the same during training anddimredvector. + float v; + internal::BinaryRead(ifs,v); + vect[i] = static_cast<double>(v); + } + outputIterator.Set(vect); + ++outputIterator; + } + ifs.close(); + this->m_Dimension = MapType::ImageDimension; +} + +template <class TInputValue, unsigned int MapDimension> +typename SOMModel<TInputValue, MapDimension>::TargetSampleType +SOMModel<TInputValue, MapDimension>::DoPredict( + const InputSampleType & value, + ConfidenceValueType * /*quality*/) const +{ + TargetSampleType target; + target.SetSize(this->m_Dimension); + + auto winner =m_SOMMap->GetWinner(value); + for (unsigned int i=0; i< this->m_Dimension ;i++) + { + target[i] = winner.GetElement(i); + } + return target; +} + +} // namespace otb +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.h b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..71d314e5f5cad1bcf31ed7de8505d6dd164309bc --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbSOMModelFactory_h +#define otbSOMModelFactory_h + +#include "itkObjectFactoryBase.h" +#include "itkImageIOBase.h" + +namespace otb +{ + +/** \class SOMModelFactory + * + * Factory for SOMModel + * + * \ingroup OTBDimensionalityReductionLearning + */ +template <class TInputValue, class TTargetValue, unsigned int MapDimension> +class ITK_EXPORT SOMModelFactory : public itk::ObjectFactoryBase +{ +public: + /** Standard class typedefs. */ + typedef SOMModelFactory Self; + typedef itk::ObjectFactoryBase Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Class methods used to interface with the registered factories. */ + const char* GetITKSourceVersion(void) const ITK_OVERRIDE; + const char* GetDescription(void) const ITK_OVERRIDE; + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(SOMModelFactory, itk::ObjectFactoryBase); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) + { + Pointer SOMFactory = SOMModelFactory::New(); + itk::ObjectFactoryBase::RegisterFactory(SOMFactory); + } + +protected: + SOMModelFactory(); + ~SOMModelFactory() ITK_OVERRIDE; + +private: + SOMModelFactory(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + +}; + +} //namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbSOMModelFactory.txx" +#endif + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.txx b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.txx new file mode 100644 index 0000000000000000000000000000000000000000..5799660768e900fa37e2dc1f4365a5f37b66079d --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/include/otbSOMModelFactory.txx @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbSOMFactory_txx +#define otbSOMFactory_txx + +#include "otbSOMModelFactory.h" + +#include "itkCreateObjectFunction.h" +#include "otbSOMModel.h" +#include "itkVersion.h" + +namespace otb +{ +template <class TInputValue, class TOutputValue, unsigned int MapDimension> +SOMModelFactory<TInputValue,TOutputValue,MapDimension>::SOMModelFactory() +{ + std::string classOverride = std::string("DimensionalityReductionModel"); + std::string subclass = std::string("SOMModel"); + + this->RegisterOverride( + classOverride.c_str(), + subclass.c_str(), + "SOM DR Model", + 1, + itk::CreateObjectFunction<SOMModel<TInputValue, MapDimension>>::New()); +} + +template <class TInputValue, class TOutputValue, unsigned int MapDimension> +SOMModelFactory<TInputValue,TOutputValue,MapDimension>::~SOMModelFactory() +{ +} + +template <class TInputValue, class TOutputValue, unsigned int MapDimension> +const char* SOMModelFactory<TInputValue,TOutputValue,MapDimension>::GetITKSourceVersion(void) const +{ + return ITK_SOURCE_VERSION; +} + +template <class TInputValue, class TOutputValue, unsigned int MapDimension> +const char* SOMModelFactory<TInputValue,TOutputValue,MapDimension>::GetDescription() const +{ + return "SOM model factory"; +} + +} // end namespace otb + +#endif diff --git a/Modules/Learning/DimensionalityReductionLearning/otb-module.cmake b/Modules/Learning/DimensionalityReductionLearning/otb-module.cmake new file mode 100644 index 0000000000000000000000000000000000000000..aaff635d359f095f0e8cd79c32ebac618498e6bc --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/otb-module.cmake @@ -0,0 +1,36 @@ +# +# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) +# +# This file is part of Orfeo Toolbox +# +# https://www.orfeo-toolbox.org/ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set(DOCUMENTATION "Dimensionality reduction application") +otb_module(OTBDimensionalityReductionLearning + DEPENDS + OTBCommon + OTBITK + OTBShark + OTBBoost + OTBSOM + OTBLearningBase + + TEST_DEPENDS + OTBTestKernel + + DESCRIPTION + "${DOCUMENTATION}" +) diff --git a/Modules/Learning/DimensionalityReductionLearning/test/CMakeLists.txt b/Modules/Learning/DimensionalityReductionLearning/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e51906297744b458c625bcc8b0d78f65a67a529a --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/CMakeLists.txt @@ -0,0 +1,102 @@ +# +# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) +# +# This file is part of Orfeo Toolbox +# +# https://www.orfeo-toolbox.org/ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +otb_module_test() + +set(OTBDimensionalityReductionLearningTests +otbDimensionalityReductionLearningTestDriver.cxx +otbAutoencoderModelTest.cxx +otbPCAModelTest.cxx +otbSOMModelTest.cxx +) + +add_executable(otbDimensionalityReductionLearningTestDriver ${OTBDimensionalityReductionLearningTests}) +target_link_libraries(otbDimensionalityReductionLearningTestDriver ${OTBDimensionalityReductionLearning-Test_LIBRARIES}) +otb_module_target_label(otbDimensionalityReductionLearningTestDriver) + +# Tests Declaration +# --------------- Autoencoder -------------------------------- +otb_add_test(NAME leTuAutoencoderModelNew COMMAND + otbDimensionalityReductionLearningTestDriver + otbAutoencoderModelNew + ) + +otb_add_test(NAME leTvAutoencoderModelTrain COMMAND + otbDimensionalityReductionLearningTestDriver + otbAutoencoderModeTrain + ${INPUTDATA}/letter_light.scale + ${TEMP}/model.ae + ) + +otb_add_test(NAME leTvAutoencoderModelCanRead COMMAND + otbDimensionalityReductionLearningTestDriver + otbAutoencoderModelCanRead + ${TEMP}/model.ae + ) + +set_property(TEST leTvAutoencoderModelCanRead APPEND PROPERTY DEPENDS leTvAutoencoderModelTrain) + +# --------------- PCA -------------------------------- +otb_add_test(NAME leTuPCAModelNew COMMAND + otbDimensionalityReductionLearningTestDriver + otbPCAModelNew + ) + +otb_add_test(NAME leTvPCAModelTrain COMMAND + otbDimensionalityReductionLearningTestDriver + otbPCAModeTrain + ${INPUTDATA}/letter_light.scale + ${TEMP}/model.pca + ) + +otb_add_test(NAME leTvPCAModelCanRead COMMAND + otbDimensionalityReductionLearningTestDriver + otbPCAModelCanRead + ${TEMP}/model.pca + ) + +set_property(TEST leTvPCAModelCanRead APPEND PROPERTY DEPENDS leTvPCAModelTrain) + +# --------------- SOM -------------------------------- +otb_add_test(NAME leTuSOMModelNew COMMAND + otbDimensionalityReductionLearningTestDriver + otbSOMModelNew + ) + +otb_add_test(NAME leTvSOMModelTrain COMMAND + otbDimensionalityReductionLearningTestDriver + otbSOMModeTrain + ${INPUTDATA}/letter_light.scale + ${TEMP}/model2D.som + ${TEMP}/model3D.som + ${TEMP}/model4D.som + ${TEMP}/model5D.som + ) + +otb_add_test(NAME leTvSOMModelCanRead COMMAND + otbDimensionalityReductionLearningTestDriver + otbSOMModelCanRead + ${TEMP}/model2D.som + ${TEMP}/model3D.som + ${TEMP}/model4D.som + ${TEMP}/model5D.som + ) + +set_property(TEST leTvSOMModelCanRead APPEND PROPERTY DEPENDS leTvSOMModelTrain) diff --git a/Modules/Learning/DimensionalityReductionLearning/test/otbAutoencoderModelTest.cxx b/Modules/Learning/DimensionalityReductionLearning/test/otbAutoencoderModelTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ad3880f6f54b9e4fb234d4d3a9297a2918c02d27 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/otbAutoencoderModelTest.cxx @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbAutoencoderModel.h" +#include "otbReadDataFile.h" +#include "itkMacro.h" + +typedef otb::AutoencoderModel<double, shark::LogisticNeuron> LogAutoencoderModel; +typedef LogAutoencoderModel::InputListSampleType InputListSampleType; +typedef LogAutoencoderModel::TargetListSampleType TargetListSampleType; + +int otbAutoencoderModelNew(int itkNotUsed(argc), char * itkNotUsed(argv) []) +{ + LogAutoencoderModel::Pointer model = LogAutoencoderModel::New(); + + return EXIT_SUCCESS; +} + +int otbAutoencoderModelCanRead(int argc, char * argv []) +{ + if (argc < 2) + { + std::cerr << "Usage: " << argv[0] << " <model>" << std::endl; + return EXIT_FAILURE; + } + + LogAutoencoderModel::Pointer model = LogAutoencoderModel::New(); + std::string filename(argv[1]); + if (! model->CanReadFile(filename) ) + { + std::cerr << "Failed to read model file : "<< filename << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int otbAutoencoderModeTrain(int argc, char * argv []) +{ + if (argc < 3) + { + std::cerr << "Usage: " << argv[0] << " letter.scale model.out" << std::endl; + return EXIT_FAILURE; + } + + // Extract data from letter.scale + InputListSampleType::Pointer samples = InputListSampleType::New(); + TargetListSampleType::Pointer target = TargetListSampleType::New(); + if (!otb::ReadDataFile(argv[1], samples, target)) + { + std::cout << "Failed to read samples file " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + itk::Array<unsigned int> nb_neuron; + itk::Array<float> noise; + itk::Array<float> regularization; + itk::Array<float> rho; + itk::Array<float> beta; + + nb_neuron.SetSize(1); + noise.SetSize(1); + regularization.SetSize(1); + rho.SetSize(1); + beta.SetSize(1); + + nb_neuron[0] = 14; + noise[0] = 0.0; + regularization[0] = 0.01; + rho[0] = 0.0; + beta[0] = 0.0; + + LogAutoencoderModel::Pointer model = LogAutoencoderModel::New(); + model->SetNumberOfHiddenNeurons(nb_neuron); + model->SetNumberOfIterations(50); + model->SetNumberOfIterationsFineTuning(0); + model->SetEpsilon(0.0); + model->SetInitFactor(1.0); + model->SetRegularization(regularization); + model->SetNoise(noise); + model->SetRho(rho); + model->SetBeta(beta); + model->SetWriteWeights(true); + model->SetInputListSample(samples); + model->Train(); + model->Save(std::string(argv[2])); + + return EXIT_SUCCESS; +} diff --git a/Modules/Learning/DimensionalityReductionLearning/test/otbDimensionalityReductionLearningTestDriver.cxx b/Modules/Learning/DimensionalityReductionLearning/test/otbDimensionalityReductionLearningTestDriver.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6e0c644798e2501bbc77a3c7dc3a28c55b87f5d8 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/otbDimensionalityReductionLearningTestDriver.cxx @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbTestMain.h" + +void RegisterTests() +{ + REGISTER_TEST(otbAutoencoderModelNew); + REGISTER_TEST(otbAutoencoderModelCanRead); + REGISTER_TEST(otbAutoencoderModeTrain); + REGISTER_TEST(otbPCAModelNew); + REGISTER_TEST(otbPCAModelCanRead); + REGISTER_TEST(otbPCAModeTrain); + REGISTER_TEST(otbSOMModelNew); + REGISTER_TEST(otbSOMModelCanRead); + REGISTER_TEST(otbSOMModeTrain); +} diff --git a/Modules/Learning/DimensionalityReductionLearning/test/otbImageDimensionalityReductionFilterTest.cxx b/Modules/Learning/DimensionalityReductionLearning/test/otbImageDimensionalityReductionFilterTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a2b8da9d9a15553f2681fa732d90711d1b24306f --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/otbImageDimensionalityReductionFilterTest.cxx @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/Modules/Learning/DimensionalityReductionLearning/test/otbPCAModelTest.cxx b/Modules/Learning/DimensionalityReductionLearning/test/otbPCAModelTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6fe3945e43729e464de4f264025dd78fb8610e16 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/otbPCAModelTest.cxx @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbPCAModel.h" +#include "otbReadDataFile.h" + +typedef otb::PCAModel<double> PCAModelType; +typedef PCAModelType::InputListSampleType InputListSampleType; +typedef PCAModelType::TargetListSampleType TargetListSampleType; + +int otbPCAModelNew(int itkNotUsed(argc), char * itkNotUsed(argv) []) +{ + PCAModelType::Pointer model = PCAModelType::New(); + + return EXIT_SUCCESS; +} + +int otbPCAModelCanRead(int argc, char * argv []) +{ + if (argc < 2) + { + std::cerr << "Usage: " << argv[0] << " <model>" << std::endl; + return EXIT_FAILURE; + } + + PCAModelType::Pointer model = PCAModelType::New(); + std::string filename(argv[1]); + if (! model->CanReadFile(filename) ) + { + std::cerr << "Failed to read model file : "<< filename << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int otbPCAModeTrain(int argc, char * argv []) +{ + if (argc < 3) + { + std::cerr << "Usage: " << argv[0] << " letter.scale model.out" << std::endl; + return EXIT_FAILURE; + } + + // Extract data from letter.scale + InputListSampleType::Pointer samples = InputListSampleType::New(); + TargetListSampleType::Pointer target = TargetListSampleType::New(); + if (!otb::ReadDataFile(argv[1], samples, target)) + { + std::cout << "Failed to read samples file " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + PCAModelType::Pointer model = PCAModelType::New(); + model->SetDimension(14); + model->SetWriteEigenvectors(true); + model->SetInputListSample(samples); + model->Train(); + model->Save(std::string(argv[2])); + + return EXIT_SUCCESS; +} diff --git a/Modules/Learning/DimensionalityReductionLearning/test/otbSOMModelTest.cxx b/Modules/Learning/DimensionalityReductionLearning/test/otbSOMModelTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..092cac8404ced25b8a106e5ac5037bbaa06ced71 --- /dev/null +++ b/Modules/Learning/DimensionalityReductionLearning/test/otbSOMModelTest.cxx @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbSOMModel.h" +#include "otbReadDataFile.h" + +typedef otb::SOMModel<double,2> SOMModel2D; +typedef otb::SOMModel<double,3> SOMModel3D; +typedef otb::SOMModel<double,4> SOMModel4D; +typedef otb::SOMModel<double,5> SOMModel5D; + +typedef SOMModel2D::InputListSampleType InputListSampleType; +typedef SOMModel2D::TargetListSampleType TargetListSampleType; + +int otbSOMModelNew(int itkNotUsed(argc), char * itkNotUsed(argv) []) +{ + SOMModel2D::Pointer model2D = SOMModel2D::New(); + SOMModel3D::Pointer model3D = SOMModel3D::New(); + SOMModel4D::Pointer model4D = SOMModel4D::New(); + SOMModel5D::Pointer model5D = SOMModel5D::New(); + + return EXIT_SUCCESS; +} + +int otbSOMModelCanRead(int argc, char * argv []) +{ + if (argc < 2) + { + std::cerr << "Usage: " << argv[0] << " <model2D> <model3D> <model4D> <model5D>" << std::endl; + return EXIT_FAILURE; + } + + std::string filename2D(argv[1]); + std::string filename3D(argv[2]); + std::string filename4D(argv[3]); + std::string filename5D(argv[4]); + + SOMModel2D::Pointer model2D = SOMModel2D::New(); + SOMModel3D::Pointer model3D = SOMModel3D::New(); + SOMModel4D::Pointer model4D = SOMModel4D::New(); + SOMModel5D::Pointer model5D = SOMModel5D::New(); + + if (! model2D->CanReadFile(filename2D) ) + { + std::cerr << "Failed to read model file : "<< filename2D << std::endl; + return EXIT_FAILURE; + } + if (! model3D->CanReadFile(filename3D) ) + { + std::cerr << "Failed to read model file : "<< filename3D << std::endl; + return EXIT_FAILURE; + } + if (! model4D->CanReadFile(filename4D) ) + { + std::cerr << "Failed to read model file : "<< filename4D << std::endl; + return EXIT_FAILURE; + } + if (! model5D->CanReadFile(filename5D) ) + { + std::cerr << "Failed to read model file : "<< filename5D << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int otbSOMModeTrain(int argc, char * argv []) +{ + if (argc < 3) + { + std::cerr << "Usage: " << argv[0] << " letter.scale model2D.out model3D.out model4D.out model5D.out" << std::endl; + return EXIT_FAILURE; + } + + // Extract data from letter.scale + InputListSampleType::Pointer samples = InputListSampleType::New(); + TargetListSampleType::Pointer target = TargetListSampleType::New(); + if (!otb::ReadDataFile(argv[1], samples, target)) + { + std::cout << "Failed to read samples file " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + SOMModel2D::Pointer model2D = SOMModel2D::New(); + SOMModel3D::Pointer model3D = SOMModel3D::New(); + SOMModel4D::Pointer model4D = SOMModel4D::New(); + SOMModel5D::Pointer model5D = SOMModel5D::New(); + + SOMModel2D::SizeType size2D, radius2D; + size2D.Fill(10); + radius2D.Fill(3); + SOMModel3D::SizeType size3D, radius3D; + size3D.Fill(6); + radius3D.Fill(3); + SOMModel4D::SizeType size4D, radius4D; + size4D.Fill(4); + radius4D.Fill(2); + SOMModel5D::SizeType size5D, radius5D; + size5D.Fill(3); + radius5D.Fill(2); + + std::cout << "Train 2D model..."<< std::endl; + model2D->SetNumberOfIterations(10); + model2D->SetBetaInit(1.0); + model2D->SetWriteMap(true); + model2D->SetBetaEnd(0.1); + model2D->SetMaxWeight(10.0); + model2D->SetMapSize(size2D); + model2D->SetNeighborhoodSizeInit(radius2D); + model2D->SetInputListSample(samples); + model2D->Train(); + model2D->Save(std::string(argv[2])); + + std::cout << "Train 3D model..."<< std::endl; + model3D->SetNumberOfIterations(10); + model3D->SetBetaInit(1.0); + model3D->SetWriteMap(true); + model3D->SetBetaEnd(0.1); + model3D->SetMaxWeight(10.0); + model3D->SetMapSize(size3D); + model3D->SetNeighborhoodSizeInit(radius3D); + model3D->SetInputListSample(samples); + model3D->Train(); + model3D->Save(std::string(argv[3])); + + std::cout << "Train 4D model..."<< std::endl; + model4D->SetNumberOfIterations(10); + model4D->SetBetaInit(1.0); + model4D->SetWriteMap(true); + model4D->SetBetaEnd(0.1); + model4D->SetMaxWeight(10.0); + model4D->SetMapSize(size4D); + model4D->SetNeighborhoodSizeInit(radius4D); + model4D->SetInputListSample(samples); + model4D->Train(); + model4D->Save(std::string(argv[4])); + + std::cout << "Train 5D model..."<< std::endl; + model5D->SetNumberOfIterations(10); + model5D->SetBetaInit(1.0); + model5D->SetWriteMap(true); + model5D->SetBetaEnd(0.1); + model5D->SetMaxWeight(10.0); + model5D->SetMapSize(size5D); + model5D->SetNeighborhoodSizeInit(radius5D); + model5D->SetInputListSample(samples); + model5D->Train(); + model5D->Save(std::string(argv[5])); + + return EXIT_SUCCESS; +} + diff --git a/Modules/Learning/LearningBase/CMakeLists.txt b/Modules/Learning/LearningBase/CMakeLists.txt index b3460da963ae8c229aee0b34e3120fb27d27d6ec..45b573a3dc2006a8f638f7b81a80880adebc334a 100644 --- a/Modules/Learning/LearningBase/CMakeLists.txt +++ b/Modules/Learning/LearningBase/CMakeLists.txt @@ -20,4 +20,6 @@ project(OTBLearningBase) +set(OTBLearningBase_LIBRARIES OTBLearningBase) + otb_module_impl() diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModel.h b/Modules/Learning/LearningBase/include/otbMachineLearningModel.h index 552880cb9a83a4e43b7e29ae75689613633e5ef0..2bfd9177ff00feda39a6c251dc62cb7e75706733 100644 --- a/Modules/Learning/LearningBase/include/otbMachineLearningModel.h +++ b/Modules/Learning/LearningBase/include/otbMachineLearningModel.h @@ -116,7 +116,11 @@ public: */ TargetSampleType Predict(const InputSampleType& input, ConfidenceValueType *quality = ITK_NULLPTR) const; - + /**\name Set and get the dimension of the model for dimensionality reduction models */ + //@{ + itkSetMacro(Dimension,unsigned int); + itkGetMacro(Dimension,unsigned int); + //@} /** Predict a batch of samples (InputListSampleType) * \param input The batch of sample to predict @@ -128,29 +132,29 @@ public: */ typename TargetListSampleType::Pointer PredictBatch(const InputListSampleType * input, ConfidenceListSampleType * quality = ITK_NULLPTR) const; - /**\name Classification model file manipulation */ - //@{ - /** Save the model to file */ +/**\name Classification model file manipulation */ +//@{ +/** Save the model to file */ virtual void Save(const std::string & filename, const std::string & name="") = 0; - /** Load the model from file */ +/** Load the model from file */ virtual void Load(const std::string & filename, const std::string & name="") = 0; - //@} +//@} - /**\name Classification model file compatibility tests */ - //@{ - /** Is the input model file readable and compatible with the corresponding classifier ? */ +/**\name Classification model file compatibility tests */ +//@{ +/** Is the input model file readable and compatible with the corresponding classifier ? */ virtual bool CanReadFile(const std::string &) = 0; - /** Is the input model file writable and compatible with the corresponding classifier ? */ +/** Is the input model file writable and compatible with the corresponding classifier ? */ virtual bool CanWriteFile(const std::string &) = 0; - //@} +//@} - /** Query capacity to produce a confidence index */ +/** Query capacity to produce a confidence index */ bool HasConfidenceIndex() const {return m_ConfidenceIndex;} - /**\name Input list of samples accessors */ - //@{ +/**\name Input list of samples accessors */ +//@{ itkSetObjectMacro(InputListSample,InputListSampleType); itkGetObjectMacro(InputListSample,InputListSampleType); itkGetConstObjectMacro(InputListSample,InputListSampleType); @@ -185,6 +189,9 @@ protected: /** Input list sample */ typename InputListSampleType::Pointer m_InputListSample; + /** Validation list sample if provided for some models */ + typename InputListSampleType::Pointer m_ValidationListSample; + /** Target list sample */ typename TargetListSampleType::Pointer m_TargetListSample; @@ -192,7 +199,7 @@ protected: /** flag to choose between classification and regression modes */ bool m_RegressionMode; - + /** flag that indicates if the model supports regression, child * classes should modify it in their constructor if they support * regression mode */ @@ -203,6 +210,9 @@ protected: /** Is DoPredictBatch multi-threaded ? */ bool m_IsDoPredictBatchMultiThreaded; + + /** Output Dimension of the model, used by Dimensionality Reduction models*/ + unsigned int m_Dimension; private: /** Actual implementation of BatchPredicition diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx b/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx index 00da0413879e83f013cf98053413e81dbcac0193..a983cb2fa0aaa6f6b0a7d7747e0ee1e0ac7636a5 100644 --- a/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx +++ b/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx @@ -38,7 +38,8 @@ MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> m_RegressionMode(false), m_IsRegressionSupported(false), m_ConfidenceIndex(false), - m_IsDoPredictBatchMultiThreaded(false) + m_IsDoPredictBatchMultiThreaded(false), + m_Dimension(0) {} @@ -98,11 +99,11 @@ MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> else { - #ifdef _OPENMP +#ifdef _OPENMP // OpenMP threading here unsigned int nb_threads(0), threadId(0), nb_batches(0); - #pragma omp parallel shared(nb_threads,nb_batches) private(threadId) +#pragma omp parallel shared(nb_threads,nb_batches) private(threadId) { // Get number of threads configured with ITK omp_set_num_threads(itk::MultiThreader::GetGlobalDefaultNumberOfThreads()); @@ -122,9 +123,9 @@ MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> this->DoPredictBatch(input,batch_start,batch_size,targets,quality); } } - #else +#else this->DoPredictBatch(input,0,input->Size(),targets,quality); - #endif +#endif return targets; } } @@ -169,12 +170,12 @@ MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> template <class TInputValue, class TOutputValue, class TConfidenceValue> void -MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> -::PrintSelf(std::ostream& os, itk::Indent indent) const -{ - // Call superclass implementation - Superclass::PrintSelf(os,indent); -} -} + MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue> + ::PrintSelf(std::ostream& os, itk::Indent indent) const + { + // Call superclass implementation + Superclass::PrintSelf(os,indent); + } + } #endif diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModelFactoryBase.h b/Modules/Learning/LearningBase/include/otbMachineLearningModelFactoryBase.h index 0ca61f2c37483d0735c146f9355b4a4a8d4c5d35..012e0f1d77935bf1fffaed129bebcf8a8492368f 100644 --- a/Modules/Learning/LearningBase/include/otbMachineLearningModelFactoryBase.h +++ b/Modules/Learning/LearningBase/include/otbMachineLearningModelFactoryBase.h @@ -22,7 +22,7 @@ #define otbMachineLearningModelFactoryBase_h #include "itkMutexLock.h" -#include "OTBSupervisedExport.h" +#include "OTBLearningBaseExport.h" namespace otb { @@ -34,7 +34,7 @@ namespace otb * * \ingroup OTBLearningBase */ -class OTBSupervised_EXPORT MachineLearningModelFactoryBase : public itk::Object +class OTBLearningBase_EXPORT MachineLearningModelFactoryBase : public itk::Object { public: /** Standard class typedefs. */ diff --git a/Modules/Learning/LearningBase/otb-module.cmake b/Modules/Learning/LearningBase/otb-module.cmake index b4fab23bbaec200852575ff64dbb2424475542c6..afa2a339a1813cf16e5f6ea3700f079a36180dcd 100644 --- a/Modules/Learning/LearningBase/otb-module.cmake +++ b/Modules/Learning/LearningBase/otb-module.cmake @@ -22,19 +22,15 @@ set(DOCUMENTATION "This module contains OTB generic Machine Learning framework mainly based on OpenCV.") otb_module(OTBLearningBase + ENABLE_SHARED DEPENDS OTBCommon - OTBITK - OTBImageIO OTBImageBase - - OPTIONAL_DEPENDS - OTBShark + OTBITK TEST_DEPENDS OTBTestKernel OTBImageIO - OTBImageBase DESCRIPTION "${DOCUMENTATION}" diff --git a/Modules/Learning/LearningBase/src/CMakeLists.txt b/Modules/Learning/LearningBase/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4a7ef1c0d25c764f375e5b6fc3652efd2c430963 --- /dev/null +++ b/Modules/Learning/LearningBase/src/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) +# +# This file is part of Orfeo Toolbox +# +# https://www.orfeo-toolbox.org/ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set(OTBLearningBase_SRC + otbMachineLearningModelFactoryBase.cxx + ) + +add_library(OTBLearningBase ${OTBLearningBase_SRC}) +target_link_libraries(OTBLearningBase + ${OTBCommon_LIBRARIES} + ${OTBImageBase_LIBRARIES} + ${OTBITK_LIBRARIES} + ) + +otb_module_target(OTBLearningBase) diff --git a/Modules/Learning/Supervised/src/otbMachineLearningModelFactoryBase.cxx b/Modules/Learning/LearningBase/src/otbMachineLearningModelFactoryBase.cxx similarity index 100% rename from Modules/Learning/Supervised/src/otbMachineLearningModelFactoryBase.cxx rename to Modules/Learning/LearningBase/src/otbMachineLearningModelFactoryBase.cxx diff --git a/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.txx b/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.txx index 2b14f6dca92ebe4c97d4305b16afe744e5635944..1d1c03e39a67864cbcbe81c014c4a97d7aca59df 100644 --- a/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.txx +++ b/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.txx @@ -66,7 +66,7 @@ LibSVMMachineLearningModel<TInputValue,TOutputValue> this->m_Problem.l = 0; this->m_Problem.y = ITK_NULLPTR; this->m_Problem.x = ITK_NULLPTR; -#ifndef OTB_SHOW_ALL_MSG_DEBUG +#ifndef NDEBUG svm_set_print_string_function(&otb::Utils::PrintNothing); #endif } diff --git a/Modules/Learning/Supervised/src/CMakeLists.txt b/Modules/Learning/Supervised/src/CMakeLists.txt index 7a3c77b3a7e2992216d16f444178abb697424dc0..45e881904bbbf61bec7bb8a158f8661806d64896 100644 --- a/Modules/Learning/Supervised/src/CMakeLists.txt +++ b/Modules/Learning/Supervised/src/CMakeLists.txt @@ -19,7 +19,6 @@ # set(OTBSupervised_SRC - otbMachineLearningModelFactoryBase.cxx otbExhaustiveExponentialOptimizer.cxx ) @@ -33,6 +32,7 @@ target_link_libraries(OTBSupervised ${OTBLibSVM_LIBRARIES} ${OTBOpenCV_LIBRARIES} ${OTBShark_LIBRARIES} + ${OTBLearningBase_LIBRARIES} ) otb_module_target(OTBSupervised) diff --git a/Modules/Learning/Supervised/test/otbTrainMachineLearningModel.cxx b/Modules/Learning/Supervised/test/otbTrainMachineLearningModel.cxx index 0633cd0f53a7acbf991cf2d727b1e766c9a753a3..dd34b41b8b3a4f9711530f99892f5780515e2566 100644 --- a/Modules/Learning/Supervised/test/otbTrainMachineLearningModel.cxx +++ b/Modules/Learning/Supervised/test/otbTrainMachineLearningModel.cxx @@ -26,6 +26,8 @@ #include <otbMachineLearningModel.h> #include "otbConfusionMatrixCalculator.h" +#include "otbReadDataFile.h" + #include "otb_boost_string_header.h" typedef otb::MachineLearningModel<float,short> MachineLearningModelType; @@ -46,142 +48,6 @@ typedef MachineLearningModelRegressionType::TargetListSampleType TargetListSampl typedef otb::ConfusionMatrixCalculator<TargetListSampleType, TargetListSampleType> ConfusionMatrixCalculatorType; -bool ReadDataFile(const std::string & infname, InputListSampleType * samples, TargetListSampleType * labels) -{ - std::ifstream ifs; - ifs.open(infname.c_str()); - - if(!ifs) - { - std::cout<<"Could not read file "<<infname<<std::endl; - return false; - } - - unsigned int nbfeatures = 0; - - while (!ifs.eof()) - { - std::string line; - std::getline(ifs, line); - boost::algorithm::trim(line); - - if(nbfeatures == 0) - { - nbfeatures = std::count(line.begin(),line.end(),' '); - } - - if(line.size()>1) - { - InputSampleType sample(nbfeatures); - sample.Fill(0); - - std::string::size_type pos = line.find_first_of(" ", 0); - - // Parse label - TargetSampleType label; - label[0] = atoi(line.substr(0, pos).c_str()); - - bool endOfLine = false; - unsigned int id = 0; - - while(!endOfLine) - { - std::string::size_type nextpos = line.find_first_of(" ", pos+1); - - if(pos == std::string::npos) - { - endOfLine = true; - nextpos = line.size()-1; - } - else - { - std::string feature = line.substr(pos,nextpos-pos); - std::string::size_type semicolonpos = feature.find_first_of(":"); - id = atoi(feature.substr(0,semicolonpos).c_str()); - sample[id - 1] = atof(feature.substr(semicolonpos+1,feature.size()-semicolonpos).c_str()); - pos = nextpos; - } - - } - samples->SetMeasurementVectorSize(itk::NumericTraits<InputSampleType>::GetLength(sample)); - samples->PushBack(sample); - labels->PushBack(label); - } - } - - //std::cout<<"Retrieved "<<samples->Size()<<" samples"<<std::endl; - ifs.close(); - return true; -} - -bool ReadDataRegressionFile(const std::string & infname, InputListSampleRegressionType * samples, TargetListSampleRegressionType * labels) -{ - std::ifstream ifs; - ifs.open(infname.c_str()); - - if(!ifs) - { - std::cout<<"Could not read file "<<infname<<std::endl; - return false; - } - - unsigned int nbfeatures = 0; - - while (!ifs.eof()) - { - std::string line; - std::getline(ifs, line); - - if(nbfeatures == 0) - { - nbfeatures = std::count(line.begin(),line.end(),' ')-1; - //std::cout<<"Found "<<nbfeatures<<" features per samples"<<std::endl; - } - - if(line.size()>1) - { - InputSampleRegressionType sample(nbfeatures); - sample.Fill(0); - - std::string::size_type pos = line.find_first_of(" ", 0); - - // Parse label - TargetSampleRegressionType label; - label[0] = atof(line.substr(0, pos).c_str()); - - bool endOfLine = false; - unsigned int id = 0; - - while(!endOfLine) - { - std::string::size_type nextpos = line.find_first_of(" ", pos+1); - - if(nextpos == std::string::npos) - { - endOfLine = true; - nextpos = line.size()-1; - } - else - { - std::string feature = line.substr(pos,nextpos-pos); - std::string::size_type semicolonpos = feature.find_first_of(":"); - id = atoi(feature.substr(0,semicolonpos).c_str()); - sample[id - 1] = atof(feature.substr(semicolonpos+1,feature.size()-semicolonpos).c_str()); - pos = nextpos; - } - - } - samples->SetMeasurementVectorSize(itk::NumericTraits<InputSampleRegressionType>::GetLength(sample)); - samples->PushBack(sample); - labels->PushBack(label); - } - } - - //std::cout<<"Retrieved "<<samples->Size()<<" samples"<<std::endl; - ifs.close(); - return true; -} - #ifdef OTB_USE_LIBSVM #include "otbLibSVMMachineLearningModel.h" int otbLibSVMMachineLearningModelNew(int itkNotUsed(argc), char * itkNotUsed(argv) []) @@ -205,7 +71,7 @@ int otbLibSVMMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if (!ReadDataFile(argv[1], samples, labels)) + if (!otb::ReadDataFile(argv[1], samples, labels)) { std::cout << "Failed to read samples file " << argv[1] << std::endl; return EXIT_FAILURE; @@ -294,7 +160,7 @@ int otbSVMMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -364,7 +230,7 @@ int otbSVMMachineLearningRegressionModel(int argc, char * argv[]) InputListSampleRegressionType::Pointer samples = InputListSampleRegressionType::New(); TargetListSampleRegressionType::Pointer labels = TargetListSampleRegressionType::New(); - if(!ReadDataRegressionFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -439,7 +305,7 @@ int otbKNearestNeighborsMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -516,7 +382,7 @@ int otbRandomForestsMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -603,7 +469,7 @@ int otbBoostMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -689,7 +555,7 @@ int otbANNMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if (!ReadDataFile(argv[1], samples, labels)) + if (!otb::ReadDataFile(argv[1], samples, labels)) { std::cout << "Failed to read samples file " << argv[1] << std::endl; return EXIT_FAILURE; @@ -779,7 +645,7 @@ int otbNormalBayesMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -856,7 +722,7 @@ int otbDecisionTreeMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -934,7 +800,7 @@ int otbGradientBoostedTreeMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!ReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; @@ -995,139 +861,6 @@ int otbGradientBoostedTreeMachineLearningModel(int argc, char * argv[]) #ifdef OTB_USE_SHARK #include <chrono> // If shark is on, then we are using c++11 -bool SharkReadDataFile(const std::string & infname, InputListSampleType * samples, TargetListSampleType * labels) -{ - std::ifstream ifs(infname.c_str()); - - if(!ifs) - { - std::cout<<"Could not read file "<<infname<<std::endl; - return false; - } - - unsigned int nbfeatures = 0; - - std::string line; - while (std::getline(ifs, line)) - { - boost::algorithm::trim(line); - - if(nbfeatures == 0) - { - nbfeatures = std::count(line.begin(),line.end(),' '); - } - - if(line.size()>1) - { - InputSampleType sample(nbfeatures); - sample.Fill(0); - - std::string::size_type pos = line.find_first_of(" ", 0); - - // Parse label - TargetSampleType label; - label[0] = std::stoi(line.substr(0, pos).c_str()); - - bool endOfLine = false; - unsigned int id = 0; - - while(!endOfLine) - { - std::string::size_type nextpos = line.find_first_of(" ", pos+1); - - if(pos == std::string::npos) - { - endOfLine = true; - nextpos = line.size()-1; - } - else - { - std::string feature = line.substr(pos,nextpos-pos); - std::string::size_type semicolonpos = feature.find_first_of(":"); - id = std::stoi(feature.substr(0,semicolonpos).c_str()); - sample[id - 1] = atof(feature.substr(semicolonpos+1,feature.size()-semicolonpos).c_str()); - pos = nextpos; - } - - } - samples->SetMeasurementVectorSize(itk::NumericTraits<InputSampleType>::GetLength(sample)); - samples->PushBack(sample); - labels->PushBack(label); - } - } - - //std::cout<<"Retrieved "<<samples->Size()<<" samples"<<std::endl; - ifs.close(); - return true; -} - -bool SharkReadDataRegressionFile(const std::string & infname, InputListSampleRegressionType * samples, TargetListSampleRegressionType * labels) -{ - std::ifstream ifs(infname.c_str()); - if(!ifs) - { - std::cout<<"Could not read file "<<infname<<std::endl; - return false; - } - - unsigned int nbfeatures = 0; - - while (!ifs.eof()) - { - std::string line; - std::getline(ifs, line); - - if(nbfeatures == 0) - { - nbfeatures = std::count(line.begin(),line.end(),' ')-1; - //std::cout<<"Found "<<nbfeatures<<" features per samples"<<std::endl; - } - - if(line.size()>1) - { - InputSampleRegressionType sample(nbfeatures); - sample.Fill(0); - - std::string::size_type pos = line.find_first_of(" ", 0); - - // Parse label - TargetSampleRegressionType label; - label[0] = atof(line.substr(0, pos).c_str()); - - bool endOfLine = false; - unsigned int id = 0; - - while(!endOfLine) - { - std::string::size_type nextpos = line.find_first_of(" ", pos+1); - - if(nextpos == std::string::npos) - { - endOfLine = true; - nextpos = line.size()-1; - } - else - { - std::string feature = line.substr(pos,nextpos-pos); - std::string::size_type semicolonpos = feature.find_first_of(":"); - id = std::stoi(feature.substr(0,semicolonpos).c_str()); - sample[id - 1] = atof(feature.substr(semicolonpos+1,feature.size()-semicolonpos).c_str()); - pos = nextpos; - } - - } - samples->SetMeasurementVectorSize(itk::NumericTraits<InputSampleRegressionType>::GetLength(sample)); - samples->PushBack(sample); - labels->PushBack(label); - } - } - - //std::cout<<"Retrieved "<<samples->Size()<<" samples"<<std::endl; - ifs.close(); - return true; -} - - #include "otbSharkRandomForestsMachineLearningModel.h" int otbSharkRFMachineLearningModelNew(int itkNotUsed(argc), char * itkNotUsed(argv) []) { @@ -1149,7 +882,7 @@ int otbSharkRFMachineLearningModel(int argc, char * argv[]) InputListSampleType::Pointer samples = InputListSampleType::New(); TargetListSampleType::Pointer labels = TargetListSampleType::New(); - if(!SharkReadDataFile(argv[1],samples,labels)) + if(!otb::ReadDataFile(argv[1],samples,labels)) { std::cout<<"Failed to read samples file "<<argv[1]<<std::endl; return EXIT_FAILURE; diff --git a/Modules/Learning/Supervised/test/tests-libsvm.cmake b/Modules/Learning/Supervised/test/tests-libsvm.cmake index bbf6647ab09866b3074d840a84e301f9956bc48f..03b5118cd9ffb9eb538df0efe8452ccd0fff30cc 100644 --- a/Modules/Learning/Supervised/test/tests-libsvm.cmake +++ b/Modules/Learning/Supervised/test/tests-libsvm.cmake @@ -20,7 +20,7 @@ otb_add_test(NAME leTvLibSVMMachineLearningModel COMMAND otbSupervisedTestDriver otbLibSVMMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/libsvm_model.txt ) otb_add_test(NAME leTuLibSVMMachineLearningModelNew COMMAND otbSupervisedTestDriver diff --git a/Modules/Learning/Supervised/test/tests-opencv.cmake b/Modules/Learning/Supervised/test/tests-opencv.cmake index a309c341dc2b06f83d53b4a4aeab2305b9cf68a1..f898971f56ffc964adf8f1a352a3628fc7ba6990 100644 --- a/Modules/Learning/Supervised/test/tests-opencv.cmake +++ b/Modules/Learning/Supervised/test/tests-opencv.cmake @@ -26,7 +26,7 @@ otb_add_test(NAME leTuRandomForestsMachineLearningModelNew COMMAND otbSupervised otb_add_test(NAME leTvANNMachineLearningModel COMMAND otbSupervisedTestDriver otbANNMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/ann_model.txt ) @@ -74,7 +74,7 @@ otb_add_test(NAME leTvSVMMachineLearningRegressionModel COMMAND otbSupervisedTes otb_add_test(NAME leTvSVMMachineLearningModel COMMAND otbSupervisedTestDriver otbSVMMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/svm_model.txt ) @@ -83,14 +83,14 @@ otb_add_test(NAME leTuBoostMachineLearningModelNew COMMAND otbSupervisedTestDriv otb_add_test(NAME leTvNormalBayesMachineLearningModel COMMAND otbSupervisedTestDriver otbNormalBayesMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/normalbayes_model.txt ) if(NOT OTB_OPENCV_3) otb_add_test(NAME leTvGradientBoostedTreeMachineLearningModel COMMAND otbSupervisedTestDriver otbGradientBoostedTreeMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/gbt_model.txt ) otb_add_test(NAME leTuGradientBoostedTreeMachineLearningModelNew COMMAND otbSupervisedTestDriver @@ -99,7 +99,7 @@ endif() otb_add_test(NAME leTvRandomForestsMachineLearningModel COMMAND otbSupervisedTestDriver otbRandomForestsMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/rf_model.txt ) @@ -108,19 +108,19 @@ otb_add_test(NAME leTuANNMachineLearningModelNew COMMAND otbSupervisedTestDriver otb_add_test(NAME leTvKNearestNeighborsMachineLearningModel COMMAND otbSupervisedTestDriver otbKNearestNeighborsMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/knn_model.txt ) otb_add_test(NAME leTvDecisionTreeMachineLearningModel COMMAND otbSupervisedTestDriver otbDecisionTreeMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/decisiontree_model.txt ) otb_add_test(NAME leTvBoostMachineLearningModel COMMAND otbSupervisedTestDriver otbBoostMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/boost_model.txt ) diff --git a/Modules/Learning/Supervised/test/tests-shark.cmake b/Modules/Learning/Supervised/test/tests-shark.cmake index eeda8fff3f9f1413dcffe868c3fb5f8cb4f8f6d0..546e826043b31d284840fc3bed69250b82ad6dfb 100644 --- a/Modules/Learning/Supervised/test/tests-shark.cmake +++ b/Modules/Learning/Supervised/test/tests-shark.cmake @@ -23,7 +23,7 @@ otb_add_test(NAME leTuSharkRFMachineLearningModelNew COMMAND otbSupervisedTestDr otb_add_test(NAME leTvSharkRFMachineLearningModel COMMAND otbSupervisedTestDriver otbSharkRFMachineLearningModel - ${INPUTDATA}/letter.scale + ${INPUTDATA}/letter_light.scale ${TEMP}/shark_rf_model.txt ) diff --git a/Modules/MPI/MPIConfig/CMakeLists.txt b/Modules/MPI/MPIConfig/CMakeLists.txt index ed0784dadc1e4d75f10b36a63995c0a1c44dea7b..dabc7a26acee81f883b8ec0a853fe959f3f38b97 100644 --- a/Modules/MPI/MPIConfig/CMakeLists.txt +++ b/Modules/MPI/MPIConfig/CMakeLists.txt @@ -19,9 +19,6 @@ # project(MPIConfig) -set(MPIConfig_LIBRARIES MPIConfig) - set(OTBMPIConfig_LIBRARIES OTBMPIConfig) otb_module_impl() - diff --git a/Modules/MPI/MPIConfig/README b/Modules/MPI/MPIConfig/README deleted file mode 100644 index e30ca8bb5c45886310a7eb0a9205db01e831b3b8..0000000000000000000000000000000000000000 --- a/Modules/MPI/MPIConfig/README +++ /dev/null @@ -1,71 +0,0 @@ -General -======= - -This is a template module for the ORFEO -Toolbox(https://www.orfeo-toolbox.org/). It is designed to work with OTBv5 -modular system and to be places in OTB/Module/Remote. - -This module is empty it is just a template to be used as a starting point for a -module with actual content. It contains the template for sources (src folder), -test (test folder) and application (app folder). - -Getting Started -=============== - -The official OTB Wiki documentation on adding an external module is here: -http://wiki.orfeo-toolbox.org/index.php/How_to_write_a_remote_module - -Remote Module -------------- - -After a module has been created as a git repository it can be included -as a remote module, which enables automatic fetching. Add a file in -"OTB/Modules/Remote" called "YourModule.remote.cmake", for this module -it would be "ExternalExample.remote.cmake" with the followlowing contents: - -otb_fetch_module(ExternalTemplate - "A template for a module." - GIT_REPOSITORY https://github.com/orfeotoolbox/otbExternalModuleTemplate - GIT_TAG master - ) - -Editing -======= - -The CMakeLists.txt and otb-modules need to be modified with the name of the -module, something along the following: - -sed 's/ExternalTemplate/MyModule/g' CMakeLists.txt otb-module.cmake - -There is the inplace option to sed, but it's not portable, so do this change by -hand or look up the option in sed. - -Then hack away at you code in include, src, test and app folders. - -License -======= - -This software is distributed under the Apache License. Please see LICENSE for -details. - -Author -====== - -Manuel Grizonnet - -Thanks -====== - -It is a fork of the ITK template module provided by Bradley Lowekamp -(https://github.com/blowekamp/itkExternalTemplate.git) which was adapted for the -ORFEO ToolBox. - -Compilation des tests -===================== -module load cmake/3.4.3 openmpi/1.10.2 otb/develop -cd build -rm -rf * -cmake -DCMAKE_CXX_FLAGS="-Wno-unused-local-typedefs -std=c++11" .. -make -ctest - diff --git a/Modules/Remote/otb-bv.remote.cmake b/Modules/Remote/otb-bv.remote.cmake index 06e067e6586cc345fed2d1f6aade487cf08350b3..739f46126b5c658ce1eb11dcd0d07879dfbbcc8d 100644 --- a/Modules/Remote/otb-bv.remote.cmake +++ b/Modules/Remote/otb-bv.remote.cmake @@ -22,8 +22,8 @@ otb_fetch_module(OTBBioVars "Biophysical variable estimation from remote sensing imagery. A more detailed description can be found on the project website: -http://tully.ups-tlse.fr/jordi/otb-bv +https://gitlab.orfeo-toolbox.org/jinglada/otb-bv " - GIT_REPOSITORY http://tully.ups-tlse.fr/jordi/otb-bv.git + GIT_REPOSITORY https://gitlab.orfeo-toolbox.org/jinglada/otb-bv.git GIT_TAG 0e56e487aebc4a493e25223960560e9ef0ca27ec ) diff --git a/Modules/Remote/phenotb.remote.cmake b/Modules/Remote/phenotb.remote.cmake index aa9e9a8ead204e1b3a4f8492e16825c838da95d7..74d83a9d96d04bd545ee5b02d4790fcac6ab6e3e 100644 --- a/Modules/Remote/phenotb.remote.cmake +++ b/Modules/Remote/phenotb.remote.cmake @@ -24,8 +24,8 @@ otb_fetch_module(OTBPhenology information from time profiles. These time profiles should represent vegetation status as for instance NDVI, LAI, etc. A more detailed description can be found on the project website: -http://tully.ups-tlse.fr/jordi/phenotb +https://gitlab.orfeo-toolbox.org/jinglada/phenotb " - GIT_REPOSITORY http://tully.ups-tlse.fr/jordi/phenotb.git + GIT_REPOSITORY https://gitlab.orfeo-toolbox.org/jinglada/phenotb.git GIT_TAG c9349eb89a652a18b28a40dfb3fa352b76388527 ) diff --git a/Modules/Remote/temporal-gapfilling.remote.cmake b/Modules/Remote/temporal-gapfilling.remote.cmake index 469a857fb8119f1564de992b6d0481f82920e61b..2dd788d21391a19390f40ac90ff3af1b5271311b 100644 --- a/Modules/Remote/temporal-gapfilling.remote.cmake +++ b/Modules/Remote/temporal-gapfilling.remote.cmake @@ -23,9 +23,9 @@ otb_fetch_module(OTBTemporalGapFilling "Gapfilling for time series replaces invalid pixels (as designated by a mask) by an interpolation using the valid dates of the series. A more detailed description can be found on the project website: -http://tully.ups-tlse.fr/jordi/temporalgapfilling +https://gitlab.orfeo-toolbox.org/jinglada/temporalgapfilling " - GIT_REPOSITORY http://tully.ups-tlse.fr/jordi/temporalgapfilling.git + GIT_REPOSITORY https://gitlab.orfeo-toolbox.org/jinglada/temporalgapfilling.git # Commit on develop branch which includes patches for Windows support GIT_TAG 4fc4a71acf7b9b051cda5a3b950de2cdb9d26287 ) diff --git a/Modules/Learning/LearningBase/include/otbSharkUtils.h b/Modules/ThirdParty/Shark/include/otbSharkUtils.h similarity index 87% rename from Modules/Learning/LearningBase/include/otbSharkUtils.h rename to Modules/ThirdParty/Shark/include/otbSharkUtils.h index 9efcf948bdbbfd7e9a672068677f029ac10c7d39..de3adf77401d0f131d2bd7d447627829b3df64ff 100644 --- a/Modules/Learning/LearningBase/include/otbSharkUtils.h +++ b/Modules/ThirdParty/Shark/include/otbSharkUtils.h @@ -21,7 +21,8 @@ #ifndef otbSharkUtils_h #define otbSharkUtils_h -#include "itkMacro.h" +#include <stdexcept> +#include <string> #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push @@ -41,11 +42,13 @@ namespace Shark { template <class T> void ListSampleRangeToSharkVector(const T * listSample, std::vector<shark::RealVector> & output, unsigned int start, unsigned int size) { - assert(listSample != ITK_NULLPTR); + assert(listSample != nullptr); if(start+size>listSample->Size()) { - itkGenericExceptionMacro(<<"Requested range ["<<start<<", "<<start+size<<"[ is out of bound for input list sample (range [0, "<<listSample->Size()<<"["); + std::out_of_range e_(std::string("otb::Shark::ListSampleRangeToSharkVector " + ": Requested range is out of list sample bounds")); + throw e_; } output.clear(); @@ -83,11 +86,13 @@ template <class T> void ListSampleRangeToSharkVector(const T * listSample, std:: template <class T> void ListSampleRangeToSharkVector(const T * listSample, std::vector<unsigned int> & output, unsigned int start, unsigned int size) { - assert(listSample != ITK_NULLPTR); + assert(listSample != nullptr); if(start+size>listSample->Size()) { - itkGenericExceptionMacro(<<"Requested range ["<<start<<", "<<start+size<<"[ is out of bound for input list sample (range [0, "<<listSample->Size()<<"["); + std::out_of_range e_(std::string("otb::Shark::ListSampleRangeToSharkVector " + ": Requested range is out of list sample bounds")); + throw e_; } output.clear(); @@ -113,13 +118,13 @@ template <class T> void ListSampleRangeToSharkVector(const T * listSample, std:: template <class T> void ListSampleToSharkVector(const T * listSample, std::vector<shark::RealVector> & output) { - assert(listSample != ITK_NULLPTR); + assert(listSample != nullptr); ListSampleRangeToSharkVector(listSample,output,0U,static_cast<unsigned int>(listSample->Size())); } template <class T> void ListSampleToSharkVector(const T * listSample, std::vector<unsigned int> & output) { - assert(listSample != ITK_NULLPTR); + assert(listSample != nullptr); ListSampleRangeToSharkVector(listSample,output,0, static_cast<unsigned int>(listSample->Size())); } diff --git a/Modules/ThirdParty/Shark/otb-module-init.cmake b/Modules/ThirdParty/Shark/otb-module-init.cmake index 6bdd8c6a31559d89eb7b56d8bb9b0295ed0c7c26..23ec6090c7031f09ffe821918d14e58de5fc764e 100644 --- a/Modules/ThirdParty/Shark/otb-module-init.cmake +++ b/Modules/ThirdParty/Shark/otb-module-init.cmake @@ -20,4 +20,8 @@ find_package ( Shark REQUIRED ) +if(SHARK_USE_OPENMP AND NOT OTB_USE_OPENMP) + message(WARNING "Shark library is built with OpenMP and you have OTB_USE_OPENMP set to OFF.") +endif() + mark_as_advanced( Shark_DIR ) diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h index c6317be14289016f5a5f9636b1af864a1d0c969c..bbc610eeb91e77fff82d2635fda33d40dad34bdc 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h @@ -212,6 +212,9 @@ public: bool GetParameterEmpty(std::string paramKey); /** Set HasUserValue flag of parameter with key paramKey + * Note that when this function is called from DoInit, DoUpdateParameters + * or DoExecute, it will always set this flag to false, because this is + * the core behavior of the application. */ void SetParameterUserValue(std::string paramKey, bool value); @@ -1013,6 +1016,10 @@ private: bool m_HaveInXML; bool m_HaveOutXML; bool m_IsInXMLParsed; + + /** Flag is true when executing DoInit, DoUpdateParameters or DoExecute */ + bool m_IsInPrivateDo; + /** * Declare the class * - Wrapper::MapProjectionParametersHandler diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h new file mode 100644 index 0000000000000000000000000000000000000000..b2a26670de700f3daf95a9c943477366c59dba50 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbWrapperBoolParameter_h +#define otbWrapperBoolParameter_h + +#include "otbWrapperParameter.h" +#include "OTBApplicationEngineExport.h" + +namespace otb +{ +namespace Wrapper +{ + +/** \class BoolParameter + * \brief This class represent a boolean parameter for the wrapper framework + * + * It is intended to replace the deprecated EmptyParameter + * + * \ingroup OTBApplicationEngine + */ +class OTBApplicationEngine_EXPORT BoolParameter + : public Parameter +{ +public: + /** Standard class typedef */ + typedef BoolParameter Self; + typedef Parameter Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Defining ::New() static method */ + itkNewMacro(Self); + + /** RTTI support */ + itkTypeMacro(BoolParameter, Parameter); + + /** This parameter is ON/OFF switch, it always has a value */ + bool HasValue() const override + { + return true; + } + + bool GetValue() const; + + std::string GetValueAsString() const; + + void SetValue(bool state); + + void SetValue(const std::string & str); + +protected: + /** Constructor */ + BoolParameter(); + + /** Destructor */ + ~BoolParameter() override + {} + +private: + BoolParameter(const BoolParameter &) = delete; + void operator =(const BoolParameter&) = delete; + + bool m_Value; +}; + +} // end of namespace Wrapper +} // end of namespace otb + +#endif diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h index 7978c5fb4f7a0345c123a0b8612196495cfafca1..cb34ef1e3ffe9cc583d4f67c2b3a1db4ba1c534f 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h @@ -31,6 +31,8 @@ namespace Wrapper /** \class EmptyParameter * \brief This class represent an empty parameter for the wrapper framework (boolean value) * + * \deprecated in OTB 6.6, use BoolParameter instead + * * \ingroup OTBApplicationEngine */ class OTBApplicationEngine_EXPORT EmptyParameter diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx index 74e7385133261080cf1e05a831fbac8608f94abe..814695045a90df698c862b0a361fe78683ebaa7d 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx @@ -38,8 +38,6 @@ template <class TImageType> TImageType* InputImageParameter::GetImage() { - otbMsgDevMacro(<< "GetImage()"); - // Used m_PreviousFileName because if not, when the user call twice GetImage, // it without changing the filename, it returns 2 different // image pointers diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h index 236411f8f21e8b185bed7aa514770bb19ca00b14..5776138606c07ad87371d00aa855f7864156be03 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h @@ -31,26 +31,6 @@ namespace otb { namespace Wrapper { -enum DefaultValueMode - { - /** - * This parameter has no default behaviour and should be set by - * the user. - */ - DefaultValueMode_UNKNOWN, - /** - * The default value of this parameter can be estimated from - * other parameters. - */ - DefaultValueMode_RELATIVE, - - /** - * The default value of this parameter is not depending on any - * other parameter. - */ - DefaultValueMode_ABSOLUTE - }; - /** \class Parameter * \brief This class represent a parameter for the wrapper framework @@ -114,20 +94,29 @@ public: /** Toogle the parameter mandatory flag */ itkBooleanMacro(Mandatory); - /** Set the parameter AutomaticValue flag */ - itkSetMacro(AutomaticValue, bool); + /** Set the parameter AutomaticValue flag (which is the opposite of UserValue)*/ + virtual void SetAutomaticValue(bool flag) + { + this->SetUserValue(!flag); + } /** Get the parameter AutomaticValue flag */ - itkGetConstMacro(AutomaticValue, bool); - - /** Toogle the parameter AutomaticValue flag */ - itkBooleanMacro(AutomaticValue); - - /** Set the default value mode */ - itkSetEnumMacro(DefaultValueMode, DefaultValueMode); - - /** Get the default value mode */ - itkGetEnumMacro(DefaultValueMode, DefaultValueMode); + virtual bool GetAutomaticValue() const + { + return !m_UserValue; + } + + /** Toogle ON the parameter AutomaticValue flag */ + void AutomaticValueOn() + { + this->SetAutomaticValue(true); + } + + /** Toogle OFF the parameter AutomaticValue flag */ + void AutomaticValueOff() + { + this->SetAutomaticValue(false); + } /** Set the user access level */ itkSetEnumMacro(UserLevel, UserLevel); @@ -199,20 +188,6 @@ public: return m_ChildrenList; } - /** Store the state of the check box relative to this parameter (TO - * BE MOVED to QtWrapper Model ) - */ - virtual bool IsChecked() const - { - return m_IsChecked; - } - - /** Modify the state of the checkbox relative to this parameter */ - virtual void SetChecked(const bool value) - { - m_IsChecked = value; - } - protected: /** Constructor */ Parameter() : @@ -222,12 +197,9 @@ protected: m_Mandatory( true ), m_Active( false ), m_UserValue( false ), - m_AutomaticValue( false ), - m_DefaultValueMode( DefaultValueMode_UNKNOWN ), m_UserLevel( UserLevel_Basic ), m_Role( Role_Input ), - m_Root( this ), - m_IsChecked( false ) + m_Root( this ) {} /** Destructor */ @@ -248,15 +220,9 @@ protected: /** True if activated (a mandatory parameter is always active) */ bool m_Active; - /** True if the value is set in user mode */ + /** True if the value is set in user mode (otherwise, it is an automatic value)*/ bool m_UserValue; - /** True if the application change the value of this parameter */ - bool m_AutomaticValue; - - /** Default value behaviour */ - DefaultValueMode m_DefaultValueMode; - UserLevel m_UserLevel; /** Default iotype mode */ @@ -268,9 +234,6 @@ protected: /** List of children parameters */ std::vector<Parameter::Pointer > m_ChildrenList; - /** Store the status of the checkbox */ - bool m_IsChecked; - private: Parameter(const Parameter &); //purposely not implemented void operator =(const Parameter&); //purposely not implemented diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h index 8a31e1f2c45040b1a7c69334311bdbc762c4c2fa..a27e22508403dc4fed5069571f16991ea9a07310 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h @@ -58,7 +58,8 @@ typedef enum ParameterType_ComplexOutputImage, ParameterType_RAM, ParameterType_OutputProcessXML, - ParameterType_InputProcessXML + ParameterType_InputProcessXML, + ParameterType_Bool } ParameterType; typedef enum diff --git a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt index 45d0427a4910b17dba0d51cbbce91ebc67492940..115c5a772bc146af0c87c8123920e90a4f33f1bf 100644 --- a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt +++ b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt @@ -31,6 +31,17 @@ set( OTBApplicationEngine_SRC otbWrapperInputFilenameListParameter.cxx otbWrapperOutputImageParameter.cxx otbWrapperInputImageParameter.cxx + otbWrapperInputImageParameterUInt8.cxx + otbWrapperInputImageParameterUInt16.cxx + otbWrapperInputImageParameterUInt32.cxx + otbWrapperInputImageParameterInt16.cxx + otbWrapperInputImageParameterInt32.cxx + otbWrapperInputImageParameterCInt16.cxx + otbWrapperInputImageParameterCInt32.cxx + otbWrapperInputImageParameterCFloat.cxx + otbWrapperInputImageParameterCDouble.cxx + otbWrapperInputImageParameterFloat.cxx + otbWrapperInputImageParameterDouble.cxx otbWrapperParameterKey.cxx otbWrapperDocExampleStructure.cxx otbWrapperInputVectorDataParameter.cxx @@ -45,7 +56,7 @@ set( OTBApplicationEngine_SRC otbWrapperStringListParameter.cxx otbWrapperAbstractParameterList.cxx otbWrapperParameterList.cxx - otbLogger.cxx + otbWrapperBoolParameter.cxx ) add_library(OTBApplicationEngine ${OTBApplicationEngine_SRC}) diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx index cca32d50d38ee1b3c8bb056854863e49179a493b..5c597e94d233d22461c20b69a7f81308c754472e 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx @@ -37,7 +37,7 @@ #include "otbWrapperRAMParameter.h" #include "otbWrapperProxyParameter.h" #include "otbWrapperParameterKey.h" - +#include "otbWrapperBoolParameter.h" #include "otbWrapperAddProcessToWatchEvent.h" @@ -65,7 +65,8 @@ Application::Application() m_Doclink(""), m_HaveInXML(true), m_HaveOutXML(true), - m_IsInXMLParsed(false) + m_IsInXMLParsed(false), + m_IsInPrivateDo(false) { // Don't call Init from the constructor, since it calls a virtual method ! m_Logger->SetName("Application.logger"); @@ -138,6 +139,11 @@ void Application::SetParameterInt(std::string parameter, int value, bool hasUser ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param); paramChoice->SetValue(value); } + else if (dynamic_cast<BoolParameter*>(param)) + { + BoolParameter* paramBool = dynamic_cast<BoolParameter*>(param); + paramBool->SetValue(static_cast<bool>(value)); + } this->SetParameterUserValue(parameter, hasUserValueFlag); } @@ -250,6 +256,11 @@ void Application::SetParameterString(std::string parameter, std::string value, b if ( !paramDown->SetFileName(value) ) otbAppLogCRITICAL( <<"Invalid XML parameter filename " << value <<"."); } + else if (dynamic_cast<BoolParameter*>(param)) + { + BoolParameter* paramDown = dynamic_cast<BoolParameter*>(param); + paramDown->SetValue(value); + } else { otbAppLogWARNING( <<"This parameter can't be set using SetParameterString()."); @@ -293,8 +304,8 @@ void Application::SetParameterStringList(std::string parameter, std::vector<std: void Application::SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag) { - GetParameterByKey(parameter)->SetActive(value); this->SetParameterUserValue(parameter, hasUserValueFlag); + GetParameterByKey(parameter)->SetActive(value); } void Application::SetParameterUserValue(std::string paramKey, bool value) @@ -304,7 +315,14 @@ void Application::SetParameterUserValue(std::string paramKey, bool value) using Application::EnableParameter(); **/ EnableParameter(paramKey); - GetParameterByKey(paramKey)->SetUserValue(value); + if (m_IsInPrivateDo) + { + GetParameterByKey(paramKey)->SetUserValue(false); + } + else + { + GetParameterByKey(paramKey)->SetUserValue(value); + } } const Parameter* Application::GetParameterByKey(std::string name, bool follow) const @@ -320,7 +338,9 @@ void Application::Init() m_ParameterList = ParameterGroup::New(); //reset inXML parse checker in case if reinit-ing m_IsInXMLParsed = false; + m_IsInPrivateDo = true; this->DoInit(); + m_IsInPrivateDo = false; //rashad: global parameters. now used only for inxml and outxml if(this->GetHaveInXML()) @@ -352,7 +372,9 @@ void Application::UpdateParameters() } } } + m_IsInPrivateDo = true; this->DoUpdateParameters(); + m_IsInPrivateDo = false; } void Application::AfterExecuteAndWriteOutputs() @@ -387,7 +409,9 @@ int Application::Execute() itk::Statistics::MersenneTwisterRandomVariateGenerator::GetInstance()->Initialize(); } + m_IsInPrivateDo = true; this->DoExecute(); + m_IsInPrivateDo = false; // Ensure that all output image parameter have called UpdateOutputInformation() for (auto it = paramList.begin(); it != paramList.end(); ++it) @@ -724,6 +748,10 @@ ParameterType Application::GetParameterType(std::string paramKey) const { type = ParameterType_InputProcessXML; } + else if (dynamic_cast<const BoolParameter*>(param)) + { + type = ParameterType_Bool; + } else { itkExceptionMacro(<< "Unknown parameter : " << paramKey); @@ -1007,6 +1035,16 @@ int Application::GetParameterInt(std::string parameter) ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param); ret = paramChoice->GetValue(); } + else if (dynamic_cast<BoolParameter*>(param)) + { + BoolParameter* paramBool = dynamic_cast<BoolParameter*>(param); + ret = static_cast<int>(paramBool->GetValue()); + } + else if (dynamic_cast<EmptyParameter*>(param)) + { + // This case is here for compatibility purpose with deprecated EmptyParameter + ret = static_cast<int>(this->IsParameterEnabled(parameter)); + } else { itkExceptionMacro(<<parameter << " parameter can't be casted to int"); @@ -1128,6 +1166,11 @@ std::string Application::GetParameterString(std::string parameter) InputProcessXMLParameter* paramDown = dynamic_cast<InputProcessXMLParameter*>(param); ret = paramDown->GetFileName(); } + else if (dynamic_cast<BoolParameter*>(param)) + { + BoolParameter* paramDown = dynamic_cast<BoolParameter*>(param); + ret = paramDown->GetValueAsString(); + } else { itkExceptionMacro(<<parameter << " : parameter can't be casted to string"); @@ -1450,7 +1493,8 @@ std::string Application::GetParameterAsString(std::string paramKey) || type == ParameterType_ComplexInputImage || type == ParameterType_InputVectorData || type == ParameterType_OutputImage || type == ParameterType_OutputVectorData || type == ParameterType_ListView || type == ParameterType_Choice - || type == ParameterType_OutputProcessXML || type == ParameterType_InputProcessXML ) + || type == ParameterType_OutputProcessXML || type == ParameterType_InputProcessXML + || type == ParameterType_Bool) { ret = this->GetParameterString( paramKey ); } diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx index f022af0ddbe47d8d7c59415363fff57800151c4f..f68d3a39233577a2f5e139063eb43da100cf9130 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx @@ -211,10 +211,6 @@ ApplicationRegistry::CreateApplication(const std::string& name, bool useFactory) appli = app; appli->Init(); } - else - { - otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << possibleApp->GetNameOfClass() << std::endl ); - } } } @@ -350,10 +346,6 @@ ApplicationRegistry::GetAvailableApplications(bool useFactory) std::string curName(app->GetName()); appSet.insert(curName); } - else - { - otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl ); - } } } @@ -438,7 +430,7 @@ ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name) } else { - otbMsgDevMacro( << "Can't load library : " << path << std::endl ); + otbLogMacro(Warning,<< "Failed to load libraries from " << path << " while trying to create application "<<name ); } } return appli; diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperBoolParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperBoolParameter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d34cb43676fb8faaa382091457f6fafe06d2fdf8 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperBoolParameter.cxx @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperBoolParameter.h" + +namespace otb +{ +namespace Wrapper +{ + +BoolParameter::BoolParameter() + : m_Value(false) +{} + +bool +BoolParameter::GetValue() const +{ + return m_Value; +} + +std::string +BoolParameter::GetValueAsString() const +{ + return std::string(m_Value?"true":"false"); +} + +void +BoolParameter::SetValue(bool state) +{ + if (m_Value != state) + { + m_Value = state; + this->Modified(); + } + this->SetActive(true); +} + +void +BoolParameter::SetValue(const std::string & str) +{ + std::string lowerStr; + // only strings less than 8 characters expected + lowerStr.reserve(8); + for (unsigned int i=0 ; i < std::min(8U,(unsigned int) str.size()) ; i++ ) + { + lowerStr.push_back(tolower(str[i])); + } + if (lowerStr == "1" || lowerStr == "on" || lowerStr == "true" || lowerStr == "yes") + { + this->SetValue(true); + } + else if (lowerStr == "0" || lowerStr == "off" || lowerStr == "false" || lowerStr == "no") + { + this->SetValue(false); + } + else + { + itkGenericExceptionMacro(<< "Wrong value for BoolParameter (" << str << ")," + " accepts: 0, 1, on, off, true, false, yes, no"); + } +} + +} // end of namespace Wrapper +} // end of namespace otb diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx index fe226ef2ffbd7ccb6f588e3926642181c31819ea..96b315b050c76e22a9dd89060777e1d4dede5363 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx @@ -70,18 +70,6 @@ InputImageParameter::GetImage() otbGetImageMacro(UInt8RGBImage); otbGetImageMacro(UInt8RGBAImage); -otbGetImageAndVectorImageMacro(UInt8); -otbGetImageAndVectorImageMacro(UInt16); -otbGetImageAndVectorImageMacro(UInt32); -otbGetImageAndVectorImageMacro(Int16); -otbGetImageAndVectorImageMacro(Int32); -otbGetImageAndVectorImageMacro(Float); -otbGetImageAndVectorImageMacro(Double); -otbGetImageAndVectorImageMacro(ComplexInt16); -otbGetImageAndVectorImageMacro(ComplexInt32); -otbGetImageAndVectorImageMacro(ComplexFloat); -otbGetImageAndVectorImageMacro(ComplexDouble); - void InputImageParameter::SetImage(FloatVectorImageType* image) diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCDouble.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCDouble.cxx new file mode 100644 index 0000000000000000000000000000000000000000..304a871a7757c1a3d7296319b058c48054bd9869 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCDouble.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(ComplexDouble); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCFloat.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCFloat.cxx new file mode 100644 index 0000000000000000000000000000000000000000..264b851038d31309591fc0302450db99bbcd49d8 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCFloat.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(ComplexFloat); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt16.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d49f3d031a92ff29987d485298eb4aae41c84216 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt16.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(ComplexInt16); +} +} \ No newline at end of file diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt32.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5d675543ad21f25620b2ee410e6a31d70c98b8bc --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterCInt32.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(ComplexInt32); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b7735195eac6a82a3d9cfdf0726a7aaacd6169c9 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(Double); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9d41953f67861b5021752e86868ba9a7de3a375a --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(Float); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx new file mode 100644 index 0000000000000000000000000000000000000000..217fda3d3fcf00838937df23d0a8d70393555d33 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(Int16); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6a38bb1a303e90639ca24985d4f2f01795e1de04 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(Int32); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d2e58d1503439919714e15252ea8b7f608bf79a6 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(UInt16); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fe75efce28305dd87fee383fa026084610d43497 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(UInt32); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e8af7e127a3d2270dda6c6bb7ffd6ea60f825a04 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperInputImageParameter.h" +#include "otbWrapperInputImageParameterMacros.h" +#include "otbWrapperTypes.h" + +namespace otb +{ +namespace Wrapper +{ +otbGetImageAndVectorImageMacro(UInt8); +} +} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx index 938936ebf64784d0287e9d5e4be25701e2c2c738..8287525aa66b9266a994486b49c613a4a8d9ae24 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx @@ -306,8 +306,9 @@ InputProcessXMLParameter::Read(Application::Pointer this_) } } - if ( type == ParameterType_OutputFilename || type == ParameterType_OutputVectorData || - type == ParameterType_String || type == ParameterType_Choice || type == ParameterType_RAM) + if (type == ParameterType_OutputFilename || type == ParameterType_OutputVectorData || + type == ParameterType_String || type == ParameterType_Choice || + type == ParameterType_RAM || type == ParameterType_Bool) { this_->SetParameterString(key, value); } diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx index 493191677c554686770604ca734effe4017c3784..a4d4557c6d58dad4cdd47bec748822eac41d2ffd 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx @@ -50,7 +50,7 @@ void MapProjectionParametersHandler::AddMapProjectionParameters( Application::Po oss.str(""); oss <<key<<".utm" <<".northhem"; - app->AddParameter(ParameterType_Empty, oss.str(), "Northern Hemisphere"); + app->AddParameter(ParameterType_Bool, oss.str(), "Northern Hemisphere"); app->SetParameterDescription(oss.str(),"The transverse mercator projections are defined by their zone number as well as the hemisphere. Activate this parameter if your image is in the northern hemisphere."); diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx index 5ba103723d9d93908d66f14330570e515f9caadd..cc2f69e995dc0cdcf1b7e83d4ffa267a8df64c15 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx @@ -235,7 +235,9 @@ OutputProcessXMLParameter::ParseGroup(const std::string& group) } else { - bool paramExists = m_Appli->HasUserValue(key) && m_Appli->IsParameterEnabled(key); + bool paramExists = m_Appli->HasUserValue(key) && + m_Appli->IsParameterEnabled(key) && + m_Appli->GetParameterRole(key) == Role_Input; if ( type == ParameterType_OutputProcessXML ) { paramExists = false; @@ -305,7 +307,7 @@ OutputProcessXMLParameter::ParseGroup(const std::string& group) type == ParameterType_Directory || type == ParameterType_InputImage || type == ParameterType_ComplexInputImage || type == ParameterType_InputVectorData || type == ParameterType_Choice || type == ParameterType_OutputVectorData || - type == ParameterType_OutputFilename) + type == ParameterType_OutputFilename || type == ParameterType_Bool) { value = m_Appli->GetParameterString(key); } diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx index 2ba9ba9307936fba2a190c054c050e69181c696c..9846f99ce4e471a557b30422e8735f483dbe73eb 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx @@ -40,6 +40,7 @@ #include "otbWrapperParameterKey.h" #include "otbWrapperRAMParameter.h" #include "otbWrapperProxyParameter.h" +#include "otbWrapperBoolParameter.h" #include "otb_boost_string_header.h" @@ -332,6 +333,10 @@ ParameterGroup::GetSelectedItems(std::string paramKey) { return ParameterType_InputProcessXML; } + else if (type == "Bool") + { + return ParameterType_Bool; + } else { std::cerr << "Cannot find parameter type code for type: " << type << std::endl; @@ -466,6 +471,11 @@ std::string ParameterGroup::GetParameterTypeAsString(ParameterType type) paramType = "InputProcessXML"; } break; + case ParameterType_Bool: + { + paramType = "Bool"; + } + break; default: { std::cerr << "Cannot find string version of parameter type" << std::endl; @@ -625,6 +635,11 @@ ParameterGroup::AddParameter(ParameterType type, std::string paramKey, std::stri newParam = InputProcessXMLParameter::New(); } break; + case ParameterType_Bool: + { + newParam = BoolParameter::New(); + } + break; } if (newParam.IsNull()) diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx index cf70dc07b7bd8e50922a313f4bc6ff21ecaa973c..670bb484373bee1c0fa7c964c1d3b7b31002a266 100644 --- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx +++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx @@ -435,7 +435,8 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() type == ParameterType_InputVectorData || type == ParameterType_OutputVectorData || type == ParameterType_RAM || - type == ParameterType_OutputProcessXML) // || type == ParameterType_InputProcessXML) + type == ParameterType_OutputProcessXML || + type == ParameterType_Bool) // || type == ParameterType_InputProcessXML) { // Single value parameter m_Application->SetParameterString(paramKey, values[0]); @@ -686,7 +687,7 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer & { oss << "<int32> "; } - else if (type == ParameterType_Empty ) + else if (type == ParameterType_Empty || type == ParameterType_Bool) { oss << "<boolean> "; } diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetBoolParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetBoolParameter.h new file mode 100644 index 0000000000000000000000000000000000000000..681ef9c6933b622487dd1599813b9e6f96ea4923 --- /dev/null +++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetBoolParameter.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbWrapperQtWidgetBoolParameter_h +#define otbWrapperQtWidgetBoolParameter_h + +#include <QtGui> +#ifndef Q_MOC_RUN // See: https://bugreports.qt-project.org/browse/QTBUG-22829 //tag=QT4-boost-compatibility +#include "otbWrapperBoolParameter.h" +#include "otbWrapperQtWidgetParameterBase.h" +#endif //tag=QT4-boost-compatibility + +namespace otb +{ +namespace Wrapper +{ + +/** \class QtWidgetBoolParameter + * \brief + * + * \ingroup OTBQtWidget + */ +class OTBQtWidget_EXPORT QtWidgetBoolParameter : public QtWidgetParameterBase +{ + Q_OBJECT + +public: + QtWidgetBoolParameter(BoolParameter*, QtWidgetModel*); + ~QtWidgetBoolParameter() ITK_OVERRIDE; + +public slots: + void SetValue( bool value ); + +private: + QtWidgetBoolParameter(const QtWidgetBoolParameter&) = delete; + void operator=(const QtWidgetBoolParameter&) = delete; + + void DoCreateWidget() ITK_OVERRIDE; + + void DoUpdateGUI() ITK_OVERRIDE; + + QToolButton *m_Button; +}; + + +} +} + +#endif diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h index db88ca9ace0243f4a10165b560e26dc2967b4869..86b0eeed42228ed64efe2be8a3e8f9c2af5e6ae9 100644 --- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h +++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h @@ -33,6 +33,8 @@ namespace otb namespace Wrapper { +class QtWidgetParameterGroup; + /** \class QtWidgetParameterBase * \brief * @@ -41,12 +43,26 @@ namespace Wrapper class OTBQtWidget_EXPORT QtWidgetParameterBase : public QWidget { Q_OBJECT + friend class QtWidgetParameterGroup; public: QtWidgetParameterBase( Parameter *, QtWidgetModel * ); ~QtWidgetParameterBase() ITK_OVERRIDE; void CreateWidget(); + /** Store the state of the check box relative to this parameter + */ + virtual bool IsChecked() const + { + return m_IsChecked; + } + + /** Modify the state of the checkbox relative to this parameter */ + virtual void SetChecked(const bool value) + { + m_IsChecked = value; + } + public slots: void UpdateGUI(); virtual void SetActivationState( bool value ); @@ -77,6 +93,9 @@ private: QtWidgetModel * m_Model; Parameter * m_Param; + + /** Store the status of the checkbox */ + bool m_IsChecked; }; diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterGroup.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterGroup.h index 3e3969739fa821ad30ed26666c5e019e89ea1746..da70434fbf7684fe17fd05c781a9f54bcf50f0ad 100644 --- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterGroup.h +++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterGroup.h @@ -59,7 +59,7 @@ private: void DoUpdateGUI() ITK_OVERRIDE; - virtual void ProcessChild(Parameter * currentNode, bool status); + virtual void ProcessChild(QObject* currentNode, bool status); ParameterGroup::Pointer m_ParamList; diff --git a/Modules/Wrappers/QtWidget/src/CMakeLists.txt b/Modules/Wrappers/QtWidget/src/CMakeLists.txt index 28cb58c37691087555171daca7ab833814eed571..a366e0458e9376d11e445ce2f332786d1ad2bb6e 100644 --- a/Modules/Wrappers/QtWidget/src/CMakeLists.txt +++ b/Modules/Wrappers/QtWidget/src/CMakeLists.txt @@ -57,6 +57,7 @@ set(OTBQtWidget_SRC otbWrapperQtWidgetListEditWidget.cxx otbWrapperQtWidgetListEditItemModel.cxx otbWrapperQtWidgetParameterList.cxx + otbWrapperQtWidgetBoolParameter.cxx ) set(OTBQtWidget_MOC_HDR @@ -97,6 +98,7 @@ set(OTBQtWidget_MOC_HDR ../include/otbWrapperQtWidgetListEditWidget.h ../include/otbWrapperQtWidgetListEditItemModel.h ../include/otbWrapperQtWidgetParameterList.h + ../include/otbWrapperQtWidgetBoolParameter.h ) set( OTBQtWidget_FORMS diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetBoolParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetBoolParameter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..effe1fc5633d5541681928e1a2ce3f6667442129 --- /dev/null +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetBoolParameter.cxx @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperQtWidgetBoolParameter.h" + +namespace otb +{ +namespace Wrapper +{ + +QtWidgetBoolParameter::QtWidgetBoolParameter(BoolParameter* boolParam, QtWidgetModel* m) + : QtWidgetParameterBase(boolParam, m) +{ +} + +QtWidgetBoolParameter::~QtWidgetBoolParameter() +{ +} + +void QtWidgetBoolParameter::SetValue( bool value ) +{ + BoolParameter* paramDown = dynamic_cast<BoolParameter*>(this->GetParam()); + assert(paramDown && "Not a BoolParameter"); + if (paramDown->GetValue() != value) + { + paramDown->SetValue(value); + + QString key( paramDown->GetKey() ); + emit ParameterChanged(key); + } +} + +void QtWidgetBoolParameter::DoUpdateGUI() +{ + BoolParameter* paramDown = dynamic_cast<BoolParameter*>(this->GetParam()); + assert(paramDown && "Not a BoolParameter"); + if (paramDown->GetValue() != m_Button->isChecked()) + { + m_Button->setChecked(paramDown->GetValue()); + } + QString buttonText(paramDown->GetValue()?"On":"Off"); + if (m_Button->text() != buttonText) + { + m_Button->setText(buttonText); + } +} + +void QtWidgetBoolParameter::DoCreateWidget() +{ + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->setSpacing(0); + hLayout->setContentsMargins(0, 0, 0, 0); + + m_Button = new QToolButton; + m_Button->setCheckable(true); + BoolParameter* paramDown = dynamic_cast<BoolParameter*>(this->GetParam()); + assert(paramDown && "Not a BoolParameter"); + if (paramDown->GetValue()) + { + m_Button->setText("On"); + m_Button->setChecked(true); + } + else + { + m_Button->setText("Off"); + } + + connect( m_Button, SIGNAL(toggled(bool)), this, SLOT(SetValue(bool)) ); + connect( m_Button, SIGNAL(toggled(bool)), GetModel(), SLOT(NotifyUpdate()) ); + + hLayout->addWidget(m_Button); + hLayout->addStretch(); + + this->setLayout(hLayout); +} + +} +} diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx index eb44e1a4ee8eca304b95e7e52f11a185c2560c0a..86789e4197d67cdf0848b673b9a4508740e4949b 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx @@ -26,7 +26,9 @@ namespace Wrapper { QtWidgetParameterBase::QtWidgetParameterBase(Parameter * param, QtWidgetModel* m) - : m_Model(m), m_Param(param) + : m_Model(m) + , m_Param(param) + , m_IsChecked( false ) { } @@ -89,7 +91,7 @@ void QtWidgetParameterBase::SetActivationState( bool value ) } this->setEnabled(value); - m_Param->SetChecked(value); + this->SetChecked(value); m_Param->SetActive(value); } diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx index 89763c423741832b3c1e21f21ef144ff85690a22..f675050e2347ecbfea6604ee8bdbda458d5f08f3 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx @@ -50,6 +50,7 @@ #include "otbWrapperQtWidgetRAMParameter.h" #include "otbWrapperQtWidgetStringParameter.h" #include "otbWrapperQtWidgetStringListParameter.h" +#include "otbWrapperQtWidgetBoolParameter.h" namespace otb @@ -123,7 +124,7 @@ QtWidgetParameterFactory::CreateQtWidget( Parameter* param, QtWidgetModel* model CREATEWIDGET(InputVectorDataParameter, QtWidgetInputVectorDataParameter) CREATEWIDGET(OutputImageParameter, QtWidgetOutputImageParameter) CREATEWIDGET(OutputVectorDataParameter, QtWidgetOutputVectorDataParameter) - CREATEWIDGET(EmptyParameter, QtWidgetEmptyParameter) + CREATEWIDGET(BoolParameter, QtWidgetBoolParameter) CREATEWIDGET(ParameterGroup, QtWidgetParameterGroup) CREATEWIDGET(RAMParameter, QtWidgetRAMParameter) CREATEWIDGET(OutputProcessXMLParameter, QtWidgetOutputProcessXMLParameter) diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterGroup.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterGroup.cxx index 12af047e282ec56f150656711ba4086c238ea647..b9ba4673cb1049c6ebccfced5e5e13774f5fbdba 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterGroup.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterGroup.cxx @@ -141,10 +141,10 @@ void QtWidgetParameterGroup::DoCreateWidget() group->setChecked(false); // Update iteratively the children status - for (unsigned int idx = 0; idx < param->GetChildrenList().size(); ++idx) + for (auto child : specificWidget->children()) { // deactivate the children tree - this->ProcessChild(param->GetChildrenList()[idx], false); + this->ProcessChild(child, false); } } else @@ -176,33 +176,35 @@ void QtWidgetParameterGroup::SetActivationState( bool value ) this->setEnabled(value); // Update iteratively the children status - for (unsigned int idx = 0; idx < m_ParamList->GetChildrenList().size(); ++idx) + for (auto child : this->children() ) { - this->ProcessChild(m_ParamList->GetChildrenList()[idx], value); + this->ProcessChild(child, value); } } // Activate iteratively the children -void QtWidgetParameterGroup::ProcessChild(Parameter* currentNode, bool status) +void QtWidgetParameterGroup::ProcessChild(QObject* currentNode, bool status) { // Activate the current node if it was checked - if ( currentNode->IsChecked() && status) + QtWidgetParameterBase* widgetBase = dynamic_cast<QtWidgetParameterBase*>(currentNode); + if(widgetBase) { - currentNode->SetActive(status); - } + if ( widgetBase->IsChecked() && status) + { + widgetBase->GetParam()->SetActive(status); + } - // If the status is false (deactivating) deactivate all the children - // tree - if (!status) - { - currentNode->SetActive(status); + // If the status is false (deactivating) deactivate all the children + // tree + if (!status) + { + widgetBase->GetParam()->SetActive(status); + } } - unsigned int counter = 0; - while(counter < currentNode->GetChildrenList().size()) + for (auto child : currentNode->children() ) { - this->ProcessChild(currentNode->GetChildrenList()[counter], status); - ++counter; + this->ProcessChild(child, status); } } diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i index d945d52af4dc68f35b84e30601c69fa2896557c5..88802af41a2805f1c0921814d7dd1a7f34bcc175 100644 --- a/Modules/Wrappers/SWIG/src/otbApplication.i +++ b/Modules/Wrappers/SWIG/src/otbApplication.i @@ -74,12 +74,6 @@ namespace otb { namespace Wrapper { - enum DefaultValueMode - { - DefaultValueMode_UNKNOWN, - DefaultValueMode_RELATIVE, - DefaultValueMode_ABSOLUTE - }; typedef enum { @@ -106,7 +100,8 @@ namespace Wrapper ParameterType_ComplexOutputImage, ParameterType_RAM, ParameterType_OutputProcessXML, - ParameterType_InputProcessXML + ParameterType_InputProcessXML, + ParameterType_Bool } ParameterType; typedef enum @@ -502,6 +497,7 @@ class ApplicationProxy(object): ParameterType_Empty : 'ParameterType_Empty', ParameterType_Choice : 'ParameterType_Choice', ParameterType_Group : 'ParameterType_Group', + ParameterType_Bool : 'ParameterType_Bool' }.get(parameter_type, 'ParameterType_UNKNOWN') def __str__(self): @@ -510,6 +506,10 @@ class ApplicationProxy(object): s += self.GetDocLongDescription() return s + def SetParameters(self, dict_params): + for param_key, param_value in dict_params.iteritems(): + self.SetParameterValue(param_key, param_value) + def SetParameterValue(self, paramKey, value): paramType = self.GetParameterType(paramKey) if paramType in [ParameterType_InputProcessXML, ParameterType_RAM, @@ -522,13 +522,15 @@ class ApplicationProxy(object): elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList, ParameterType_InputFilenameList, ParameterType_StringList, ParameterType_ListView]: - return self.setParameterStringList(paramKey, value) + return self.SetParameterStringList(paramKey, value) elif paramType in [ParameterType_Int, ParameterType_Radius]: return self.SetParameterInt(paramKey, value) elif paramType in [ParameterType_Float]: return self.SetParameterFloat(paramKey, value) elif paramType in [ParameterType_Empty]: return self.EnableParameter(paramKey) + elif paramType in [ParameterType_Bool]: + return self.SetParameterString(paramKey, str(value) ) elif paramType in [ParameterType_Group]: return ApplicationProxy(self, paramKey) elif paramType in [ParameterType_Choice]: @@ -537,6 +539,13 @@ class ApplicationProxy(object): print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey)) return + def GetParameters(self): + ret = {} + for key in self.GetParametersKeys(): + if self.HasValue(key) and self.IsParameterEnabled(key) and self.GetParameterRole(key) == 0: + ret[key] = self.GetParameterValue(key) + return ret + def GetParameterValue(self, paramKey): paramType = self.GetParameterType(paramKey) if paramType in [ParameterType_InputProcessXML, @@ -556,6 +565,8 @@ class ApplicationProxy(object): return self.GetParameterFloat(paramKey) elif paramType in [ParameterType_Empty]: return self.IsParameterEnabled(paramKey) + elif paramType in [ParameterType_Bool]: + return bool(self.GetParameterInt(paramKey)) elif paramType in [ParameterType_Group, ParameterType_Choice]: return ApplicationProxy(self, paramKey) else: diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt index b0e0ac49bc32e831d3780db989ad2a08938e293b..bd5865b5706658c76aa13d81c90f4ee5926c5b6d 100644 --- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt +++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt @@ -141,3 +141,8 @@ add_test( NAME pyTvBug1498 ${OTB_DATA_ROOT}/Input/poupees.tif ${TEMP}/Bu1498-output.tif) +add_test( NAME pyTvParametersDict + COMMAND ${TEST_DRIVER} Execute + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py + PythonParametersDict + ${OTB_DATA_ROOT}/Input/poupees.tif) diff --git a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py index 4cb17b6fe546d0c2ad2a97222d40e5eca83eae4b..c6cb4f3c4bad06845c8a3e9449f83174cbe35aca 100644 --- a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py +++ b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py @@ -84,12 +84,12 @@ def test(otb, argv): cm_assert(app.MAP.UTM.ZONE, 31) # 10 - bool type sub parameters of choice parameter get - app.DisableParameter('map.utm.northhem') + app.SetParameterInt('map.utm.northhem',0) cm_assert(app.MAP.UTM.NORTHHEM, False) # 11 - bool type sub parameters of choice parameter set app.MAP.UTM.NORTHHEM = True - cm_assert(True, app.IsParameterEnabled('map.utm.northhem') ) + cm_assert(True, app.GetParameterInt('map.utm.northhem') ) #12 - simple choice parameter set app.OUTPUTS.MODE = 'auto' @@ -128,7 +128,7 @@ def test(otb, argv): cm_assert(app.IsParameterEnabled('outputs.isotropic'), True) #21 - parameter bool get - app.DisableParameter('outputs.isotropic') + app.SetParameterInt('outputs.isotropic',0) cm_assert(False, app.OUTPUTS.ISOTROPIC) #Do not execute. we need LARGEINPUT. so we tried a small application diff --git a/Modules/Wrappers/SWIG/test/python/PythonParametersDict.py b/Modules/Wrappers/SWIG/test/python/PythonParametersDict.py new file mode 100644 index 0000000000000000000000000000000000000000..d05161acc4c52dde972821ef827edeea26344be8 --- /dev/null +++ b/Modules/Wrappers/SWIG/test/python/PythonParametersDict.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) +# +# This file is part of Orfeo Toolbox +# +# https://www.orfeo-toolbox.org/ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# -*- coding: utf-8 -*- + +# +# Example on the use of parameters dictionaries +# + +def test(otb, argv): + app = otb.Registry.CreateApplication("Smoothing") + + app.SetParameterString("out", "myOutput.tif") + app.SetParameterInt("type.mean.radius",4) + prm = app.GetParameters() + if prm["out"] != "myOutput.tif": + exit(1) + if prm["type.mean.radius"] != 4: + exit(1) + prm["in"] = argv[1] + prm["type"] = "anidif" + prm["type.anidif.nbiter"] = 12 + app.SetParameters(prm) + if app.GetParameterString("in") != argv[1]: + exit(1) + if app.GetParameterInt("type.anidif.nbiter") != 12: + exit(1) +