From 84514586f43a879ec3fd33a52bb557263bddc0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Mon, 29 Jul 2019 17:59:22 +0200 Subject: [PATCH 01/24] ENH: make VectorClassifier template --- .../app/otbVectorClassifier.cxx | 408 +--------------- .../include/otbVectorPrediction.h | 444 ++++++++++++++++++ 2 files changed, 446 insertions(+), 406 deletions(-) create mode 100644 Modules/Applications/AppClassification/include/otbVectorPrediction.h diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index 1f0401aeec..d6f5e25e42 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -18,418 +18,14 @@ * 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 "otbMachineLearningModelFactory.h" - -#include "otbMachineLearningModel.h" - -#include +#include "otbVectorPrediction.h" namespace otb { namespace Wrapper { -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } - -class VectorClassifier : public Application -{ -public: - /** Standard class typedefs. */ - typedef VectorClassifier Self; - typedef Application Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Standard macro */ - itkNewMacro(Self); - - itkTypeMacro(Self, Application) - - /** Filters typedef */ - typedef float ValueType; - typedef unsigned int LabelType; - typedef itk::FixedArray LabelSampleType; - typedef itk::Statistics::ListSample LabelListSampleType; - - typedef otb::MachineLearningModel MachineLearningModelType; - typedef otb::MachineLearningModelFactory MachineLearningModelFactoryType; - typedef MachineLearningModelType::Pointer ModelPointerType; - typedef MachineLearningModelType::ConfidenceListSampleType ConfidenceListSampleType; - - /** Statistics Filters typedef */ - typedef itk::VariableLengthVector MeasurementType; - typedef otb::StatisticsXMLFileReader StatisticsReader; - - typedef itk::VariableLengthVector InputSampleType; - typedef itk::Statistics::ListSample ListSampleType; - typedef otb::Statistics::ShiftScaleSampleListFilter ShiftScaleFilterType; - - ~VectorClassifier() override - { - MachineLearningModelFactoryType::CleanFactories(); - } - -private: - void DoInit() override - { - SetName("VectorClassifier"); - SetDescription("Performs a classification of the input vector data according to a model file."); - - SetDocAuthors("OTB-Team"); - SetDocLongDescription("This application performs a vector data classification " - "based on a model file produced by the TrainVectorClassifier application." - "Features of the vector data output will contain the class labels decided by the classifier " - "(maximal class label = 65535). \n" - "There are two modes: \n" - "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n" - "2) Write mode: copies the existing fields of the input file to the output file " - " and add the 'cfield' field containing the predicted class. \n" - "If you have declared the output file, the write mode applies. " - "Otherwise, the input file update mode will be applied."); - - SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); - SetDocSeeAlso("TrainVectorClassifier"); - AddDocTag(Tags::Learning); - - AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); - SetParameterDescription("in","The input vector data file to classify."); - - AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); - SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" - "and reduce samples before classification, produced by ComputeImagesStatistics application."); - MandatoryOff("instat"); - - AddParameter(ParameterType_InputFilename, "model", "Model file"); - SetParameterDescription("model", "Model file produced by TrainVectorClassifier application."); - - AddParameter(ParameterType_String,"cfield","Field class"); - SetParameterDescription("cfield","Field containing the predicted class." - "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"); - - 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_Bool, "confmap", "Confidence map"); - SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n" - "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n" - "* Boost: sum of votes\n" - "* DecisionTree: (not supported)\n" - "* KNearestNeighbors: number of neighbors with the same label\n" - "* NeuralNetwork: difference between the two highest responses\n" - "* NormalBayes: (not supported)\n" - "* 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"); - - AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels"); - SetParameterDescription("out","Output vector data file storing sample values (OGR format)." - "If not given, the input vector data file is updated."); - MandatoryOff("out"); - - // Doc example parameter settings - SetDocExampleParameterValue("in", "vectorData.shp"); - SetDocExampleParameterValue("instat", "meanVar.xml"); - SetDocExampleParameterValue("model", "svmModel.svm"); - SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); - SetDocExampleParameterValue("feat", "perimeter area width"); - SetDocExampleParameterValue("cfield", "predicted"); - - SetOfficialDocLink(); - } - - void DoUpdateParameters() override - { - if ( HasValue("in") ) - { - std::string shapefile = GetParameterString("in"); - - otb::ogr::DataSource::Pointer ogrDS; - - OGRSpatialReference oSRS(""); - std::vector 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); - key.erase( std::remove_if(key.begin(),key.end(),IsNotAlphaNum), key.end()); - std::transform(key.begin(), key.end(), key.begin(), tolower); - - OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); - if(fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) - { - std::string tmpKey="feat."+key; - AddChoice(tmpKey,item); - } - } - } - } - - void DoExecute() 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(); - - const int nbFeatures = GetSelectedItems("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) - { - // Beware that itemIndex differs from ogr layer field index - unsigned int itemIndex = GetSelectedItems("feat")[idx]; - std::string fieldName = GetChoiceNames( "feat" )[itemIndex]; - switch ((*it)[fieldName].GetType()) - { - case OFTInteger: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - case OFTInteger64: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - case OFTReal: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - default: - itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); - } - - - } - 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"); - } - 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("mean used: " << meanMeasurementVector); - otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); - - otbAppLogINFO("Loading model"); - m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), - MachineLearningModelFactoryType::ReadMode); - - if (m_Model.IsNull()) - { - otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); - } - - m_Model->Load(GetParameterString("model")); - otbAppLogINFO("Model loaded"); - - ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); - - ConfidenceListSampleType::Pointer quality; - - bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() - && !m_Model->GetRegressionMode()); - - if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) - { - otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); - } - - LabelListSampleType::Pointer target; - if (computeConfidenceMap) - { - quality = ConfidenceListSampleType::New(); - target = m_Model->PredictBatch(listSample, quality); - } - else - { - target = m_Model->PredictBatch(listSample); - } - - ogr::DataSource::Pointer output; - ogr::DataSource::Pointer buffer = ogr::DataSource::New(); - bool updateMode = false; - if (IsParameterEnabled("out") && HasValue("out")) - { - // Create new OGRDataSource - output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); - otb::ogr::Layer newLayer = output->CreateLayer( - GetParameterString("out"), - const_cast(layer.GetSpatialRef()), - layer.GetGeomType()); - // Copy existing fields - OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); - for (int k=0 ; kCopyLayer(inputLayer, std::string("Buffer")); - // close input data source - source->Clear(); - // Re-open input data source in update mode - output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); - } - - otb::ogr::Layer outLayer = output->GetLayer(0); - - OGRErr errStart = outLayer.ogr().StartTransaction(); - if (errStart != OGRERR_NONE) - { - itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); - } - - // Add the field of prediction in the output layer if field not exist - OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); - int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTInteger) - itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); - } - else - { - OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTInteger); - ogr::FieldDefn predictedFieldDef(predictedField); - outLayer.CreateField(predictedFieldDef); - } - - // Add confidence field in the output layer - std::string confFieldName("confidence"); - if (computeConfidenceMap) - { - idx = layerDefn.GetFieldIndex(confFieldName.c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) - itkExceptionMacro("Field name "<< confFieldName << " already exists with a different type!"); - } - else - { - OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal); - confidenceField.SetWidth(confidenceField.GetWidth()); - confidenceField.SetPrecision(confidenceField.GetPrecision()); - ogr::FieldDefn confFieldDefn(confidenceField); - outLayer.CreateField(confFieldDefn); - } - } - - // Fill output layer - unsigned int count=0; - std::string classfieldname = GetParameterString("cfield"); - it = layer.cbegin(); - itEnd = layer.cend(); - for( ; it!=itEnd ; ++it, ++count) - { - ogr::Feature dstFeature(outLayer.GetLayerDefn()); - dstFeature.SetFrom( *it , TRUE); - dstFeature.SetFID(it->GetFID()); - switch (dstFeature[classfieldname].GetType()) - { - case OFTInteger: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTInteger64: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTReal: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTString: - dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); - break; - default: - itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); - } - if (computeConfidenceMap) - dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); - if (updateMode) - { - outLayer.SetFeature(dstFeature); - } - else - { - outLayer.CreateFeature(dstFeature); - } - } - - if(outLayer.ogr().TestCapability("Transactions")) - { - const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); - if (errCommitX != OGRERR_NONE) - { - itkExceptionMacro(<< "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; -}; +typedef VectorPrediction VectorClassifier; } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h new file mode 100644 index 0000000000..a138572574 --- /dev/null +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2005-2019 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 otbVectorPrediction_h +#define otbVectorPrediction_h + +#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 "otbMachineLearningModelFactory.h" + +#include "otbMachineLearningModel.h" + +#include + +namespace otb +{ +namespace Wrapper +{ + +template +class VectorPrediction : public Application +{ +public: + /** Standard class typedefs. */ + typedef VectorPrediction Self; + typedef Application Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + /** Standard macro */ + itkNewMacro(Self); + + itkTypeMacro(Self, Application) + + /** Filters typedef */ + //typedef float ValueType; + //typedef unsigned int LabelType; + typedef itk::FixedArray LabelSampleType; + typedef itk::Statistics::ListSample LabelListSampleType; + + typedef otb::MachineLearningModel MachineLearningModelType; + typedef otb::MachineLearningModelFactory MachineLearningModelFactoryType; + typedef typename MachineLearningModelType::Pointer ModelPointerType; + typedef typename MachineLearningModelType::ConfidenceListSampleType ConfidenceListSampleType; + + /** Statistics Filters typedef */ + typedef itk::VariableLengthVector MeasurementType; + typedef otb::StatisticsXMLFileReader StatisticsReader; + + typedef itk::VariableLengthVector InputSampleType; + typedef itk::Statistics::ListSample ListSampleType; + typedef otb::Statistics::ShiftScaleSampleListFilter ShiftScaleFilterType; + + ~VectorPrediction() override + { + MachineLearningModelFactoryType::CleanFactories(); + } + +private: + /** Utility function to negate std::isalnum */ + static bool IsNotAlphaNum(char c) + { + return !std::isalnum(c); + } + + void DoInit() override + { + SetName("VectorClassifier"); + SetDescription("Performs a classification of the input vector data according to a model file."); + + SetDocAuthors("OTB-Team"); + SetDocLongDescription("This application performs a vector data classification " + "based on a model file produced by the TrainVectorClassifier application." + "Features of the vector data output will contain the class labels decided by the classifier " + "(maximal class label = 65535). \n" + "There are two modes: \n" + "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n" + "2) Write mode: copies the existing fields of the input file to the output file " + " and add the 'cfield' field containing the predicted class. \n" + "If you have declared the output file, the write mode applies. " + "Otherwise, the input file update mode will be applied."); + + SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); + SetDocSeeAlso("TrainVectorClassifier"); + AddDocTag(Tags::Learning); + + AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + SetParameterDescription("in","The input vector data file to classify."); + + AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); + SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" + "and reduce samples before classification, produced by ComputeImagesStatistics application."); + MandatoryOff("instat"); + + AddParameter(ParameterType_InputFilename, "model", "Model file"); + SetParameterDescription("model", "Model file produced by TrainVectorClassifier application."); + + AddParameter(ParameterType_String,"cfield","Field class"); + SetParameterDescription("cfield","Field containing the predicted class." + "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"); + + 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_Bool, "confmap", "Confidence map"); + SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n" + "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n" + "* Boost: sum of votes\n" + "* DecisionTree: (not supported)\n" + "* KNearestNeighbors: number of neighbors with the same label\n" + "* NeuralNetwork: difference between the two highest responses\n" + "* NormalBayes: (not supported)\n" + "* 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"); + + AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels"); + SetParameterDescription("out","Output vector data file storing sample values (OGR format)." + "If not given, the input vector data file is updated."); + MandatoryOff("out"); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "vectorData.shp"); + SetDocExampleParameterValue("instat", "meanVar.xml"); + SetDocExampleParameterValue("model", "svmModel.svm"); + SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); + SetDocExampleParameterValue("feat", "perimeter area width"); + SetDocExampleParameterValue("cfield", "predicted"); + + SetOfficialDocLink(); + } + + void DoUpdateParameters() override + { + if ( HasValue("in") ) + { + std::string shapefile = GetParameterString("in"); + + otb::ogr::DataSource::Pointer ogrDS; + + OGRSpatialReference oSRS(""); + std::vector 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); + key.erase( std::remove_if(key.begin(),key.end(),IsNotAlphaNum), key.end()); + std::transform(key.begin(), key.end(), key.begin(), tolower); + + OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); + if(fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) + { + std::string tmpKey="feat."+key; + AddChoice(tmpKey,item); + } + } + } + } + + void DoExecute() 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); + + typename ListSampleType::Pointer input = ListSampleType::New(); + + const int nbFeatures = GetSelectedItems("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) + { + // Beware that itemIndex differs from ogr layer field index + unsigned int itemIndex = GetSelectedItems("feat")[idx]; + std::string fieldName = GetChoiceNames( "feat" )[itemIndex]; + switch ((*it)[fieldName].GetType()) + { + case OFTInteger: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + case OFTInteger64: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + case OFTReal: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + default: + itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); + } + + + } + input->PushBack(mv); + } + + // Statistics for shift/scale + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + if (HasValue("instat") && IsParameterEnabled("instat")) + { + typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + std::string XMLfile = GetParameterString("instat"); + statisticsReader->SetFileName(XMLfile); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + } + else + { + meanMeasurementVector.SetSize(nbFeatures); + meanMeasurementVector.Fill(0.); + stddevMeasurementVector.SetSize(nbFeatures); + stddevMeasurementVector.Fill(1.); + } + + typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); + trainingShiftScaleFilter->SetInput(input); + trainingShiftScaleFilter->SetShifts(meanMeasurementVector); + trainingShiftScaleFilter->SetScales(stddevMeasurementVector); + trainingShiftScaleFilter->Update(); + otbAppLogINFO("mean used: " << meanMeasurementVector); + otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); + + otbAppLogINFO("Loading model"); + m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), + MachineLearningModelFactoryType::ReadMode); + + if (m_Model.IsNull()) + { + otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); + } + + m_Model->Load(GetParameterString("model")); + otbAppLogINFO("Model loaded"); + + typename ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); + + typename ConfidenceListSampleType::Pointer quality; + + bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() + && !m_Model->GetRegressionMode()); + + if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) + { + otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); + } + + typename LabelListSampleType::Pointer target; + if (computeConfidenceMap) + { + quality = ConfidenceListSampleType::New(); + target = m_Model->PredictBatch(listSample, quality); + } + else + { + target = m_Model->PredictBatch(listSample); + } + + ogr::DataSource::Pointer output; + ogr::DataSource::Pointer buffer = ogr::DataSource::New(); + bool updateMode = false; + if (IsParameterEnabled("out") && HasValue("out")) + { + // Create new OGRDataSource + output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); + otb::ogr::Layer newLayer = output->CreateLayer( + GetParameterString("out"), + const_cast(layer.GetSpatialRef()), + layer.GetGeomType()); + // Copy existing fields + OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); + for (int k=0 ; kCopyLayer(inputLayer, std::string("Buffer")); + // close input data source + source->Clear(); + // Re-open input data source in update mode + output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); + } + + otb::ogr::Layer outLayer = output->GetLayer(0); + + OGRErr errStart = outLayer.ogr().StartTransaction(); + if (errStart != OGRERR_NONE) + { + itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); + } + + // Add the field of prediction in the output layer if field not exist + OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); + int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTInteger) + itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); + } + else + { + OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTInteger); + ogr::FieldDefn predictedFieldDef(predictedField); + outLayer.CreateField(predictedFieldDef); + } + + // Add confidence field in the output layer + std::string confFieldName("confidence"); + if (computeConfidenceMap) + { + idx = layerDefn.GetFieldIndex(confFieldName.c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) + itkExceptionMacro("Field name "<< confFieldName << " already exists with a different type!"); + } + else + { + OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal); + confidenceField.SetWidth(confidenceField.GetWidth()); + confidenceField.SetPrecision(confidenceField.GetPrecision()); + ogr::FieldDefn confFieldDefn(confidenceField); + outLayer.CreateField(confFieldDefn); + } + } + + // Fill output layer + unsigned int count=0; + std::string classfieldname = GetParameterString("cfield"); + it = layer.cbegin(); + itEnd = layer.cend(); + for( ; it!=itEnd ; ++it, ++count) + { + ogr::Feature dstFeature(outLayer.GetLayerDefn()); + dstFeature.SetFrom( *it , TRUE); + dstFeature.SetFID(it->GetFID()); + switch (dstFeature[classfieldname].GetType()) + { + case OFTInteger: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTInteger64: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTReal: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTString: + dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); + break; + default: + itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); + } + if (computeConfidenceMap) + dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); + if (updateMode) + { + outLayer.SetFeature(dstFeature); + } + else + { + outLayer.CreateFeature(dstFeature); + } + } + + if(outLayer.ogr().TestCapability("Transactions")) + { + const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); + if (errCommitX != OGRERR_NONE) + { + itkExceptionMacro(<< "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; +}; + +typedef VectorPrediction VectorClassifier; +typedef VectorPrediction VectorRegression; + +} +} + +#endif -- GitLab From bf1a286314ca9b8a85efe7038bb85a1449611365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Mon, 29 Jul 2019 18:00:06 +0200 Subject: [PATCH 02/24] ENH: new application VectorRegression --- .../AppClassification/app/CMakeLists.txt | 5 +++ .../app/otbVectorRegression.cxx | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 Modules/Applications/AppClassification/app/otbVectorRegression.cxx diff --git a/Modules/Applications/AppClassification/app/CMakeLists.txt b/Modules/Applications/AppClassification/app/CMakeLists.txt index 9c9404e94b..c981d9ec5b 100644 --- a/Modules/Applications/AppClassification/app/CMakeLists.txt +++ b/Modules/Applications/AppClassification/app/CMakeLists.txt @@ -115,6 +115,11 @@ otb_create_application( SOURCES otbVectorClassifier.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES}) +otb_create_application( + NAME VectorRegression + SOURCES otbVectorRegression.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES}) + otb_create_application( NAME SampleAugmentation SOURCES otbSampleAugmentation.cxx diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx new file mode 100644 index 0000000000..00670adfe2 --- /dev/null +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2019 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 "otbVectorPrediction.h" + +namespace otb +{ +namespace Wrapper +{ + +typedef VectorPrediction VectorRegression; + +} +} + +OTB_APPLICATION_EXPORT(otb::Wrapper::VectorRegression) -- GitLab From 3369f28ec53757e9d7f5e406791e792e08861246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 30 Jul 2019 14:13:13 +0200 Subject: [PATCH 03/24] ENH: use template parameter RegressionMode on the ML model --- .../app/otbVectorClassifier.cxx | 21 ++++++++++++++- .../app/otbVectorRegression.cxx | 21 ++++++++++++++- .../include/otbVectorPrediction.h | 27 +++++++------------ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index d6f5e25e42..da553cfae0 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -25,7 +25,26 @@ namespace otb namespace Wrapper { -typedef VectorPrediction VectorClassifier; +using VectorClassifier = VectorPrediction; + +template<> +void +VectorClassifier +::CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer) +{ + int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTInteger) + itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); + } + else + { + OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTInteger); + ogr::FieldDefn predictedFieldDef(predictedField); + outLayer.CreateField(predictedFieldDef); + } +} } } diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 00670adfe2..bba74a3152 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -25,7 +25,26 @@ namespace otb namespace Wrapper { -typedef VectorPrediction VectorRegression; +using VectorRegression = VectorPrediction; + +template<> +void +VectorRegression +::CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer) +{ + int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) + itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); + } + else + { + OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTReal); + ogr::FieldDefn predictedFieldDef(predictedField); + outLayer.CreateField(predictedFieldDef); + } +} } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index a138572574..dfa537be48 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -194,6 +194,10 @@ private: } } + /** Create the prediction field in the output layer, this template method should be specialized + * to create the right type of field (e.g. OGRInteger or OGRReal) */ + void CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer); + void DoExecute() override { clock_t tic = clock(); @@ -275,6 +279,8 @@ private: otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); } + m_Model->SetRegressionMode(RegressionMode); + m_Model->Load(GetParameterString("model")); otbAppLogINFO("Model loaded"); @@ -342,26 +348,16 @@ private: itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); } - // Add the field of prediction in the output layer if field not exist OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); - int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTInteger) - itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); - } - else - { - OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTInteger); - ogr::FieldDefn predictedFieldDef(predictedField); - outLayer.CreateField(predictedFieldDef); - } + + // Add the field of prediction in the output layer if field not exist + CreatePredictionField(layerDefn, outLayer); // Add confidence field in the output layer std::string confFieldName("confidence"); if (computeConfidenceMap) { - idx = layerDefn.GetFieldIndex(confFieldName.c_str()); + int idx = layerDefn.GetFieldIndex(confFieldName.c_str()); if (idx >= 0) { if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) @@ -435,9 +431,6 @@ private: ModelPointerType m_Model; }; -typedef VectorPrediction VectorClassifier; -typedef VectorPrediction VectorRegression; - } } -- GitLab From 85fc4c8c973a840c76613cf918a9de555edf6025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 30 Jul 2019 16:45:20 +0200 Subject: [PATCH 04/24] ENH: partial specialization for the DoInit method --- .../app/otbVectorClassifier.cxx | 73 ++++++++++++++++++ .../app/otbVectorRegression.cxx | 63 ++++++++++++++++ .../include/otbVectorPrediction.h | 75 ++----------------- 3 files changed, 142 insertions(+), 69 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index da553cfae0..62d6800210 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -27,6 +27,79 @@ namespace Wrapper using VectorClassifier = VectorPrediction; +template<> +void +VectorClassifier +::DoInitSpecialization() +{ + SetName("VectorClassifier"); + SetDescription("Performs a classification of the input vector data according to a model file."); + + SetDocAuthors("OTB-Team"); + SetDocLongDescription("This application performs a vector data classification " + "based on a model file produced by the TrainVectorClassifier application." + "Features of the vector data output will contain the class labels decided by the classifier " + "(maximal class label = 65535). \n" + "There are two modes: \n" + "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n" + "2) Write mode: copies the existing fields of the input file to the output file " + " and add the 'cfield' field containing the predicted class. \n" + "If you have declared the output file, the write mode applies. " + "Otherwise, the input file update mode will be applied."); + + SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); + SetDocSeeAlso("TrainVectorClassifier"); + AddDocTag(Tags::Learning); + + AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + SetParameterDescription("in","The input vector data file to classify."); + + AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); + SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" + "and reduce samples before classification, produced by ComputeImagesStatistics application."); + MandatoryOff("instat"); + + AddParameter(ParameterType_InputFilename, "model", "Model file"); + SetParameterDescription("model", "Model file produced by TrainVectorClassifier application."); + + AddParameter(ParameterType_String,"cfield","Output field"); + SetParameterDescription("cfield","Field containing the predicted class." + "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"); + + 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_Bool, "confmap", "Confidence map"); + SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n" + "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n" + "* Boost: sum of votes\n" + "* DecisionTree: (not supported)\n" + "* KNearestNeighbors: number of neighbors with the same label\n" + "* NeuralNetwork: difference between the two highest responses\n" + "* NormalBayes: (not supported)\n" + "* 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"); + + AddParameter(ParameterType_OutputFilename, "out", "Output vector data file"); + MandatoryOff("out"); + SetParameterDescription("out","Output vector data file storing sample values (OGR format)." + "If not given, the input vector data file is updated."); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "vectorData.shp"); + SetDocExampleParameterValue("instat", "meanVar.xml"); + SetDocExampleParameterValue("model", "svmModel.svm"); + SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); + SetDocExampleParameterValue("feat", "perimeter area width"); + SetDocExampleParameterValue("cfield", "predicted"); + + SetOfficialDocLink(); +} + template<> void VectorClassifier diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index bba74a3152..02dd347096 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -27,6 +27,69 @@ namespace Wrapper using VectorRegression = VectorPrediction; +template<> +void +VectorRegression +::DoInitSpecialization() +{ + SetName("VectorRegression"); + SetDescription("Performs regression on the input vector data according to a model file."); + + SetDocAuthors("OTB-Team"); + SetDocLongDescription("This application performs a vector data regression " + "based on a model file produced by the TrainVectorRegression application." + "Features of the vector data output will contain the values predicted by the classifier. \n" + "There are two modes: \n" + "1) Update mode: add of the 'cfield' field containing the predicted value in the input file. \n" + "2) Write mode: copies the existing fields of the input file to the output file " + " and add the 'cfield' field containing the predicted value. \n" + "If you have declared the output file, the write mode applies. " + "Otherwise, the input file update mode will be applied."); + + SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); + SetDocSeeAlso("TrainVectorRegression"); + AddDocTag(Tags::Learning); + + AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + SetParameterDescription("in","The input vector data file to classify."); + + AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); + SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" + "and reduce samples before classification, produced by ComputeImagesStatistics application."); + MandatoryOff("instat"); + + AddParameter(ParameterType_InputFilename, "model", "Model file"); + SetParameterDescription("model", "Model file produced by TrainVectorRegression application."); + + AddParameter(ParameterType_String,"cfield","Output field"); + SetParameterDescription("cfield","Field containing the predicted value." + "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"); + + 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 TrainVectorRegression application."); + + AddParameter(ParameterType_OutputFilename, "out", "Output vector data file"); + MandatoryOff("out"); + + SetParameterDescription("out","Output vector data file storing sample values (OGR format)." + "If not given, the input vector data file is updated."); + MandatoryOff("out"); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "vectorData.shp"); + SetDocExampleParameterValue("instat", "meanVar.xml"); + SetDocExampleParameterValue("model", "rfModel.rf"); + SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); + SetDocExampleParameterValue("feat", "perimeter area width"); + SetDocExampleParameterValue("cfield", "predicted"); + + SetOfficialDocLink(); +} + template<> void VectorRegression diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index dfa537be48..247a2e4ace 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -92,74 +92,12 @@ private: void DoInit() override { - SetName("VectorClassifier"); - SetDescription("Performs a classification of the input vector data according to a model file."); - - SetDocAuthors("OTB-Team"); - SetDocLongDescription("This application performs a vector data classification " - "based on a model file produced by the TrainVectorClassifier application." - "Features of the vector data output will contain the class labels decided by the classifier " - "(maximal class label = 65535). \n" - "There are two modes: \n" - "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n" - "2) Write mode: copies the existing fields of the input file to the output file " - " and add the 'cfield' field containing the predicted class. \n" - "If you have declared the output file, the write mode applies. " - "Otherwise, the input file update mode will be applied."); - - SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); - SetDocSeeAlso("TrainVectorClassifier"); - AddDocTag(Tags::Learning); - - AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); - SetParameterDescription("in","The input vector data file to classify."); - - AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); - SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" - "and reduce samples before classification, produced by ComputeImagesStatistics application."); - MandatoryOff("instat"); - - AddParameter(ParameterType_InputFilename, "model", "Model file"); - SetParameterDescription("model", "Model file produced by TrainVectorClassifier application."); - - AddParameter(ParameterType_String,"cfield","Field class"); - SetParameterDescription("cfield","Field containing the predicted class." - "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"); - - 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_Bool, "confmap", "Confidence map"); - SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n" - "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n" - "* Boost: sum of votes\n" - "* DecisionTree: (not supported)\n" - "* KNearestNeighbors: number of neighbors with the same label\n" - "* NeuralNetwork: difference between the two highest responses\n" - "* NormalBayes: (not supported)\n" - "* 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"); - - AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels"); - SetParameterDescription("out","Output vector data file storing sample values (OGR format)." - "If not given, the input vector data file is updated."); - MandatoryOff("out"); - - // Doc example parameter settings - SetDocExampleParameterValue("in", "vectorData.shp"); - SetDocExampleParameterValue("instat", "meanVar.xml"); - SetDocExampleParameterValue("model", "svmModel.svm"); - SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); - SetDocExampleParameterValue("feat", "perimeter area width"); - SetDocExampleParameterValue("cfield", "predicted"); - - SetOfficialDocLink(); + DoInitSpecialization(); + //TODO add assert to check that parameters has been correctly defined } + void DoInitSpecialization(); + void DoUpdateParameters() override { if ( HasValue("in") ) @@ -288,10 +226,9 @@ private: typename ConfidenceListSampleType::Pointer quality; - bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() - && !m_Model->GetRegressionMode()); + bool computeConfidenceMap(!m_Model->GetRegressionMode() && GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); - if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) + if (!m_Model->GetRegressionMode() && !m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) { otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); } -- GitLab From a62d517222f45f5d8ab41d749cc61510dadde919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 30 Jul 2019 17:21:53 +0200 Subject: [PATCH 05/24] STY: move template code to hxx file --- .../include/otbVectorPrediction.h | 273 +-------------- .../include/otbVectorPrediction.hxx | 310 ++++++++++++++++++ 2 files changed, 317 insertions(+), 266 deletions(-) create mode 100644 Modules/Applications/AppClassification/include/otbVectorPrediction.hxx diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 247a2e4ace..aa4cb85e8d 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -90,280 +90,17 @@ private: return !std::isalnum(c); } - void DoInit() override - { - DoInitSpecialization(); - //TODO add assert to check that parameters has been correctly defined - } + void DoInit() override; void DoInitSpecialization(); - void DoUpdateParameters() override - { - if ( HasValue("in") ) - { - std::string shapefile = GetParameterString("in"); - - otb::ogr::DataSource::Pointer ogrDS; - - OGRSpatialReference oSRS(""); - std::vector 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); - key.erase( std::remove_if(key.begin(),key.end(),IsNotAlphaNum), key.end()); - std::transform(key.begin(), key.end(), key.begin(), tolower); - - OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); - if(fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) - { - std::string tmpKey="feat."+key; - AddChoice(tmpKey,item); - } - } - } - } + void DoUpdateParameters() override; /** Create the prediction field in the output layer, this template method should be specialized * to create the right type of field (e.g. OGRInteger or OGRReal) */ void CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer); - void DoExecute() 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); - - typename ListSampleType::Pointer input = ListSampleType::New(); - - const int nbFeatures = GetSelectedItems("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) - { - // Beware that itemIndex differs from ogr layer field index - unsigned int itemIndex = GetSelectedItems("feat")[idx]; - std::string fieldName = GetChoiceNames( "feat" )[itemIndex]; - switch ((*it)[fieldName].GetType()) - { - case OFTInteger: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - case OFTInteger64: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - case OFTReal: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - default: - itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); - } - - - } - input->PushBack(mv); - } - - // Statistics for shift/scale - MeasurementType meanMeasurementVector; - MeasurementType stddevMeasurementVector; - if (HasValue("instat") && IsParameterEnabled("instat")) - { - typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); - std::string XMLfile = GetParameterString("instat"); - statisticsReader->SetFileName(XMLfile); - meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); - stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); - } - else - { - meanMeasurementVector.SetSize(nbFeatures); - meanMeasurementVector.Fill(0.); - stddevMeasurementVector.SetSize(nbFeatures); - stddevMeasurementVector.Fill(1.); - } - - typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); - trainingShiftScaleFilter->SetInput(input); - trainingShiftScaleFilter->SetShifts(meanMeasurementVector); - trainingShiftScaleFilter->SetScales(stddevMeasurementVector); - trainingShiftScaleFilter->Update(); - otbAppLogINFO("mean used: " << meanMeasurementVector); - otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); - - otbAppLogINFO("Loading model"); - m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), - MachineLearningModelFactoryType::ReadMode); - - if (m_Model.IsNull()) - { - otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); - } - - m_Model->SetRegressionMode(RegressionMode); - - m_Model->Load(GetParameterString("model")); - otbAppLogINFO("Model loaded"); - - typename ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); - - typename ConfidenceListSampleType::Pointer quality; - - bool computeConfidenceMap(!m_Model->GetRegressionMode() && GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); - - if (!m_Model->GetRegressionMode() && !m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) - { - otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); - } - - typename LabelListSampleType::Pointer target; - if (computeConfidenceMap) - { - quality = ConfidenceListSampleType::New(); - target = m_Model->PredictBatch(listSample, quality); - } - else - { - target = m_Model->PredictBatch(listSample); - } - - ogr::DataSource::Pointer output; - ogr::DataSource::Pointer buffer = ogr::DataSource::New(); - bool updateMode = false; - if (IsParameterEnabled("out") && HasValue("out")) - { - // Create new OGRDataSource - output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); - otb::ogr::Layer newLayer = output->CreateLayer( - GetParameterString("out"), - const_cast(layer.GetSpatialRef()), - layer.GetGeomType()); - // Copy existing fields - OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); - for (int k=0 ; kCopyLayer(inputLayer, std::string("Buffer")); - // close input data source - source->Clear(); - // Re-open input data source in update mode - output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); - } - - otb::ogr::Layer outLayer = output->GetLayer(0); - - OGRErr errStart = outLayer.ogr().StartTransaction(); - if (errStart != OGRERR_NONE) - { - itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); - } - - OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); - - // Add the field of prediction in the output layer if field not exist - CreatePredictionField(layerDefn, outLayer); - - // Add confidence field in the output layer - std::string confFieldName("confidence"); - if (computeConfidenceMap) - { - int idx = layerDefn.GetFieldIndex(confFieldName.c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) - itkExceptionMacro("Field name "<< confFieldName << " already exists with a different type!"); - } - else - { - OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal); - confidenceField.SetWidth(confidenceField.GetWidth()); - confidenceField.SetPrecision(confidenceField.GetPrecision()); - ogr::FieldDefn confFieldDefn(confidenceField); - outLayer.CreateField(confFieldDefn); - } - } - - // Fill output layer - unsigned int count=0; - std::string classfieldname = GetParameterString("cfield"); - it = layer.cbegin(); - itEnd = layer.cend(); - for( ; it!=itEnd ; ++it, ++count) - { - ogr::Feature dstFeature(outLayer.GetLayerDefn()); - dstFeature.SetFrom( *it , TRUE); - dstFeature.SetFID(it->GetFID()); - switch (dstFeature[classfieldname].GetType()) - { - case OFTInteger: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTInteger64: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTReal: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTString: - dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); - break; - default: - itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); - } - if (computeConfidenceMap) - dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); - if (updateMode) - { - outLayer.SetFeature(dstFeature); - } - else - { - outLayer.CreateFeature(dstFeature); - } - } - - if(outLayer.ogr().TestCapability("Transactions")) - { - const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); - if (errCommitX != OGRERR_NONE) - { - itkExceptionMacro(<< "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."); - - } + void DoExecute() override; ModelPointerType m_Model; }; @@ -371,4 +108,8 @@ private: } } +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbVectorPrediction.hxx" +#endif + #endif diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx new file mode 100644 index 0000000000..10428ca0ba --- /dev/null +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2005-2019 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 otbVectorPrediction_hxx +#define otbVectorPrediction_hxx + +namespace otb +{ +namespace Wrapper +{ + +template +void +VectorPrediction +::DoInit() +{ + DoInitSpecialization(); + //TODO add assert to check that parameters has been correctly defined +} + +template +void +VectorPrediction +::DoUpdateParameters() +{ + if ( HasValue("in") ) + { + std::string shapefile = GetParameterString("in"); + + otb::ogr::DataSource::Pointer ogrDS; + + OGRSpatialReference oSRS(""); + std::vector 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); + key.erase( std::remove_if(key.begin(),key.end(),IsNotAlphaNum), key.end()); + std::transform(key.begin(), key.end(), key.begin(), tolower); + + OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); + if(fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) + { + std::string tmpKey="feat."+key; + AddChoice(tmpKey,item); + } + } + } +} + +template +void +VectorPrediction +::DoExecute() +{ + 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); + + typename ListSampleType::Pointer input = ListSampleType::New(); + + const int nbFeatures = GetSelectedItems("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) + { + // Beware that itemIndex differs from ogr layer field index + unsigned int itemIndex = GetSelectedItems("feat")[idx]; + std::string fieldName = GetChoiceNames( "feat" )[itemIndex]; + switch ((*it)[fieldName].GetType()) + { + case OFTInteger: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + case OFTInteger64: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + case OFTReal: + mv[idx] = static_cast((*it)[fieldName].GetValue()); + break; + default: + itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); + } + + + } + input->PushBack(mv); + } + + // Statistics for shift/scale + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + if (HasValue("instat") && IsParameterEnabled("instat")) + { + typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + std::string XMLfile = GetParameterString("instat"); + statisticsReader->SetFileName(XMLfile); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + } + else + { + meanMeasurementVector.SetSize(nbFeatures); + meanMeasurementVector.Fill(0.); + stddevMeasurementVector.SetSize(nbFeatures); + stddevMeasurementVector.Fill(1.); + } + + typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); + trainingShiftScaleFilter->SetInput(input); + trainingShiftScaleFilter->SetShifts(meanMeasurementVector); + trainingShiftScaleFilter->SetScales(stddevMeasurementVector); + trainingShiftScaleFilter->Update(); + otbAppLogINFO("mean used: " << meanMeasurementVector); + otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); + + otbAppLogINFO("Loading model"); + m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), + MachineLearningModelFactoryType::ReadMode); + + if (m_Model.IsNull()) + { + otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); + } + + m_Model->SetRegressionMode(RegressionMode); + + m_Model->Load(GetParameterString("model")); + otbAppLogINFO("Model loaded"); + + typename ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); + + typename ConfidenceListSampleType::Pointer quality; + + bool computeConfidenceMap(!m_Model->GetRegressionMode() && GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); + + if (!m_Model->GetRegressionMode() && !m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) + { + otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); + } + + typename LabelListSampleType::Pointer target; + if (computeConfidenceMap) + { + quality = ConfidenceListSampleType::New(); + target = m_Model->PredictBatch(listSample, quality); + } + else + { + target = m_Model->PredictBatch(listSample); + } + + ogr::DataSource::Pointer output; + ogr::DataSource::Pointer buffer = ogr::DataSource::New(); + bool updateMode = false; + if (IsParameterEnabled("out") && HasValue("out")) + { + // Create new OGRDataSource + output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); + otb::ogr::Layer newLayer = output->CreateLayer( + GetParameterString("out"), + const_cast(layer.GetSpatialRef()), + layer.GetGeomType()); + // Copy existing fields + OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); + for (int k=0 ; kCopyLayer(inputLayer, std::string("Buffer")); + // close input data source + source->Clear(); + // Re-open input data source in update mode + output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); + } + + otb::ogr::Layer outLayer = output->GetLayer(0); + + OGRErr errStart = outLayer.ogr().StartTransaction(); + if (errStart != OGRERR_NONE) + { + itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); + } + + OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); + + // Add the field of prediction in the output layer if field not exist + CreatePredictionField(layerDefn, outLayer); + + // Add confidence field in the output layer + std::string confFieldName("confidence"); + if (computeConfidenceMap) + { + int idx = layerDefn.GetFieldIndex(confFieldName.c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) + itkExceptionMacro("Field name "<< confFieldName << " already exists with a different type!"); + } + else + { + OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal); + confidenceField.SetWidth(confidenceField.GetWidth()); + confidenceField.SetPrecision(confidenceField.GetPrecision()); + ogr::FieldDefn confFieldDefn(confidenceField); + outLayer.CreateField(confFieldDefn); + } + } + + // Fill output layer + unsigned int count=0; + std::string classfieldname = GetParameterString("cfield"); + it = layer.cbegin(); + itEnd = layer.cend(); + for( ; it!=itEnd ; ++it, ++count) + { + ogr::Feature dstFeature(outLayer.GetLayerDefn()); + dstFeature.SetFrom( *it , TRUE); + dstFeature.SetFID(it->GetFID()); + switch (dstFeature[classfieldname].GetType()) + { + case OFTInteger: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTInteger64: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTReal: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTString: + dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); + break; + default: + itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); + } + if (computeConfidenceMap) + dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); + if (updateMode) + { + outLayer.SetFeature(dstFeature); + } + else + { + outLayer.CreateFeature(dstFeature); + } + } + + if(outLayer.ogr().TestCapability("Transactions")) + { + const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); + if (errCommitX != OGRERR_NONE) + { + itkExceptionMacro(<< "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."); + +} + +} //end namespace wrapper +} //end namespace otb + +#endif -- GitLab From edb5dd65cd3d2f82198fdbea7db013b70cce37f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 31 Jul 2019 10:28:02 +0200 Subject: [PATCH 06/24] ENH: use only one template parameter in VectorPrediction --- .../AppClassification/app/otbVectorClassifier.cxx | 2 +- .../AppClassification/app/otbVectorRegression.cxx | 2 +- .../include/otbVectorPrediction.h | 8 +++++--- .../include/otbVectorPrediction.hxx | 14 +++++++------- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index 62d6800210..5ccdf67e0c 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -25,7 +25,7 @@ namespace otb namespace Wrapper { -using VectorClassifier = VectorPrediction; +using VectorClassifier = VectorPrediction; template<> void diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 02dd347096..bafb8e07b2 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -25,7 +25,7 @@ namespace otb namespace Wrapper { -using VectorRegression = VectorPrediction; +using VectorRegression = VectorPrediction; template<> void diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index aa4cb85e8d..bb19171b96 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -44,7 +44,7 @@ namespace otb namespace Wrapper { -template +template class VectorPrediction : public Application { public: @@ -60,8 +60,10 @@ public: itkTypeMacro(Self, Application) /** Filters typedef */ - //typedef float ValueType; - //typedef unsigned int LabelType; + typedef float ValueType; + // Label type is float for regression and unsigned int for classification + typedef typename std::conditional::type LabelType; + typedef itk::FixedArray LabelSampleType; typedef itk::Statistics::ListSample LabelListSampleType; diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 10428ca0ba..04510eabd9 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -26,18 +26,18 @@ namespace otb namespace Wrapper { -template +template void -VectorPrediction +VectorPrediction ::DoInit() { DoInitSpecialization(); //TODO add assert to check that parameters has been correctly defined } -template +template void -VectorPrediction +VectorPrediction ::DoUpdateParameters() { if ( HasValue("in") ) @@ -72,9 +72,9 @@ VectorPrediction } } -template +template void -VectorPrediction +VectorPrediction ::DoExecute() { clock_t tic = clock(); @@ -161,7 +161,7 @@ VectorPrediction m_Model->Load(GetParameterString("model")); otbAppLogINFO("Model loaded"); - typename ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); + ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); typename ConfidenceListSampleType::Pointer quality; -- GitLab From 1be6d55e72340d3d79688a3976466e4d0a3e01ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 31 Jul 2019 11:20:49 +0200 Subject: [PATCH 07/24] ENH: new test and baselines for the VectorRegression application --- .../Files/apTvClDTVectorRegression.dbf | 3 + .../Files/apTvClDTVectorRegression.prj | 1 + .../Files/apTvClDTVectorRegression.shp | 3 + .../Files/apTvClDTVectorRegression.shx | 3 + .../Files/apTvClModelRegression.dt | 97 +++++++++++++++++++ .../include/otbVectorPrediction.hxx | 2 + .../AppClassification/test/CMakeLists.txt | 14 +++ 7 files changed, 123 insertions(+) create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf new file mode 100644 index 0000000000..c4e492c382 --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:912188a42bffa8bd35328354cf2a53006298283885ceb1889b4822a8c21c2f9b +size 343940 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj new file mode 100644 index 0000000000..da98376fa4 --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj @@ -0,0 +1 @@ +PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp new file mode 100644 index 0000000000..bb850bca2f --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5f17b630a4b9a681d571f6075373d9937f4ae4b31cd158d9cec1efb9804938d +size 33280 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx new file mode 100644 index 0000000000..49a9782c47 --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51449568ded65b75b2b1e85c82b73091d20bc87b281294bede45521c78af6bb2 +size 9580 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt b/Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt new file mode 100644 index 0000000000..79128526d9 --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt @@ -0,0 +1,97 @@ +%YAML:1.0 +my_tree: !!opencv-ml-tree + is_classifier: 0 + var_all: 4 + var_count: 4 + ord_var_count: 4 + cat_var_count: 0 + training_params: + use_surrogates: 1 + regression_accuracy: 9.9999997764825821e-03 + max_depth: 25 + min_sample_count: 10 + cross_validation_folds: 10 + use_1se_rule: 1 + truncate_pruned_tree: 1 + var_type: [ 0, 0, 0, 0 ] + best_tree_idx: 0 + nodes: + - + depth: 0 + sample_count: 1185 + value: 2.1434599156118144e+00 + Tn: 3 + complexity: 2 + alpha: 1.0428486268774041e+03 + node_risk: 1.3156118143459917e+03 + tree_risk: 1.5363497199794813e+02 + tree_error: 2.2322315115631071e+01 + splits: + - { var:3, quality:6.5841166992187500e+03, + le:2.3381726074218750e+02 } + - + depth: 1 + sample_count: 593 + value: 1.1635750421585160e+00 + Tn: 2 + complexity: 1 + alpha: 7.2124429620364594e+01 + node_risk: 8.9133220910623891e+01 + tree_risk: 7.4075046904315172e+01 + tree_error: 1.5094741436662460e+01 + splits: + - { var:3, quality:8.8817205810546875e+02, + le:1.6510346984863281e+02 } + - + depth: 2 + sample_count: 500 + value: 1. + Tn: 2147483647 + complexity: 1 + alpha: 0. + node_risk: 0. + tree_risk: 0. + tree_error: 0. + - + depth: 2 + sample_count: 93 + value: 2.0430107526881720e+00 + Tn: 0 + complexity: 1 + alpha: 1.9506172839505780e+00 + node_risk: 3.8279569892472978e+00 + tree_risk: 1.9506172839505780e+00 + tree_error: 1.9085505258344853e+00 + - + depth: 1 + sample_count: 592 + value: 3.1250000000000000e+00 + Tn: 1 + complexity: 1 + alpha: 7.0738339190549596e+01 + node_risk: 8.6750000000000000e+01 + tree_risk: 7.9559925093632955e+01 + tree_error: 7.2275736789686107e+00 + splits: + - { var:1, quality:5.8572387695312500e+03, + le:3.6126699829101562e+02 } + - + depth: 2 + sample_count: 507 + value: 2.9783037475345169e+00 + Tn: 2147483647 + complexity: 1 + alpha: 0. + node_risk: 1.0761341222879309e+01 + tree_risk: 8.8215859030833599e+00 + tree_error: 1.9415329232083423e+00 + - + depth: 2 + sample_count: 85 + value: 4. + Tn: 2147483647 + complexity: 1 + alpha: 0. + node_risk: 0. + tree_risk: 0. + tree_error: 0. diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 04510eabd9..f6edbf2a36 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -21,6 +21,8 @@ #ifndef otbVectorPrediction_hxx #define otbVectorPrediction_hxx +#include "otbVectorPrediction.h" + namespace otb { namespace Wrapper diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt index 607867c193..5bc7d22f24 100644 --- a/Modules/Applications/AppClassification/test/CMakeLists.txt +++ b/Modules/Applications/AppClassification/test/CMakeLists.txt @@ -721,6 +721,20 @@ if(OTB_USE_OPENCV) ${TEMP}/apTvClSVMLabeledVector.shp) endif() +#----------- VectorRegression TESTS ---------------- +if(OTB_USE_OPENCV) + otb_test_application(NAME apTvClDTVectorRegression + APP VectorRegression + OPTIONS -in ${INPUTDATA}/Classification/apTvClSampleExtractionOut.sqlite + -model ${OTBAPP_BASELINE_FILES}/apTvClModelRegression.dt + -out ${TEMP}/apTvClDTVectorRegression.shp + -feat value_0 value_1 value_2 value_3 + -cfield predicted + VALID --compare-ogr 0.0 + ${OTBAPP_BASELINE_FILES}/apTvClDTVectorRegression.shp + ${TEMP}/apTvClDTVectorRegression.shp) +endif() + #----------- ComputeImagesStatistics TESTS ---------------- otb_test_application(NAME apTvClComputeImagesStatisticsQB1 APP ComputeImagesStatistics -- GitLab From 6a38bed4469a534cf88e411feb6222e112655547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 31 Jul 2019 11:59:05 +0200 Subject: [PATCH 08/24] ENH: simplification of specialized field creation --- .../app/otbVectorClassifier.cxx | 19 --------------- .../app/otbVectorRegression.cxx | 19 --------------- .../include/otbVectorPrediction.h | 4 ---- .../include/otbVectorPrediction.hxx | 24 ++++++++++++++++--- 4 files changed, 21 insertions(+), 45 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index 5ccdf67e0c..5e9a245d45 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -100,25 +100,6 @@ VectorClassifier SetOfficialDocLink(); } -template<> -void -VectorClassifier -::CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer) -{ - int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTInteger) - itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); - } - else - { - OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTInteger); - ogr::FieldDefn predictedFieldDef(predictedField); - outLayer.CreateField(predictedFieldDef); - } -} - } } diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index bafb8e07b2..8af7bb8b5f 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -90,25 +90,6 @@ VectorRegression SetOfficialDocLink(); } -template<> -void -VectorRegression -::CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer) -{ - int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); - if (idx >= 0) - { - if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) - itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); - } - else - { - OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), OFTReal); - ogr::FieldDefn predictedFieldDef(predictedField); - outLayer.CreateField(predictedFieldDef); - } -} - } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index bb19171b96..14ba7193a3 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -98,10 +98,6 @@ private: void DoUpdateParameters() override; - /** Create the prediction field in the output layer, this template method should be specialized - * to create the right type of field (e.g. OGRInteger or OGRReal) */ - void CreatePredictionField(OGRFeatureDefn & layerDefn, otb::ogr::Layer & outLayer); - void DoExecute() override; ModelPointerType m_Model; diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index f6edbf2a36..74532f9e85 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -229,13 +229,31 @@ VectorPrediction OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); // Add the field of prediction in the output layer if field not exist - CreatePredictionField(layerDefn, outLayer); - + + OGRFieldType labelType; + if (RegressionMode==true) + labelType = OFTReal; + else + labelType = OFTInteger; + + int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); + if (idx >= 0) + { + if (layerDefn.GetFieldDefn(idx)->GetType() != labelType) + itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); + } + else + { + OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), labelType); + ogr::FieldDefn predictedFieldDef(predictedField); + outLayer.CreateField(predictedFieldDef); + } + // Add confidence field in the output layer std::string confFieldName("confidence"); if (computeConfidenceMap) { - int idx = layerDefn.GetFieldIndex(confFieldName.c_str()); + idx = layerDefn.GetFieldIndex(confFieldName.c_str()); if (idx >= 0) { if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) -- GitLab From b8651eb94dd94d9ba09de6f57c3fc5ee1d1a624e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 31 Jul 2019 14:39:28 +0200 Subject: [PATCH 09/24] ENH: moved the confmap parameter from vectorPrediction to vectorClassifier --- .../app/otbVectorClassifier.cxx | 16 ++++++++++++++++ .../app/otbVectorRegression.cxx | 8 ++++++++ .../include/otbVectorPrediction.h | 2 ++ .../include/otbVectorPrediction.hxx | 7 +------ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index 5e9a245d45..a90f8d2d1e 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -100,6 +100,22 @@ VectorClassifier SetOfficialDocLink(); } +template<> +bool +VectorClassifier +::shouldComputeConfidenceMap() +{ + bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); + + if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) + { + otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); + } + + return computeConfidenceMap; +} + + } } diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 8af7bb8b5f..f6490ff4f2 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -90,6 +90,14 @@ VectorRegression SetOfficialDocLink(); } +template<> +bool +VectorRegression +::shouldComputeConfidenceMap() +{ + return false; +} + } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 14ba7193a3..83f74f52a4 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -100,6 +100,8 @@ private: void DoExecute() override; + bool shouldComputeConfidenceMap(); + ModelPointerType m_Model; }; diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 74532f9e85..1fe65059bf 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -167,12 +167,7 @@ VectorPrediction typename ConfidenceListSampleType::Pointer quality; - bool computeConfidenceMap(!m_Model->GetRegressionMode() && GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); - - if (!m_Model->GetRegressionMode() && !m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) - { - otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); - } + bool computeConfidenceMap = shouldComputeConfidenceMap(); typename LabelListSampleType::Pointer target; if (computeConfidenceMap) -- GitLab From fabd68b04510f4cb236f6d5444af929a79b787c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 31 Jul 2019 16:09:46 +0200 Subject: [PATCH 10/24] ENH: use assertions to make sure all required parameters have been defined in DoInitSpecialization --- .../AppClassification/app/otbVectorRegression.cxx | 1 + .../AppClassification/include/otbVectorPrediction.hxx | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index f6490ff4f2..74ac136552 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -90,6 +90,7 @@ VectorRegression SetOfficialDocLink(); } +// Confidence map computation is not support for regression. template<> bool VectorRegression diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 1fe65059bf..8178735bcb 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -34,7 +34,14 @@ VectorPrediction ::DoInit() { DoInitSpecialization(); - //TODO add assert to check that parameters has been correctly defined + + // Assert that the all needed parameters have ben definied in DoInitSpecialization + assert(GetParameterByKey("in") != nullptr); + assert(GetParameterByKey("instat") != nullptr); + assert(GetParameterByKey("model") != nullptr); + assert(GetParameterByKey("cfield") != nullptr); + assert(GetParameterByKey("feat") != nullptr); + assert(GetParameterByKey("out") != nullptr); } template @@ -316,7 +323,6 @@ VectorPrediction clock_t toc = clock(); otbAppLogINFO( "Elapsed: "<< ((double)(toc - tic) / CLOCKS_PER_SEC)<<" seconds."); - } } //end namespace wrapper -- GitLab From 0e324b2957ce4676c036f93fc7d134f1d09274df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 1 Aug 2019 11:28:38 +0200 Subject: [PATCH 11/24] BUG: VectorRegression now use a dt model with cvfold=0, because cvfold is not supported in opencv 3 --- .../Files/apTvClDTVectorRegression.dbf | 3 - .../Files/apTvClDTVectorRegression.prj | 1 - .../Files/apTvClDTVectorRegression.shp | 3 - .../Files/apTvClDTVectorRegression.shx | 3 - .../Files/apTvClDTVectorRegression.sqlite | 3 + .../apTvClDTVectorRegression.dt} | 82 ++++++++++++------- .../AppClassification/test/CMakeLists.txt | 8 +- 7 files changed, 58 insertions(+), 45 deletions(-) delete mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf delete mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj delete mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp delete mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx create mode 100644 Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.sqlite rename Data/{Baseline/OTB-Applications/Files/apTvClModelRegression.dt => Input/Classification/apTvClDTVectorRegression.dt} (60%) diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf deleted file mode 100644 index c4e492c382..0000000000 --- a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.dbf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:912188a42bffa8bd35328354cf2a53006298283885ceb1889b4822a8c21c2f9b -size 343940 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj deleted file mode 100644 index da98376fa4..0000000000 --- a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.prj +++ /dev/null @@ -1 +0,0 @@ -PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp deleted file mode 100644 index bb850bca2f..0000000000 --- a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a5f17b630a4b9a681d571f6075373d9937f4ae4b31cd158d9cec1efb9804938d -size 33280 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx deleted file mode 100644 index 49a9782c47..0000000000 --- a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.shx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:51449568ded65b75b2b1e85c82b73091d20bc87b281294bede45521c78af6bb2 -size 9580 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.sqlite b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.sqlite new file mode 100644 index 0000000000..e4eae4a937 --- /dev/null +++ b/Data/Baseline/OTB-Applications/Files/apTvClDTVectorRegression.sqlite @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afff9c803aa384fecd0a9b068be71de7c92538cf22767e160478fbcce3b369d5 +size 118784 diff --git a/Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt b/Data/Input/Classification/apTvClDTVectorRegression.dt similarity index 60% rename from Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt rename to Data/Input/Classification/apTvClDTVectorRegression.dt index 79128526d9..e19000fd79 100644 --- a/Data/Baseline/OTB-Applications/Files/apTvClModelRegression.dt +++ b/Data/Input/Classification/apTvClDTVectorRegression.dt @@ -10,22 +10,20 @@ my_tree: !!opencv-ml-tree regression_accuracy: 9.9999997764825821e-03 max_depth: 25 min_sample_count: 10 - cross_validation_folds: 10 - use_1se_rule: 1 - truncate_pruned_tree: 1 + cross_validation_folds: 0 var_type: [ 0, 0, 0, 0 ] - best_tree_idx: 0 + best_tree_idx: -1 nodes: - depth: 0 sample_count: 1185 value: 2.1434599156118144e+00 - Tn: 3 - complexity: 2 - alpha: 1.0428486268774041e+03 + Tn: 0 + complexity: 0 + alpha: 0. node_risk: 1.3156118143459917e+03 - tree_risk: 1.5363497199794813e+02 - tree_error: 2.2322315115631071e+01 + tree_risk: 0. + tree_error: 0. splits: - { var:3, quality:6.5841166992187500e+03, le:2.3381726074218750e+02 } @@ -33,12 +31,12 @@ my_tree: !!opencv-ml-tree depth: 1 sample_count: 593 value: 1.1635750421585160e+00 - Tn: 2 - complexity: 1 - alpha: 7.2124429620364594e+01 + Tn: 0 + complexity: 0 + alpha: 0. node_risk: 8.9133220910623891e+01 - tree_risk: 7.4075046904315172e+01 - tree_error: 1.5094741436662460e+01 + tree_risk: 0. + tree_error: 0. splits: - { var:3, quality:8.8817205810546875e+02, le:1.6510346984863281e+02 } @@ -46,8 +44,8 @@ my_tree: !!opencv-ml-tree depth: 2 sample_count: 500 value: 1. - Tn: 2147483647 - complexity: 1 + Tn: 0 + complexity: 0 alpha: 0. node_risk: 0. tree_risk: 0. @@ -57,21 +55,43 @@ my_tree: !!opencv-ml-tree sample_count: 93 value: 2.0430107526881720e+00 Tn: 0 - complexity: 1 - alpha: 1.9506172839505780e+00 + complexity: 0 + alpha: 0. node_risk: 3.8279569892472978e+00 - tree_risk: 1.9506172839505780e+00 - tree_error: 1.9085505258344853e+00 + tree_risk: 0. + tree_error: 0. + splits: + - { var:0, quality:392., le:2.1638174438476562e+02 } + - + depth: 3 + sample_count: 4 + value: 3. + Tn: 0 + complexity: 0 + alpha: 0. + node_risk: 0. + tree_risk: 0. + tree_error: 0. + - + depth: 3 + sample_count: 89 + value: 2. + Tn: 0 + complexity: 0 + alpha: 0. + node_risk: 0. + tree_risk: 0. + tree_error: 0. - depth: 1 sample_count: 592 value: 3.1250000000000000e+00 - Tn: 1 - complexity: 1 - alpha: 7.0738339190549596e+01 + Tn: 0 + complexity: 0 + alpha: 0. node_risk: 8.6750000000000000e+01 - tree_risk: 7.9559925093632955e+01 - tree_error: 7.2275736789686107e+00 + tree_risk: 0. + tree_error: 0. splits: - { var:1, quality:5.8572387695312500e+03, le:3.6126699829101562e+02 } @@ -79,18 +99,18 @@ my_tree: !!opencv-ml-tree depth: 2 sample_count: 507 value: 2.9783037475345169e+00 - Tn: 2147483647 - complexity: 1 + Tn: 0 + complexity: 0 alpha: 0. node_risk: 1.0761341222879309e+01 - tree_risk: 8.8215859030833599e+00 - tree_error: 1.9415329232083423e+00 + tree_risk: 0. + tree_error: 0. - depth: 2 sample_count: 85 value: 4. - Tn: 2147483647 - complexity: 1 + Tn: 0 + complexity: 0 alpha: 0. node_risk: 0. tree_risk: 0. diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt index 5bc7d22f24..3822967fc7 100644 --- a/Modules/Applications/AppClassification/test/CMakeLists.txt +++ b/Modules/Applications/AppClassification/test/CMakeLists.txt @@ -726,13 +726,13 @@ if(OTB_USE_OPENCV) otb_test_application(NAME apTvClDTVectorRegression APP VectorRegression OPTIONS -in ${INPUTDATA}/Classification/apTvClSampleExtractionOut.sqlite - -model ${OTBAPP_BASELINE_FILES}/apTvClModelRegression.dt - -out ${TEMP}/apTvClDTVectorRegression.shp + -model ${INPUTDATA}/Classification/apTvClDTVectorRegression.dt + -out ${TEMP}/apTvClDTVectorRegression.sqlite -feat value_0 value_1 value_2 value_3 -cfield predicted VALID --compare-ogr 0.0 - ${OTBAPP_BASELINE_FILES}/apTvClDTVectorRegression.shp - ${TEMP}/apTvClDTVectorRegression.shp) + ${OTBAPP_BASELINE_FILES}/apTvClDTVectorRegression.sqlite + ${TEMP}/apTvClDTVectorRegression.sqlite) endif() #----------- ComputeImagesStatistics TESTS ---------------- -- GitLab From c57c393910f7936a238f5d19c49a5c0c83042d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 1 Aug 2019 11:58:50 +0200 Subject: [PATCH 12/24] ENH: make GetParameterInt GetParameterFloat and GetParameterString const --- .../AppClassification/app/otbVectorClassifier.cxx | 2 +- .../AppClassification/app/otbVectorRegression.cxx | 2 +- .../AppClassification/include/otbVectorPrediction.h | 2 +- .../ApplicationEngine/include/otbWrapperApplication.h | 6 +++--- .../ApplicationEngine/src/otbWrapperApplication.cxx | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index a90f8d2d1e..add5f261cd 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -103,7 +103,7 @@ VectorClassifier template<> bool VectorClassifier -::shouldComputeConfidenceMap() +::shouldComputeConfidenceMap() const { bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 74ac136552..3e529e9000 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -94,7 +94,7 @@ VectorRegression template<> bool VectorRegression -::shouldComputeConfidenceMap() +::shouldComputeConfidenceMap() const { return false; } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 83f74f52a4..637ee4ba91 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -100,7 +100,7 @@ private: void DoExecute() override; - bool shouldComputeConfidenceMap(); + bool shouldComputeConfidenceMap() const; ModelPointerType m_Model; }; diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h index 6d857dfde4..a192638083 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h @@ -420,14 +420,14 @@ public: * \li ParameterType_Radius * \li ParameterType_Choice */ - int GetParameterInt(std::string parameter); + int GetParameterInt(std::string parameter) const; /* Get a floating parameter value * * Can be called for types : * \li ParameterType_Float */ - float GetParameterFloat(std::string parameter); + float GetParameterFloat(std::string parameter) const; /* Get a string parameter value * @@ -441,7 +441,7 @@ public: * \li ParameterType_OutputImage * \li ParameterType_OutputVectorData */ - std::string GetParameterString(std::string parameter); + std::string GetParameterString(std::string parameter) const; /* Get a string list parameter value * diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx index 9cdfa1e1d8..7d5cfe93b7 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx @@ -1234,17 +1234,17 @@ void Application::SetParameterDescription(std::string parameter, std::string des param->SetDescription(desc); } -int Application::GetParameterInt(std::string key) +int Application::GetParameterInt(std::string key) const { return GetParameterByKey(key)->ToInt(); } -float Application::GetParameterFloat(std::string key) +float Application::GetParameterFloat(std::string key) const { return GetParameterByKey(key)->ToFloat(); } -std::string Application::GetParameterString(std::string key) +std::string Application::GetParameterString(std::string key) const { return GetParameterByKey(key)->ToString(); } -- GitLab From 3d6f7e386e478a299245ea6b1ea0930c7f56b7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 1 Aug 2019 13:50:51 +0200 Subject: [PATCH 13/24] ENH: change io.vd's type from VectorData to InputFilename, as the parameter is used as a filename in the application --- .../Applications/AppClassification/app/otbVectorClassifier.cxx | 2 +- .../Applications/AppClassification/app/otbVectorRegression.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index add5f261cd..92f4e90f54 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -51,7 +51,7 @@ VectorClassifier SetDocSeeAlso("TrainVectorClassifier"); AddDocTag(Tags::Learning); - AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + AddParameter(ParameterType_InputFilename, "in", "Name of the input vector data"); SetParameterDescription("in","The input vector data file to classify."); AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 3e529e9000..9b655fe01e 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -50,7 +50,7 @@ VectorRegression SetDocSeeAlso("TrainVectorRegression"); AddDocTag(Tags::Learning); - AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data"); + AddParameter(ParameterType_InputFilename, "in", "Name of the input vector data"); SetParameterDescription("in","The input vector data file to classify."); AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); -- GitLab From ada12164ae933b20e5fd9a2a65d26eb15e3707cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 1 Aug 2019 13:56:23 +0200 Subject: [PATCH 14/24] PERF: remove unused variables --- .../AppClassification/include/otbVectorPrediction.hxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 8178735bcb..73435e8fda 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -55,9 +55,6 @@ VectorPrediction otb::ogr::DataSource::Pointer ogrDS; - OGRSpatialReference oSRS(""); - std::vector options; - ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read); otb::ogr::Layer layer = ogrDS->GetLayer(0); OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); -- GitLab From 50bca421f3d749907c5eeacaff24984f335a06fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 1 Aug 2019 14:19:18 +0200 Subject: [PATCH 15/24] STY: apply clang format --- .../app/otbVectorClassifier.cxx | 102 ++++----- .../app/otbVectorRegression.cxx | 60 ++--- .../include/otbVectorPrediction.h | 43 ++-- .../include/otbVectorPrediction.hxx | 212 +++++++++--------- 4 files changed, 204 insertions(+), 213 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx index 92f4e90f54..4308f19ac6 100644 --- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx @@ -27,67 +27,73 @@ namespace Wrapper using VectorClassifier = VectorPrediction; -template<> -void -VectorClassifier -::DoInitSpecialization() +template <> +void VectorClassifier::DoInitSpecialization() { SetName("VectorClassifier"); SetDescription("Performs a classification of the input vector data according to a model file."); SetDocAuthors("OTB-Team"); - SetDocLongDescription("This application performs a vector data classification " - "based on a model file produced by the TrainVectorClassifier application." - "Features of the vector data output will contain the class labels decided by the classifier " - "(maximal class label = 65535). \n" - "There are two modes: \n" + SetDocLongDescription( + "This application performs a vector data classification " + "based on a model file produced by the TrainVectorClassifier application." + "Features of the vector data output will contain the class labels decided by the classifier " + "(maximal class label = 65535). \n" + "There are two modes: \n" "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n" "2) Write mode: copies the existing fields of the input file to the output file " - " and add the 'cfield' field containing the predicted class. \n" - "If you have declared the output file, the write mode applies. " - "Otherwise, the input file update mode will be applied."); + " and add the 'cfield' field containing the predicted class. \n" + "If you have declared the output file, the write mode applies. " + "Otherwise, the input file update mode will be applied."); SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); SetDocSeeAlso("TrainVectorClassifier"); AddDocTag(Tags::Learning); - + AddParameter(ParameterType_InputFilename, "in", "Name of the input vector data"); - SetParameterDescription("in","The input vector data file to classify."); + SetParameterDescription("in", "The input vector data file to classify."); AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); - SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" - "and reduce samples before classification, produced by ComputeImagesStatistics application."); + SetParameterDescription("instat", + "A XML file containing mean and standard deviation to center" + "and reduce samples before classification, produced by ComputeImagesStatistics application."); MandatoryOff("instat"); AddParameter(ParameterType_InputFilename, "model", "Model file"); SetParameterDescription("model", "Model file produced by TrainVectorClassifier application."); - - AddParameter(ParameterType_String,"cfield","Output field"); - SetParameterDescription("cfield","Field containing the predicted class." - "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"); - + + AddParameter(ParameterType_String, "cfield", "Output field"); + SetParameterDescription("cfield", + "Field containing the predicted class." + "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"); + 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_Bool, "confmap", "Confidence map"); - SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n" - "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n" - "* Boost: sum of votes\n" - "* DecisionTree: (not supported)\n" - "* KNearestNeighbors: number of neighbors with the same label\n" - "* NeuralNetwork: difference between the two highest responses\n" - "* NormalBayes: (not supported)\n" - "* 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"); + 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_Bool, "confmap", "Confidence map"); + SetParameterDescription("confmap", + "Confidence map of the produced classification. The confidence index depends on the model: \n\n" + "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities " + "can be computed for each sample)\n" + "* Boost: sum of votes\n" + "* DecisionTree: (not supported)\n" + "* KNearestNeighbors: number of neighbors with the same label\n" + "* NeuralNetwork: difference between the two highest responses\n" + "* NormalBayes: (not supported)\n" + "* 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"); AddParameter(ParameterType_OutputFilename, "out", "Output vector data file"); MandatoryOff("out"); - SetParameterDescription("out","Output vector data file storing sample values (OGR format)." - "If not given, the input vector data file is updated."); + SetParameterDescription("out", + "Output vector data file storing sample values (OGR format)." + "If not given, the input vector data file is updated."); // Doc example parameter settings SetDocExampleParameterValue("in", "vectorData.shp"); @@ -96,26 +102,22 @@ VectorClassifier SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp"); SetDocExampleParameterValue("feat", "perimeter area width"); SetDocExampleParameterValue("cfield", "predicted"); - + SetOfficialDocLink(); } -template<> -bool -VectorClassifier -::shouldComputeConfidenceMap() const +template <> +bool VectorClassifier::shouldComputeConfidenceMap() const { - bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex() ); + bool computeConfidenceMap(GetParameterInt("confmap") && m_Model->HasConfidenceIndex()); if (!m_Model->HasConfidenceIndex() && GetParameterInt("confmap")) - { + { otbAppLogWARNING("Confidence map requested but the classifier doesn't support it!"); - } - + } + return computeConfidenceMap; } - - } } diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index 9b655fe01e..d1b8a02f66 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -27,56 +27,59 @@ namespace Wrapper using VectorRegression = VectorPrediction; -template<> -void -VectorRegression -::DoInitSpecialization() +template <> +void VectorRegression::DoInitSpecialization() { SetName("VectorRegression"); SetDescription("Performs regression on the input vector data according to a model file."); SetDocAuthors("OTB-Team"); - SetDocLongDescription("This application performs a vector data regression " - "based on a model file produced by the TrainVectorRegression application." - "Features of the vector data output will contain the values predicted by the classifier. \n" - "There are two modes: \n" + SetDocLongDescription( + "This application performs a vector data regression " + "based on a model file produced by the TrainVectorRegression application." + "Features of the vector data output will contain the values predicted by the classifier. \n" + "There are two modes: \n" "1) Update mode: add of the 'cfield' field containing the predicted value in the input file. \n" "2) Write mode: copies the existing fields of the input file to the output file " - " and add the 'cfield' field containing the predicted value. \n" - "If you have declared the output file, the write mode applies. " - "Otherwise, the input file update mode will be applied."); + " and add the 'cfield' field containing the predicted value. \n" + "If you have declared the output file, the write mode applies. " + "Otherwise, the input file update mode will be applied."); SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode."); SetDocSeeAlso("TrainVectorRegression"); AddDocTag(Tags::Learning); AddParameter(ParameterType_InputFilename, "in", "Name of the input vector data"); - SetParameterDescription("in","The input vector data file to classify."); + SetParameterDescription("in", "The input vector data file to classify."); AddParameter(ParameterType_InputFilename, "instat", "Statistics file"); - SetParameterDescription("instat", "A XML file containing mean and standard deviation to center" - "and reduce samples before classification, produced by ComputeImagesStatistics application."); + SetParameterDescription("instat", + "A XML file containing mean and standard deviation to center" + "and reduce samples before classification, produced by ComputeImagesStatistics application."); MandatoryOff("instat"); AddParameter(ParameterType_InputFilename, "model", "Model file"); SetParameterDescription("model", "Model file produced by TrainVectorRegression application."); - AddParameter(ParameterType_String,"cfield","Output field"); - SetParameterDescription("cfield","Field containing the predicted value." - "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"); - + AddParameter(ParameterType_String, "cfield", "Output field"); + SetParameterDescription("cfield", + "Field containing the predicted value." + "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"); + 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 TrainVectorRegression application."); + SetParameterDescription("feat", + "List of field names in the input vector data used as features for training. " + "Put the same field names as the TrainVectorRegression application."); AddParameter(ParameterType_OutputFilename, "out", "Output vector data file"); MandatoryOff("out"); - SetParameterDescription("out","Output vector data file storing sample values (OGR format)." - "If not given, the input vector data file is updated."); + SetParameterDescription("out", + "Output vector data file storing sample values (OGR format)." + "If not given, the input vector data file is updated."); MandatoryOff("out"); // Doc example parameter settings @@ -91,14 +94,11 @@ VectorRegression } // Confidence map computation is not support for regression. -template<> -bool -VectorRegression -::shouldComputeConfidenceMap() const +template <> +bool VectorRegression::shouldComputeConfidenceMap() const { return false; } - } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 637ee4ba91..12cea01487 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -59,52 +59,53 @@ public: itkTypeMacro(Self, Application) - /** Filters typedef */ - typedef float ValueType; - // Label type is float for regression and unsigned int for classification - typedef typename std::conditional::type LabelType; - - typedef itk::FixedArray LabelSampleType; - typedef itk::Statistics::ListSample LabelListSampleType; - - typedef otb::MachineLearningModel MachineLearningModelType; - typedef otb::MachineLearningModelFactory MachineLearningModelFactoryType; - typedef typename MachineLearningModelType::Pointer ModelPointerType; - typedef typename MachineLearningModelType::ConfidenceListSampleType ConfidenceListSampleType; + /** Filters typedef */ + typedef float ValueType; + // Label type is float for regression and unsigned int for classification + typedef typename std::conditional::type LabelType; + + typedef itk::FixedArray LabelSampleType; + typedef itk::Statistics::ListSample LabelListSampleType; + + typedef otb::MachineLearningModel MachineLearningModelType; + typedef otb::MachineLearningModelFactory MachineLearningModelFactoryType; + typedef typename MachineLearningModelType::Pointer ModelPointerType; + typedef typename MachineLearningModelType::ConfidenceListSampleType ConfidenceListSampleType; /** Statistics Filters typedef */ - typedef itk::VariableLengthVector MeasurementType; - typedef otb::StatisticsXMLFileReader StatisticsReader; + typedef itk::VariableLengthVector MeasurementType; + typedef otb::StatisticsXMLFileReader StatisticsReader; - typedef itk::VariableLengthVector InputSampleType; - typedef itk::Statistics::ListSample ListSampleType; + typedef itk::VariableLengthVector InputSampleType; + typedef itk::Statistics::ListSample ListSampleType; typedef otb::Statistics::ShiftScaleSampleListFilter ShiftScaleFilterType; ~VectorPrediction() override - { + { MachineLearningModelFactoryType::CleanFactories(); - } + } private: /** Utility function to negate std::isalnum */ static bool IsNotAlphaNum(char c) { - return !std::isalnum(c); + return !std::isalnum(c); } - + void DoInit() override; + /** Method defining the parameters used in the application and their documentation, specialized for RegressionMode=1 and RegrssionMode=0 */ void DoInitSpecialization(); void DoUpdateParameters() override; void DoExecute() override; + /** Method returning whether the confidence map should be computed, depending on the regression mode and input parameters */ bool shouldComputeConfidenceMap() const; ModelPointerType m_Model; }; - } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 73435e8fda..1310fdfb29 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -29,12 +29,10 @@ namespace Wrapper { template -void -VectorPrediction -::DoInit() +void VectorPrediction::DoInit() { DoInitSpecialization(); - + // Assert that the all needed parameters have ben definied in DoInitSpecialization assert(GetParameterByKey("in") != nullptr); assert(GetParameterByKey("instat") != nullptr); @@ -45,67 +43,63 @@ VectorPrediction } template -void -VectorPrediction -::DoUpdateParameters() +void VectorPrediction::DoUpdateParameters() { - if ( HasValue("in") ) + if (HasValue("in")) { std::string shapefile = GetParameterString("in"); otb::ogr::DataSource::Pointer ogrDS; - ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read); - otb::ogr::Layer layer = ogrDS->GetLayer(0); - OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); + 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++) + for (int iField = 0; iField < layerDefn.GetFieldCount(); iField++) { std::string item = layerDefn.GetFieldDefn(iField)->GetNameRef(); std::string key(item); - key.erase( std::remove_if(key.begin(),key.end(),IsNotAlphaNum), key.end()); + key.erase(std::remove_if(key.begin(), key.end(), IsNotAlphaNum), key.end()); std::transform(key.begin(), key.end(), key.begin(), tolower); OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); - if(fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) - { - std::string tmpKey="feat."+key; - AddChoice(tmpKey,item); - } + if (fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) + { + std::string tmpKey = "feat." + key; + AddChoice(tmpKey, item); + } } } } template -void -VectorPrediction -::DoExecute() +void VectorPrediction::DoExecute() { 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); + otb::ogr::Layer layer = source->GetLayer(0); typename ListSampleType::Pointer input = ListSampleType::New(); const int nbFeatures = GetSelectedItems("feat").size(); input->SetMeasurementVectorSize(nbFeatures); - otb::ogr::Layer::const_iterator it = layer.cbegin(); + otb::ogr::Layer::const_iterator it = layer.cbegin(); otb::ogr::Layer::const_iterator itEnd = layer.cend(); - for( ; it!=itEnd ; ++it) - { + for (; it != itEnd; ++it) + { MeasurementType mv; mv.SetSize(nbFeatures); - for(int idx=0; idx < nbFeatures; ++idx) - { + for (int idx = 0; idx < nbFeatures; ++idx) + { // Beware that itemIndex differs from ogr layer field index unsigned int itemIndex = GetSelectedItems("feat")[idx]; - std::string fieldName = GetChoiceNames( "feat" )[itemIndex]; + std::string fieldName = GetChoiceNames("feat")[itemIndex]; switch ((*it)[fieldName].GetType()) { case OFTInteger: @@ -120,30 +114,28 @@ VectorPrediction default: itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); } - - - } - input->PushBack(mv); } + input->PushBack(mv); + } // Statistics for shift/scale MeasurementType meanMeasurementVector; MeasurementType stddevMeasurementVector; if (HasValue("instat") && IsParameterEnabled("instat")) - { + { typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); - std::string XMLfile = GetParameterString("instat"); + std::string XMLfile = GetParameterString("instat"); statisticsReader->SetFileName(XMLfile); - meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); - } + } else - { + { meanMeasurementVector.SetSize(nbFeatures); meanMeasurementVector.Fill(0.); stddevMeasurementVector.SetSize(nbFeatures); stddevMeasurementVector.Fill(1.); - } + } typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); trainingShiftScaleFilter->SetInput(input); @@ -154,13 +146,12 @@ VectorPrediction otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); otbAppLogINFO("Loading model"); - m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), - MachineLearningModelFactoryType::ReadMode); + m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), MachineLearningModelFactoryType::ReadMode); if (m_Model.IsNull()) - { + { otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); - } + } m_Model->SetRegressionMode(RegressionMode); @@ -175,154 +166,151 @@ VectorPrediction typename LabelListSampleType::Pointer target; if (computeConfidenceMap) - { + { quality = ConfidenceListSampleType::New(); - target = m_Model->PredictBatch(listSample, quality); - } - else - { + target = m_Model->PredictBatch(listSample, quality); + } + else + { target = m_Model->PredictBatch(listSample); - } + } ogr::DataSource::Pointer output; - ogr::DataSource::Pointer buffer = ogr::DataSource::New(); - bool updateMode = false; + ogr::DataSource::Pointer buffer = ogr::DataSource::New(); + bool updateMode = false; if (IsParameterEnabled("out") && HasValue("out")) - { + { // Create new OGRDataSource - output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); - otb::ogr::Layer newLayer = output->CreateLayer( - GetParameterString("out"), - const_cast(layer.GetSpatialRef()), - layer.GetGeomType()); + output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); + otb::ogr::Layer newLayer = output->CreateLayer(GetParameterString("out"), const_cast(layer.GetSpatialRef()), layer.GetGeomType()); // Copy existing fields - OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); - for (int k=0 ; kCopyLayer(inputLayer, std::string("Buffer")); + layer = buffer->CopyLayer(inputLayer, std::string("Buffer")); // close input data source source->Clear(); // Re-open input data source in update mode output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); - } + } otb::ogr::Layer outLayer = output->GetLayer(0); OGRErr errStart = outLayer.ogr().StartTransaction(); if (errStart != OGRERR_NONE) - { + { itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); - } + } - OGRFeatureDefn &layerDefn = layer.GetLayerDefn(); + OGRFeatureDefn& layerDefn = layer.GetLayerDefn(); // Add the field of prediction in the output layer if field not exist - + OGRFieldType labelType; - if (RegressionMode==true) + if (RegressionMode == true) labelType = OFTReal; else labelType = OFTInteger; - + int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); if (idx >= 0) { if (layerDefn.GetFieldDefn(idx)->GetType() != labelType) - itkExceptionMacro("Field name "<< GetParameterString("cfield") << " already exists with a different type!"); + itkExceptionMacro("Field name " << GetParameterString("cfield") << " already exists with a different type!"); } else { - OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), labelType); + OGRFieldDefn predictedField(GetParameterString("cfield").c_str(), labelType); ogr::FieldDefn predictedFieldDef(predictedField); outLayer.CreateField(predictedFieldDef); } - + // Add confidence field in the output layer std::string confFieldName("confidence"); if (computeConfidenceMap) - { + { idx = layerDefn.GetFieldIndex(confFieldName.c_str()); if (idx >= 0) - { + { if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal) - itkExceptionMacro("Field name "<< confFieldName << " already exists with a different type!"); - } + itkExceptionMacro("Field name " << confFieldName << " already exists with a different type!"); + } else - { + { OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal); confidenceField.SetWidth(confidenceField.GetWidth()); confidenceField.SetPrecision(confidenceField.GetPrecision()); ogr::FieldDefn confFieldDefn(confidenceField); outLayer.CreateField(confFieldDefn); - } } + } // Fill output layer - unsigned int count=0; - std::string classfieldname = GetParameterString("cfield"); - it = layer.cbegin(); - itEnd = layer.cend(); - for( ; it!=itEnd ; ++it, ++count) - { + unsigned int count = 0; + std::string classfieldname = GetParameterString("cfield"); + it = layer.cbegin(); + itEnd = layer.cend(); + for (; it != itEnd; ++it, ++count) + { ogr::Feature dstFeature(outLayer.GetLayerDefn()); - dstFeature.SetFrom( *it , TRUE); + dstFeature.SetFrom(*it, TRUE); dstFeature.SetFID(it->GetFID()); switch (dstFeature[classfieldname].GetType()) - { - case OFTInteger: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTInteger64: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTReal: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTString: - dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); - break; - default: - itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); - } + { + case OFTInteger: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTInteger64: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTReal: + dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + break; + case OFTString: + dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); + break; + default: + itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); + } if (computeConfidenceMap) dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); if (updateMode) - { + { outLayer.SetFeature(dstFeature); - } + } else - { + { outLayer.CreateFeature(dstFeature); - } } + } - if(outLayer.ogr().TestCapability("Transactions")) - { + if (outLayer.ogr().TestCapability("Transactions")) + { const OGRErr errCommitX = outLayer.ogr().CommitTransaction(); if (errCommitX != OGRERR_NONE) - { + { itkExceptionMacro(<< "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."); + otbAppLogINFO("Elapsed: " << ((double)(toc - tic) / CLOCKS_PER_SEC) << " seconds."); } -} //end namespace wrapper -} //end namespace otb +} // end namespace wrapper +} // end namespace otb #endif -- GitLab From 4cef056950a4a0128b146a24a55366d47812b734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Mon, 5 Aug 2019 17:59:58 +0200 Subject: [PATCH 16/24] ENH: code review --- .../app/otbVectorRegression.cxx | 2 +- .../include/otbVectorPrediction.h | 36 ++++----- .../include/otbVectorPrediction.hxx | 77 ++++++++----------- 3 files changed, 49 insertions(+), 66 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx index d1b8a02f66..d4e23d4e49 100644 --- a/Modules/Applications/AppClassification/app/otbVectorRegression.cxx +++ b/Modules/Applications/AppClassification/app/otbVectorRegression.cxx @@ -93,7 +93,7 @@ void VectorRegression::DoInitSpecialization() SetOfficialDocLink(); } -// Confidence map computation is not support for regression. +// Confidence map computation is not supported for regression. template <> bool VectorRegression::shouldComputeConfidenceMap() const { diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 12cea01487..916ace1ea6 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -49,36 +49,36 @@ class VectorPrediction : public Application { public: /** Standard class typedefs. */ - typedef VectorPrediction Self; - typedef Application Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; + using Self = VectorPrediction; + using Superclass = Application; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer; /** Standard macro */ itkNewMacro(Self); itkTypeMacro(Self, Application) - /** Filters typedef */ - typedef float ValueType; + /** Filters typedef */ + using ValueType = float; // Label type is float for regression and unsigned int for classification - typedef typename std::conditional::type LabelType; + using LabelType = typename std::conditional::type; - typedef itk::FixedArray LabelSampleType; - typedef itk::Statistics::ListSample LabelListSampleType; + using LabelSampleType = itk::FixedArray; + using LabelListSampleType = itk::Statistics::ListSample; - typedef otb::MachineLearningModel MachineLearningModelType; - typedef otb::MachineLearningModelFactory MachineLearningModelFactoryType; - typedef typename MachineLearningModelType::Pointer ModelPointerType; - typedef typename MachineLearningModelType::ConfidenceListSampleType ConfidenceListSampleType; + using MachineLearningModelType = otb::MachineLearningModel; + using MachineLearningModelFactoryType = otb::MachineLearningModelFactory; + using ModelPointerType = typename MachineLearningModelType::Pointer; + using ConfidenceListSampleType = typename MachineLearningModelType::ConfidenceListSampleType; /** Statistics Filters typedef */ - typedef itk::VariableLengthVector MeasurementType; - typedef otb::StatisticsXMLFileReader StatisticsReader; + using MeasurementType = itk::VariableLengthVector; + using StatisticsReader = otb::StatisticsXMLFileReader; - typedef itk::VariableLengthVector InputSampleType; - typedef itk::Statistics::ListSample ListSampleType; - typedef otb::Statistics::ShiftScaleSampleListFilter ShiftScaleFilterType; + using InputSampleType = itk::VariableLengthVector; + using ListSampleType = itk::Statistics::ListSample; + using ShiftScaleFilterType = otb::Statistics::ShiftScaleSampleListFilter; ~VectorPrediction() override { diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 1310fdfb29..4d84e9e0fc 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -47,24 +47,23 @@ void VectorPrediction::DoUpdateParameters() { if (HasValue("in")) { - std::string shapefile = GetParameterString("in"); + auto shapefileName = GetParameterString("in"); - otb::ogr::DataSource::Pointer ogrDS; - - ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read); - otb::ogr::Layer layer = ogrDS->GetLayer(0); + auto ogrDS = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read); + auto 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(); + auto fieldDefn = layerDefn.GetFieldDefn(iField); + std::string item = fieldDefn->GetNameRef(); std::string key(item); key.erase(std::remove_if(key.begin(), key.end(), IsNotAlphaNum), key.end()); std::transform(key.begin(), key.end(), key.begin(), tolower); - OGRFieldType fieldType = layerDefn.GetFieldDefn(iField)->GetType(); + auto fieldType = fieldDefn->GetType(); if (fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) { std::string tmpKey = "feat." + key; @@ -77,21 +76,17 @@ void VectorPrediction::DoUpdateParameters() template void VectorPrediction::DoExecute() { - clock_t tic = clock(); + auto shapefileName = GetParameterString("in"); - 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); + auto source = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read); + auto layer = source->GetLayer(0); typename ListSampleType::Pointer input = ListSampleType::New(); const int nbFeatures = GetSelectedItems("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) + for (auto const& feature : layer) { MeasurementType mv; mv.SetSize(nbFeatures); @@ -100,19 +95,18 @@ void VectorPrediction::DoExecute() // Beware that itemIndex differs from ogr layer field index unsigned int itemIndex = GetSelectedItems("feat")[idx]; std::string fieldName = GetChoiceNames("feat")[itemIndex]; - switch ((*it)[fieldName].GetType()) + + auto field = feature[fieldName]; + switch (field.GetType()) { - case OFTInteger: - mv[idx] = static_cast((*it)[fieldName].GetValue()); - break; - case OFTInteger64: - mv[idx] = static_cast((*it)[fieldName].GetValue()); + case OFTInteger || OFTInteger64: + mv[idx] = static_cast(field.template GetValue()); break; case OFTReal: - mv[idx] = static_cast((*it)[fieldName].GetValue()); + mv[idx] = static_cast(field.template GetValue()); break; default: - itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << "."); + itkExceptionMacro(<< "incorrect field type: " << field.GetType() << "."); } } input->PushBack(mv); @@ -202,7 +196,7 @@ void VectorPrediction::DoExecute() // close input data source source->Clear(); // Re-open input data source in update mode - output = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Update_LayerUpdate); + output = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Update_LayerUpdate); } otb::ogr::Layer outLayer = output->GetLayer(0); @@ -217,11 +211,7 @@ void VectorPrediction::DoExecute() // Add the field of prediction in the output layer if field not exist - OGRFieldType labelType; - if (RegressionMode == true) - labelType = OFTReal; - else - labelType = OFTInteger; + const OGRFieldType labelType = RegressionMode ? OFTReal : OFTInteger; int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); if (idx >= 0) @@ -259,29 +249,25 @@ void VectorPrediction::DoExecute() // Fill output layer unsigned int count = 0; std::string classfieldname = GetParameterString("cfield"); - it = layer.cbegin(); - itEnd = layer.cend(); - for (; it != itEnd; ++it, ++count) + for (auto const& feature : layer) { ogr::Feature dstFeature(outLayer.GetLayerDefn()); - dstFeature.SetFrom(*it, TRUE); - dstFeature.SetFID(it->GetFID()); - switch (dstFeature[classfieldname].GetType()) + dstFeature.SetFrom(feature, TRUE); + dstFeature.SetFID(feature.GetFID()); + auto field = dstFeature[classfieldname]; + switch (field.GetType()) { - case OFTInteger: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); - break; - case OFTInteger64: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + case OFTInteger || OFTInteger64: + field.template SetValue(target->GetMeasurementVector(count)[0]); break; case OFTReal: - dstFeature[classfieldname].SetValue(target->GetMeasurementVector(count)[0]); + field.template SetValue(target->GetMeasurementVector(count)[0]); break; case OFTString: - dstFeature[classfieldname].SetValue(std::to_string(target->GetMeasurementVector(count)[0])); + field.template SetValue(std::to_string(target->GetMeasurementVector(count)[0])); break; default: - itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << "."); + itkExceptionMacro(<< "incorrect field type: " << field.GetType() << "."); } if (computeConfidenceMap) dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); @@ -305,9 +291,6 @@ void VectorPrediction::DoExecute() } output->SyncToDisk(); - - clock_t toc = clock(); - otbAppLogINFO("Elapsed: " << ((double)(toc - tic) / CLOCKS_PER_SEC) << " seconds."); } } // end namespace wrapper -- GitLab From ed03452aa57738d412e9e896ef5d6ab5b5c187c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 6 Aug 2019 10:28:40 +0200 Subject: [PATCH 17/24] BUG: fix factorized switch case --- .../AppClassification/include/otbVectorPrediction.hxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 4d84e9e0fc..00f1de167e 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -99,7 +99,8 @@ void VectorPrediction::DoExecute() auto field = feature[fieldName]; switch (field.GetType()) { - case OFTInteger || OFTInteger64: + case OFTInteger: + case OFTInteger64: mv[idx] = static_cast(field.template GetValue()); break; case OFTReal: @@ -257,7 +258,8 @@ void VectorPrediction::DoExecute() auto field = dstFeature[classfieldname]; switch (field.GetType()) { - case OFTInteger || OFTInteger64: + case OFTInteger64: + case OFTInteger: field.template SetValue(target->GetMeasurementVector(count)[0]); break; case OFTReal: -- GitLab From 6d4875166e94aa743363b2e41031edcd7204c51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 6 Aug 2019 11:16:50 +0200 Subject: [PATCH 18/24] REFAC: replace IsAlphaNum() by a lambda --- .../AppClassification/app/otbComputeConfusionMatrix.cxx | 7 +------ .../AppClassification/app/otbPolygonClassStatistics.cxx | 8 +------- .../AppClassification/app/otbSampleExtraction.cxx | 8 +------- .../AppClassification/app/otbSampleSelection.cxx | 9 +-------- .../AppClassification/include/otbTrainVectorBase.h | 6 ------ .../AppClassification/include/otbTrainVectorBase.hxx | 2 +- .../AppClassification/include/otbVectorPrediction.h | 6 ------ .../AppClassification/include/otbVectorPrediction.hxx | 3 +-- .../app/otbVectorDimensionalityReduction.cxx | 9 +-------- 9 files changed, 7 insertions(+), 51 deletions(-) diff --git a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx index 756ea62890..18b9afc245 100644 --- a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx +++ b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx @@ -37,11 +37,6 @@ namespace otb { namespace Wrapper { -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } class ComputeConfusionMatrix : public Application { @@ -198,7 +193,7 @@ private: { std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef(); key = item; - std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum); + std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);}); std::transform(key.begin(), end, key.begin(), tolower); OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType(); diff --git a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx index c4ca1ab834..db4aca185f 100644 --- a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx +++ b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx @@ -32,12 +32,6 @@ namespace otb namespace Wrapper { -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } - class PolygonClassStatistics : public Application { public: @@ -141,7 +135,7 @@ private: { std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef(); key = item; - std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum); + std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);}); std::transform(key.begin(), end, key.begin(), tolower); OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType(); diff --git a/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx b/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx index b94130d3f5..473a82b3b0 100644 --- a/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx +++ b/Modules/Applications/AppClassification/app/otbSampleExtraction.cxx @@ -27,12 +27,6 @@ namespace otb { namespace Wrapper { -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } - class SampleExtraction : public Application { public: @@ -139,7 +133,7 @@ private: { std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef(); key = item; - std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum); + std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);}); std::transform(key.begin(), end, key.begin(), tolower); OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType(); diff --git a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx index c2bc93f144..d4770c4d1d 100644 --- a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx +++ b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx @@ -32,13 +32,6 @@ namespace otb { namespace Wrapper { - -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } - class SampleSelection : public Application { public: @@ -243,7 +236,7 @@ private: { std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef(); key = item; - std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum); + std::string::iterator end = std::remove_if(key.begin(), key.end(), [](char c){return !std::isalnum(c);}); std::transform(key.begin(), end, key.begin(), tolower); OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType(); diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.h b/Modules/Applications/AppClassification/include/otbTrainVectorBase.h index 24b731cbd6..d58b536468 100644 --- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.h +++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.h @@ -43,12 +43,6 @@ namespace otb namespace Wrapper { -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) -{ - return !std::isalnum( c ); -} - template class TrainVectorBase : public LearningApplicationBase { diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx b/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx index eaaa8bee31..ff2947dc7b 100644 --- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx +++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx @@ -124,7 +124,7 @@ TrainVectorBase { std::string key, item = feature.ogr().GetFieldDefnRef( iField )->GetNameRef(); key = item; - std::string::iterator end = std::remove_if( key.begin(), key.end(), IsNotAlphaNum ); + std::string::iterator end = std::remove_if( key.begin(), key.end(), [](char c){return !std::isalnum(c);} ); std::transform( key.begin(), end, key.begin(), tolower ); OGRFieldType fieldType = feature.ogr().GetFieldDefnRef( iField )->GetType(); diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index 916ace1ea6..d895324665 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -86,12 +86,6 @@ public: } private: - /** Utility function to negate std::isalnum */ - static bool IsNotAlphaNum(char c) - { - return !std::isalnum(c); - } - void DoInit() override; /** Method defining the parameters used in the application and their documentation, specialized for RegressionMode=1 and RegrssionMode=0 */ diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 00f1de167e..c46a11a1aa 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -60,9 +60,8 @@ void VectorPrediction::DoUpdateParameters() auto fieldDefn = layerDefn.GetFieldDefn(iField); std::string item = fieldDefn->GetNameRef(); std::string key(item); - key.erase(std::remove_if(key.begin(), key.end(), IsNotAlphaNum), key.end()); + key.erase(std::remove_if(key.begin(), key.end(), [](char c){return !std::isalnum(c);}), key.end()); std::transform(key.begin(), key.end(), key.begin(), tolower); - auto fieldType = fieldDefn->GetType(); if (fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal) { diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx index 2629ce7159..d3c4a29b45 100644 --- a/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx +++ b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx @@ -32,13 +32,6 @@ namespace otb { namespace Wrapper { - -/** Utility function to negate std::isalnum */ -bool IsNotAlphaNum(char c) -{ -return !std::isalnum(c); -} - /** * \class VectorDimensionalityReduction * @@ -180,7 +173,7 @@ private: { std::string item = layerDefn.GetFieldDefn(iField)->GetNameRef(); std::string key(item); - std::string::iterator end = std::remove_if( key.begin(), key.end(), IsNotAlphaNum ); + std::string::iterator end = std::remove_if( key.begin(), key.end(), [](char c){return !std::isalnum(c);}); std::transform( key.begin(), end, key.begin(), tolower ); std::string tmpKey = "feat." + key.substr( 0, static_cast( end - key.begin() ) ); AddChoice(tmpKey,item); -- GitLab From ac700e25c20a7f21541e93ff6f7f817a8fc06893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 6 Aug 2019 14:45:54 +0200 Subject: [PATCH 19/24] STYLE: replace 0.0 by NOTOL --- Modules/Applications/AppClassification/test/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt index 3822967fc7..b47c420c21 100644 --- a/Modules/Applications/AppClassification/test/CMakeLists.txt +++ b/Modules/Applications/AppClassification/test/CMakeLists.txt @@ -716,7 +716,7 @@ if(OTB_USE_OPENCV) -out ${TEMP}/apTvClSVMLabeledVector.shp -feat meanB0 meanB1 meanB2 meanB3 varB0 varB1 varB2 varB3 -cfield class - VALID --compare-ogr 0.0 + VALID --compare-ogr ${NOTOL} ${OTBAPP_BASELINE_FILES}/apTvClSVMLabeledVector.shp ${TEMP}/apTvClSVMLabeledVector.shp) endif() @@ -730,7 +730,7 @@ if(OTB_USE_OPENCV) -out ${TEMP}/apTvClDTVectorRegression.sqlite -feat value_0 value_1 value_2 value_3 -cfield predicted - VALID --compare-ogr 0.0 + VALID --compare-ogr ${NOTOL} ${OTBAPP_BASELINE_FILES}/apTvClDTVectorRegression.sqlite ${TEMP}/apTvClDTVectorRegression.sqlite) endif() -- GitLab From 94a6cd4cd211aa66a842b172283cbd7b8c684809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 6 Aug 2019 14:46:32 +0200 Subject: [PATCH 20/24] BUG: increment the count variable at the end of the range based for loop --- .../AppClassification/include/otbVectorPrediction.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index c46a11a1aa..d4de8f2a70 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -280,6 +280,7 @@ void VectorPrediction::DoExecute() { outLayer.CreateFeature(dstFeature); } + count++; } if (outLayer.ogr().TestCapability("Transactions")) -- GitLab From dd4a2451208bfc9814ea4f8c3bcbf54d033626de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Tue, 6 Aug 2019 17:09:02 +0200 Subject: [PATCH 21/24] PERF: initialize the variable length vector with a size parameter --- .../AppClassification/include/otbVectorPrediction.hxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index d4de8f2a70..20d8d357aa 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -87,8 +87,7 @@ void VectorPrediction::DoExecute() for (auto const& feature : layer) { - MeasurementType mv; - mv.SetSize(nbFeatures); + MeasurementType mv(nbFeatures); for (int idx = 0; idx < nbFeatures; ++idx) { // Beware that itemIndex differs from ogr layer field index -- GitLab From f5c47b7387166d53cb3e9e65895c4aa16e66c5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Wed, 7 Aug 2019 16:00:53 +0200 Subject: [PATCH 22/24] PERF: pass string by const reference instead of copy --- .../include/otbWrapperApplication.h | 286 +++++++++--------- .../include/otbWrapperApplication.hxx | 4 +- .../src/otbWrapperApplication.cxx | 230 +++++++------- 3 files changed, 260 insertions(+), 260 deletions(-) diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h index a192638083..ab2ef3c0d3 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h @@ -152,72 +152,72 @@ public: /* Get the internal application parameter specified * if the follow flag is on, the function returns the target of proxy parameters * WARNING: this method may disappear from the API */ - Parameter* GetParameterByKey(std::string parameter, bool follow=true); + Parameter* GetParameterByKey(std::string const& parameter, bool follow=true); /* Get the internal application parameter specified * * WARNING: this method may disappear from the API */ - const Parameter* GetParameterByKey(std::string parameter, bool follow=true) const; + const Parameter* GetParameterByKey(std::string const& parameter, bool follow=true) const; /* Returns the description of a parameter */ - std::string GetParameterName(std::string paramKey); + std::string GetParameterName(std::string const& paramKey); /* Returns the description of a parameter */ - std::string GetParameterDescription(std::string paramKey); + std::string GetParameterDescription(std::string const& paramKey); /* Set the description of a parameter */ - void SetParameterDescription(std::string paramKey, std::string dec); + void SetParameterDescription(std::string const& paramKey, std::string dec); /* Enable the use of an optional parameter. Returns the previous state */ - void EnableParameter(std::string paramKey); + void EnableParameter(std::string const& paramKey); /* Disable the use of an optional parameter. Returns the previous state */ - void DisableParameter(std::string paramKey); + void DisableParameter(std::string const& paramKey); /* Return the enable state of an optional parameter */ - bool IsParameterEnabled(std::string paramKey, bool recurseParents = false) const; + bool IsParameterEnabled(std::string const& paramKey, bool recurseParents = false) const; /* Return true if the specified parameter is mandatory */ - bool IsMandatory(std::string paramKey) const; + bool IsMandatory(std::string const& paramKey) const; /* Return true if the specified parameter was set automatically in * the application */ - bool HasAutomaticValue(std::string paramKey) const; + bool HasAutomaticValue(std::string const& paramKey) const; /* Returns true if the parameter has an associated value provided externally * (not automatically computed by the application) */ - bool HasUserValue(std::string paramKey) const; + bool HasUserValue(std::string const& paramKey) const; /* If a user value was provided, clear it and update the other parameters */ - void ClearValue(std::string paramKey); + void ClearValue(std::string const& paramKey); /* Returns true if the parameter has an associated value. * This value can be an automatically computed value or default value, * or a value set externally by user */ - bool HasValue(std::string paramKey) const; + bool HasValue(std::string const& paramKey) const; /** 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); + void SetParameterUserValue(std::string const& paramKey, bool value); /* Return the user level of access to a parameter */ - UserLevel GetParameterUserLevel(std::string paramKey) const; + UserLevel GetParameterUserLevel(std::string const& paramKey) const; /** Get the role of the parameter */ - Role GetParameterRole(std::string paramKey) const; + Role GetParameterRole(std::string const& paramKey) const; /* Get the parameter type from its name */ - ParameterType GetParameterType(std::string paramKey) const; + ParameterType GetParameterType(std::string const& paramKey) const; /* Returns the description of a parameter */ - std::vector GetChoiceKeys(std::string paramKey); + std::vector GetChoiceKeys(std::string const& paramKey); /* Returns the description of a parameter */ - std::vector GetChoiceNames(std::string paramKey); + std::vector GetChoiceNames(std::string const& paramKey); /* Set an integer value * @@ -228,14 +228,14 @@ public: * \li ParameterType_Radius * \li ParameterType_Choice */ - void SetParameterInt(std::string parameter, int value, bool hasUserValueFlag = true); + void SetParameterInt(std::string const& parameter, int value, bool hasUserValueFlag = true); /* Set a floating value * * Can be called for types : * \li ParameterType_Float */ - void SetParameterFloat(std::string parameter, float value, bool hasUserValueFlag = true); + void SetParameterFloat(std::string const& parameter, float value, bool hasUserValueFlag = true); /* Set a string value * @@ -246,7 +246,7 @@ public: * \li ParameterType_StringList * \li ParameterType_ListView */ - void SetParameterString(std::string parameter, std::string value, bool hasUserValueFlag = true); + void SetParameterString(std::string const& parameter, std::string value, bool hasUserValueFlag = true); /* Set a string value * @@ -266,7 +266,7 @@ public: * \li ParameterType_OutputImageParameter * \li ParameterType_OutputVectorDataParameter */ - void SetParameterStringList(std::string parameter, std::vector values, bool hasUserValueFlag = true); + void SetParameterStringList(std::string const& parameter, std::vector values, bool hasUserValueFlag = true); /** Checks if the application is ready to be executed. It checks that there * is no missing parameter @@ -294,7 +294,7 @@ public: * \li ParameterType_Radius * \li ParameterType_Choice */ - void SetDefaultParameterInt(std::string parameter, int value); + void SetDefaultParameterInt(std::string const& parameter, int value); /* Get the default integer value of a parameter * @@ -304,7 +304,7 @@ public: * \li ParameterType_Radius * \li ParameterType_Choice */ - int GetDefaultParameterInt(std::string parameter); + int GetDefaultParameterInt(std::string const& parameter); /* Set a default floating value, must be used in the * DoInit when setting a value by default @@ -313,28 +313,28 @@ public: * Can be called for types : * \li ParameterType_Float */ - void SetDefaultParameterFloat(std::string parameter, float value); + void SetDefaultParameterFloat(std::string const& parameter, float value); /* Get the default floating value of a parameter * * Can be called for types : * \li ParameterType_Float */ - float GetDefaultParameterFloat(std::string parameter); + float GetDefaultParameterFloat(std::string const& parameter); /** Set a default pixel type for an output image parameter * * \param[in] parameter Name of the output image parameter * \param[in] type Default pixel type */ - void SetDefaultOutputPixelType(std::string parameter, ImagePixelType type); + void SetDefaultOutputPixelType(std::string const& parameter, ImagePixelType type); /** Set a default complex pixel type for an output complex image parameter * * \param[in] parameter Name of the output complex image parameter * \param[in] type Default complex pixel type */ - void SetDefaultOutputComplexPixelType(std::string parameter, ComplexImagePixelType type); + void SetDefaultOutputComplexPixelType(std::string const& parameter, ComplexImagePixelType type); /* Set a minimum int value, must used in the * DoInit when setting a value by default @@ -343,7 +343,7 @@ public: * Can be called for types : * \li ParameterType_Int */ - void SetMinimumParameterIntValue(std::string parameter, int value); + void SetMinimumParameterIntValue(std::string const& parameter, int value); /* Set a maximum int value, must used in the * DoInit when setting a value by default @@ -352,7 +352,7 @@ public: * Can be called for types : * \li ParameterType_Int */ - void SetMaximumParameterIntValue(std::string parameter, int value); + void SetMaximumParameterIntValue(std::string const& parameter, int value); /* Set a minimum int value, must used in the * DoInit when setting a value by default @@ -361,7 +361,7 @@ public: * Can be called for types : * \li ParameterType_Float */ - void SetMinimumParameterFloatValue(std::string parameter, float value); + void SetMinimumParameterFloatValue(std::string const& parameter, float value); /* Set a maximum int value, must used in the * DoInit when setting a value by default @@ -370,7 +370,7 @@ public: * Can be called for types : * \li ParameterType_Float */ - void SetMaximumParameterFloatValue(std::string parameter, float value); + void SetMaximumParameterFloatValue(std::string const& parameter, float value); /** @@ -380,7 +380,7 @@ public: * Can be called for types: * \li ParameterType_ListView */ - void SetListViewSingleSelectionMode(std::string parameter, bool status); + void SetListViewSingleSelectionMode(std::string const& parameter, bool status); /** * True if the parameter is a list view and is in single selection mode @@ -395,21 +395,21 @@ public: * Can be called for types : * \li ParameterType_OutputImage */ - void SetParameterOutputImage(std::string parameter, FloatVectorImageType* value); + void SetParameterOutputImage(std::string const& parameter, FloatVectorImageType* value); /* Set the pixel type in which the image will be saved * * Can be called for types : * \li ParameterType_OutputImage */ - void SetParameterOutputImagePixelType(std::string parameter, ImagePixelType pixelType); + void SetParameterOutputImagePixelType(std::string const& parameter, ImagePixelType pixelType); /* Set an output vector data value * * Can be called for types : * \li ParameterType_OutputVectorData */ - void SetParameterOutputVectorData(std::string parameter, VectorDataType* value); + void SetParameterOutputVectorData(std::string const& parameter, VectorDataType* value); /* Get an integer parameter value * @@ -420,14 +420,14 @@ public: * \li ParameterType_Radius * \li ParameterType_Choice */ - int GetParameterInt(std::string parameter) const; + int GetParameterInt(std::string const& parameter) const; /* Get a floating parameter value * * Can be called for types : * \li ParameterType_Float */ - float GetParameterFloat(std::string parameter) const; + float GetParameterFloat(std::string const& parameter) const; /* Get a string parameter value * @@ -441,7 +441,7 @@ public: * \li ParameterType_OutputImage * \li ParameterType_OutputVectorData */ - std::string GetParameterString(std::string parameter) const; + std::string GetParameterString(std::string const& parameter) const; /* Get a string list parameter value * @@ -470,7 +470,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageParameter */ - void SetParameterInputImage(std::string parameter, ImageBaseType * inputImage); + void SetParameterInputImage(std::string const& parameter, ImageBaseType * inputImage); /** * Get the output image parameter as an ImageBase * instead @@ -481,7 +481,7 @@ public: * \throw itk::Exception if parameter is not found or not an * OutputImageParameter */ - ImageBaseType * GetParameterOutputImage(std::string parameter); + ImageBaseType * GetParameterOutputImage(std::string const& parameter); /** * Add an image to an InputImageList parameter as an ImageBase @@ -492,7 +492,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter */ - void AddImageToParameterInputImageList(std::string parameter, ImageBaseType * img); + void AddImageToParameterInputImageList(std::string const& parameter, ImageBaseType * img); /** * Set the nth image of an InputImageList parameter as an ImageBase pointer @@ -504,7 +504,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter or if id is out of bounds */ - void SetNthParameterInputImageList(std::string parameter, const unsigned int &id, ImageBaseType * img); + void SetNthParameterInputImageList(std::string const& parameter, const unsigned int &id, ImageBaseType * img); /** * Add a value to a parameter list as a string @@ -517,7 +517,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter */ - void AddParameterStringList(std::string parameter, const std::string & str); + void AddParameterStringList(std::string const& parameter, const std::string & str); /** * Set the nth value of a parameter list as a string. @@ -531,7 +531,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter or if id is out of bounds */ - void SetNthParameterStringList(std::string parameter, const unsigned int &id, const std::string& str); + void SetNthParameterStringList(std::string const& parameter, const unsigned int &id, const std::string& str); /** @@ -541,7 +541,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter */ - void ClearParameterInputImageList(std::string parameter); + void ClearParameterInputImageList(std::string const& parameter); /** * Get the number of images in an InputImageList parameter. @@ -550,7 +550,7 @@ public: * \throw itk::Exception if parameter is not found or not an * InputImageList parameter */ - unsigned int GetNumberOfElementsInParameterInputImageList(std::string parameter); + unsigned int GetNumberOfElementsInParameterInputImageList(std::string const& parameter); /* Get an image value @@ -558,35 +558,35 @@ public: * Can be called for types : * \li ParameterType_InputImage */ - FloatVectorImageType* GetParameterImage(std::string parameter); - - UInt8ImageType * GetParameterUInt8Image(std::string); - UInt16ImageType * GetParameterUInt16Image(std::string); - Int16ImageType * GetParameterInt16Image(std::string); - UInt32ImageType * GetParameterUInt32Image(std::string); - Int32ImageType * GetParameterInt32Image(std::string); - FloatImageType * GetParameterFloatImage(std::string); - DoubleImageType * GetParameterDoubleImage(std::string); - UInt8VectorImageType * GetParameterUInt8VectorImage(std::string); - UInt16VectorImageType * GetParameterUInt16VectorImage(std::string); - Int16VectorImageType * GetParameterInt16VectorImage(std::string); - UInt32VectorImageType * GetParameterUInt32VectorImage(std::string); - Int32VectorImageType * GetParameterInt32VectorImage(std::string); - FloatVectorImageType * GetParameterFloatVectorImage(std::string); - DoubleVectorImageType * GetParameterDoubleVectorImage(std::string); - UInt8RGBImageType * GetParameterUInt8RGBImage(std::string); - UInt8RGBAImageType * GetParameterUInt8RGBAImage(std::string); + FloatVectorImageType* GetParameterImage(std::string const& parameter); + + UInt8ImageType * GetParameterUInt8Image(std::string const&); + UInt16ImageType * GetParameterUInt16Image(std::string const&); + Int16ImageType * GetParameterInt16Image(std::string const&); + UInt32ImageType * GetParameterUInt32Image(std::string const&); + Int32ImageType * GetParameterInt32Image(std::string const&); + FloatImageType * GetParameterFloatImage(std::string const&); + DoubleImageType * GetParameterDoubleImage(std::string const&); + UInt8VectorImageType * GetParameterUInt8VectorImage(std::string const&); + UInt16VectorImageType * GetParameterUInt16VectorImage(std::string const&); + Int16VectorImageType * GetParameterInt16VectorImage(std::string const&); + UInt32VectorImageType * GetParameterUInt32VectorImage(std::string const&); + Int32VectorImageType * GetParameterInt32VectorImage(std::string const&); + FloatVectorImageType * GetParameterFloatVectorImage(std::string const&); + DoubleVectorImageType * GetParameterDoubleVectorImage(std::string const&); + UInt8RGBImageType * GetParameterUInt8RGBImage(std::string const&); + UInt8RGBAImageType * GetParameterUInt8RGBAImage(std::string const&); // Complex image - ComplexInt16ImageType * GetParameterComplexInt16Image(std::string); - ComplexInt32ImageType * GetParameterComplexInt32Image(std::string); - ComplexFloatImageType * GetParameterComplexFloatImage(std::string); - ComplexDoubleImageType * GetParameterComplexDoubleImage(std::string); + ComplexInt16ImageType * GetParameterComplexInt16Image(std::string const&); + ComplexInt32ImageType * GetParameterComplexInt32Image(std::string const&); + ComplexFloatImageType * GetParameterComplexFloatImage(std::string const&); + ComplexDoubleImageType * GetParameterComplexDoubleImage(std::string const&); - ComplexInt16VectorImageType * GetParameterComplexInt16VectorImage(std::string); - ComplexInt32VectorImageType * GetParameterComplexInt32VectorImage(std::string); - ComplexFloatVectorImageType * GetParameterComplexFloatVectorImage(std::string); - ComplexDoubleVectorImageType * GetParameterComplexDoubleVectorImage(std::string); + ComplexInt16VectorImageType * GetParameterComplexInt16VectorImage(std::string const&); + ComplexInt32VectorImageType * GetParameterComplexInt32VectorImage(std::string const&); + ComplexFloatVectorImageType * GetParameterComplexFloatVectorImage(std::string const&); + ComplexDoubleVectorImageType * GetParameterComplexDoubleVectorImage(std::string const&); /* Get an image list value @@ -594,7 +594,7 @@ public: * Can be called for types : * \li ParameterType_InputImageList */ - FloatVectorImageListType* GetParameterImageList(std::string parameter); + FloatVectorImageListType* GetParameterImageList(std::string const& parameter); /* GetParameterVectorData * @@ -602,7 +602,7 @@ public: * \li ParameterType_InputVectorData */ - VectorDataType* GetParameterVectorData(std::string parameter); + VectorDataType* GetParameterVectorData(std::string const& parameter); /* GetParameteVetorDataList * @@ -610,7 +610,7 @@ public: * \li ParameterType_InputVectorDatalist */ - VectorDataListType* GetParameterVectorDataList(std::string parameter); + VectorDataListType* GetParameterVectorDataList(std::string const& parameter); /* Get the parameter as a std::string * @@ -628,7 +628,7 @@ public: * \li ParameterType_OutputImage * \li ParameterType_OutputVectorData */ - std::string GetParameterAsString(std::string paramKey); + std::string GetParameterAsString(std::string const& paramKey); /* Get the list of all parameters */ @@ -639,7 +639,7 @@ public: * Can be called for types : * \li ParameterType_OutputImage */ - ImagePixelType GetParameterOutputImagePixelType(std::string parameter); + ImagePixelType GetParameterOutputImagePixelType(std::string const& parameter); void SetParameterList(ParameterGroup::Pointer paramGroup) { @@ -797,43 +797,43 @@ protected: void AddProcess(itk::ProcessObject* object, std::string description); /** Add a new choice value to an existing choice parameter */ - void AddChoice(std::string paramKey, std::string paramName); + void AddChoice(std::string const& paramKey, std::string const& paramName); /** Add a new parameter to the parameter group * the parent key of paramKey can be the path to a parameter group * or the path to a choice value */ - void AddParameter(ParameterType type, std::string paramKey, std::string paramName); + void AddParameter(ParameterType type, std::string const& paramKey, std::string const& paramName); /** Add a parameterRAM method with no parameter*/ - void AddRAMParameter(std::string paramKey="ram"); + void AddRAMParameter(std::string const& paramKey="ram"); /** Add a parameterRAM method with parameter*/ - void AddRAMParameter(std::string paramKey, std::string paramName, unsigned int defaultValue); + void AddRAMParameter(std::string const& paramKey, std::string const& paramName, unsigned int defaultValue); /** Add a parameterRAND method with no parameter*/ - void AddRANDParameter(std::string paramKey="rand"); + void AddRANDParameter(std::string const& paramKey="rand"); /** Add a parameterRAND method with parameter * by default seed initialization is based on time value*/ - void AddRANDParameter(std::string paramKey, std::string paramName, unsigned int defaultValue); + void AddRANDParameter(std::string const& paramKey, std::string const& paramName, unsigned int defaultValue); /** Remove the items added to the ListWidget */ - void ClearChoices(std::string key); + void ClearChoices(std::string const& key); /** Get Items selected in the ListView Parameter*/ - std::vector GetSelectedItems(std::string paramKey); + std::vector GetSelectedItems(std::string const& paramKey); /** Declare a parameter as mandatory */ - void MandatoryOn(std::string paramKey); + void MandatoryOn(std::string const& paramKey); /** Declare a parameter as NOT mandatory (default state) */ - void MandatoryOff(std::string paramKey); + void MandatoryOff(std::string const& paramKey); /* Set the user level of access to a parameter */ - void SetParameterUserLevel(std::string paramKey, UserLevel level); + void SetParameterUserLevel(std::string const& paramKey, UserLevel level); /* Set the parameter role (input/output) */ - void SetParameterRole(std::string paramKey, Role role); + void SetParameterRole(std::string const& paramKey, Role role); /* Get an image value * @@ -841,13 +841,13 @@ protected: * \li ParameterType_InputImage */ template - TImageType* GetParameterImage(std::string parameter); + TImageType* GetParameterImage(std::string const& parameter); /** Declare a parameter as having an automatic value */ - void AutomaticValueOn(std::string paramKey); + void AutomaticValueOn(std::string const& paramKey); /** Declare a parameter as NOT having an automatic value */ - void AutomaticValueOff(std::string paramKey); + void AutomaticValueOff(std::string const& paramKey); /* Set an output image value * @@ -855,7 +855,7 @@ protected: * \li ParameterType_OutputImage */ template - void SetParameterOutputImage(std::string parameter, TImageType* value); + void SetParameterOutputImage(std::string const& parameter, TImageType* value); private: /* Implement this method to add parameters */ @@ -937,77 +937,77 @@ namespace otb namespace Wrapper { -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8VectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE Int16VectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt16VectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE Int32VectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt32VectorImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8VectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE Int16VectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt16VectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE Int32VectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt32VectorImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE FloatVectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE DoubleVectorImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE FloatVectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE DoubleVectorImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt16VectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt32VectorImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt16VectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt32VectorImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexFloatVectorImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexDoubleVectorImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexFloatVectorImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexDoubleVectorImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8RGBImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8RGBAImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8RGBImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8RGBAImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8ImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE Int16ImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt16ImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE Int32ImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt32ImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt8ImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE Int16ImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt16ImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE Int32ImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE UInt32ImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE FloatImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE DoubleImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE FloatImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE DoubleImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt16ImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt32ImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt16ImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexInt32ImageType* Application::GetParameterImage(std::string const&); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexFloatImageType* Application::GetParameterImage(std::string); -extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexDoubleImageType* Application::GetParameterImage(std::string); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexFloatImageType* Application::GetParameterImage(std::string const&); +extern template OTBApplicationEngine_EXPORT_TEMPLATE ComplexDoubleImageType* Application::GetParameterImage(std::string const&); // -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int16VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt16VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int32VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt32VectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8VectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int16VectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt16VectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int32VectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt32VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, FloatVectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, DoubleVectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, FloatVectorImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, DoubleVectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt16VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt32VectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexFloatVectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexDoubleVectorImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8RGBImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8RGBAImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8RGBImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8RGBAImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int16ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt16ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int32ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt32ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int16ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt16ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int32ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt32ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, FloatImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, DoubleImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, FloatImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, DoubleImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexInt16ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexInt32ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt16ImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt32ImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexFloatImageType*); -extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexDoubleImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexFloatImageType*); +extern template OTBApplicationEngine_EXPORT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexDoubleImageType*); } // namespace Wrapper } // namespace otb diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.hxx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.hxx index 33330cd241..104b4a99a5 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.hxx +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.hxx @@ -36,7 +36,7 @@ namespace Wrapper template TImageType* Application -::GetParameterImage(std::string parameter) +::GetParameterImage(std::string const& parameter) { typename TImageType::Pointer ret; @@ -57,7 +57,7 @@ Application template void Application -::SetParameterOutputImage(std::string parameter, TImageType* value) +::SetParameterOutputImage(std::string const& parameter, TImageType* value) { Parameter* param = GetParameterByKey(parameter); diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx index 7d5cfe93b7..95f4f79443 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx @@ -75,77 +75,77 @@ namespace Wrapper { -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8VectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int16VectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt16VectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int32VectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt32VectorImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8VectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int16VectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt16VectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int32VectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt32VectorImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE FloatVectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE DoubleVectorImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE FloatVectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE DoubleVectorImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt16VectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt32VectorImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt16VectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt32VectorImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexFloatVectorImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexDoubleVectorImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexFloatVectorImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexDoubleVectorImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8RGBImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8RGBAImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8RGBImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8RGBAImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8ImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int16ImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt16ImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int32ImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt32ImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt8ImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int16ImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt16ImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE Int32ImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE UInt32ImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE FloatImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE DoubleImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE FloatImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE DoubleImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt16ImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt32ImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt16ImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexInt32ImageType* Application::GetParameterImage(std::string const&); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexFloatImageType* Application::GetParameterImage(std::string); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexDoubleImageType* Application::GetParameterImage(std::string); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexFloatImageType* Application::GetParameterImage(std::string const&); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE ComplexDoubleImageType* Application::GetParameterImage(std::string const&); // -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int16VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt16VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int32VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt32VectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8VectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int16VectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt16VectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int32VectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt32VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, FloatVectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, DoubleVectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, FloatVectorImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, DoubleVectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt16VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt32VectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexFloatVectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexDoubleVectorImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8RGBImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8RGBAImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8RGBImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8RGBAImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt8ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int16ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt16ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, Int32ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, UInt32ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt8ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int16ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt16ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, Int32ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, UInt32ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, FloatImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, DoubleImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, FloatImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, DoubleImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexInt16ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexInt32ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt16ImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexInt32ImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexFloatImageType*); -template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string, ComplexDoubleImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexFloatImageType*); +template OTBApplicationEngine_EXPORT_EXPLICIT_TEMPLATE void Application::SetParameterOutputImage(std::string const&, ComplexDoubleImageType*); void Application::SetName( const std::string & name ) @@ -383,36 +383,36 @@ ParameterGroup* Application::GetParameterList() return m_ParameterList; } -Parameter* Application::GetParameterByKey(std::string name, bool follow) +Parameter* Application::GetParameterByKey(std::string const& name, bool follow) { return GetParameterList()->GetParameterByKey(name, follow); } -void Application::SetParameterInt(std::string key, int value, bool hasUserValueFlag) +void Application::SetParameterInt(std::string const& key, int value, bool hasUserValueFlag) { GetParameterByKey(key)->FromInt(value); this->SetParameterUserValue(key, hasUserValueFlag); } -void Application::SetParameterFloat(std::string key, float value, bool hasUserValueFlag) +void Application::SetParameterFloat(std::string const& key, float value, bool hasUserValueFlag) { GetParameterByKey(key)->FromFloat(value); this->SetParameterUserValue(key, hasUserValueFlag); } -void Application::SetParameterString(std::string parameter, std::string value, bool hasUserValueFlag) +void Application::SetParameterString(std::string const& parameter, std::string value, bool hasUserValueFlag) { GetParameterByKey(parameter)->FromString(value); this->SetParameterUserValue(parameter, hasUserValueFlag); } -void Application::SetParameterStringList(std::string key, std::vector values, bool hasUserValueFlag) +void Application::SetParameterStringList(std::string const& key, std::vector values, bool hasUserValueFlag) { GetParameterByKey(key)->FromStringList(values); this->SetParameterUserValue(key, hasUserValueFlag); } -void Application::SetParameterUserValue(std::string paramKey, bool value) +void Application::SetParameterUserValue(std::string const& paramKey, bool value) { /** UserValue is set/unset parameter must be active. Can't set the m_Active flg in Parameter::SetUserValue() instead of @@ -429,7 +429,7 @@ void Application::SetParameterUserValue(std::string paramKey, bool value) } } -const Parameter* Application::GetParameterByKey(std::string name, bool follow) const +const Parameter* Application::GetParameterByKey(std::string const& name, bool follow) const { // GetParameterList is non const... Application* _this = const_cast(this); @@ -942,36 +942,36 @@ Application::Stop() } /* Enable the use of an optional parameter. Returns the previous state */ -void Application::EnableParameter(std::string paramKey) +void Application::EnableParameter(std::string const& paramKey) { Parameter* param = GetParameterByKey(paramKey); param->SetActive(true); } /* Disable the use of an optional parameter. Returns the previous state */ -void Application::DisableParameter(std::string paramKey) +void Application::DisableParameter(std::string const& paramKey) { GetParameterByKey(paramKey)->SetActive(false); } /* Return the enable state of an optional parameter */ -bool Application::IsParameterEnabled(std::string paramKey, bool recurseParents) const +bool Application::IsParameterEnabled(std::string const& paramKey, bool recurseParents) const { return GetParameterByKey(paramKey)->GetActive(recurseParents); } /* Return true if the specified parameter is mandatory */ -bool Application::IsMandatory(std::string paramKey) const +bool Application::IsMandatory(std::string const& paramKey) const { return GetParameterByKey(paramKey)->GetMandatory(); } -void Application::MandatoryOn(std::string paramKey) +void Application::MandatoryOn(std::string const& paramKey) { GetParameterByKey(paramKey)->SetMandatory(true); } -void Application::MandatoryOff(std::string paramKey) +void Application::MandatoryOff(std::string const& paramKey) { GetParameterByKey(paramKey)->SetMandatory(false); } @@ -979,30 +979,30 @@ void Application::MandatoryOff(std::string paramKey) /* Return true if the specified parameter was set automatically in the * application */ -bool Application::HasAutomaticValue(std::string paramKey) const +bool Application::HasAutomaticValue(std::string const& paramKey) const { return GetParameterByKey(paramKey)->GetAutomaticValue(); } -void Application::AutomaticValueOn(std::string paramKey) +void Application::AutomaticValueOn(std::string const& paramKey) { GetParameterByKey(paramKey)->SetAutomaticValue(true); } -void Application::AutomaticValueOff(std::string paramKey) +void Application::AutomaticValueOff(std::string const& paramKey) { GetParameterByKey(paramKey)->SetAutomaticValue(false); } /* Returns true if the parameter has an associated value provided externally * (not automatically computed by the application) */ -bool Application::HasUserValue(std::string paramKey) const +bool Application::HasUserValue(std::string const& paramKey) const { return GetParameterByKey(paramKey)->HasUserValue(); } /* If a user value was provided clear it and update the other parameters */ -void Application::ClearValue(std::string paramKey) +void Application::ClearValue(std::string const& paramKey) { GetParameterByKey(paramKey)->ClearValue(); } @@ -1010,37 +1010,37 @@ void Application::ClearValue(std::string paramKey) /* Returns true if the parameter has an associated value. * This value can be an automatically computed value or default value, * or a value set externally by user */ -bool Application::HasValue(std::string paramKey) const +bool Application::HasValue(std::string const& paramKey) const { return GetParameterByKey(paramKey)->HasValue(); } /* Return the user level of access to a parameter */ -UserLevel Application::GetParameterUserLevel(std::string paramKey) const +UserLevel Application::GetParameterUserLevel(std::string const& paramKey) const { return GetParameterByKey(paramKey)->GetUserLevel(); } /* Return the role (input/output) of a parameter */ -Role Application::GetParameterRole(std::string paramKey) const +Role Application::GetParameterRole(std::string const& paramKey) const { return GetParameterByKey(paramKey)->GetRole(); } /* Return the role (input/output) of a parameter */ -void Application::SetParameterRole(std::string paramKey, Role role) +void Application::SetParameterRole(std::string const& paramKey, Role role) { GetParameterByKey(paramKey)->SetRole(role); } /* Get the parameter type from its name */ -ParameterType Application::GetParameterType(std::string key) const +ParameterType Application::GetParameterType(std::string const& key) const { return GetParameterByKey(key)->GetType(); } -std::vector Application::GetChoiceKeys(std::string name) +std::vector Application::GetChoiceKeys(std::string const& name) { Parameter* param = GetParameterByKey(name); if (dynamic_cast(param)) @@ -1056,7 +1056,7 @@ std::vector Application::GetChoiceKeys(std::string name) itkExceptionMacro(<< name << " is not a choice parameter"); } -std::vector Application::GetChoiceNames(std::string name) +std::vector Application::GetChoiceNames(std::string const& name) { Parameter* param = GetParameterByKey(name); if (dynamic_cast(param)) @@ -1073,7 +1073,7 @@ std::vector Application::GetChoiceNames(std::string name) } -void Application::SetDefaultParameterInt(std::string parameter, int value) +void Application::SetDefaultParameterInt(std::string const& parameter, int value) { Parameter* param = GetParameterByKey(parameter); bool hasUserValue = param->HasUserValue(); @@ -1104,7 +1104,7 @@ void Application::SetDefaultParameterInt(std::string parameter, int value) } } -int Application::GetDefaultParameterInt(std::string parameter) +int Application::GetDefaultParameterInt(std::string const& parameter) { Parameter* param = GetParameterByKey(parameter); int ret = 0 ; @@ -1135,7 +1135,7 @@ int Application::GetDefaultParameterInt(std::string parameter) return ret; } -void Application::SetDefaultParameterFloat(std::string key, float value) +void Application::SetDefaultParameterFloat(std::string const& key, float value) { auto param = downcast_check(GetParameterByKey(key)); param->SetDefaultValue(value); @@ -1146,44 +1146,44 @@ void Application::SetDefaultParameterFloat(std::string key, float value) } } -float Application::GetDefaultParameterFloat(std::string key) +float Application::GetDefaultParameterFloat(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetDefaultValue(); } -void Application::SetDefaultOutputPixelType(std::string key, ImagePixelType type) +void Application::SetDefaultOutputPixelType(std::string const& key, ImagePixelType type) { auto param = downcast_check(GetParameterByKey(key)); param->SetDefaultPixelType(type); param->SetPixelType(type); } -void Application::SetMinimumParameterIntValue(std::string key, int value) +void Application::SetMinimumParameterIntValue(std::string const& key, int value) { auto param = downcast_check(GetParameterByKey(key)); param->SetMinimumValue(value); } -void Application::SetMaximumParameterIntValue(std::string key, int value) +void Application::SetMaximumParameterIntValue(std::string const& key, int value) { auto param = downcast_check(GetParameterByKey(key)); param->SetMaximumValue(value); } -void Application::SetMinimumParameterFloatValue(std::string key, float value) +void Application::SetMinimumParameterFloatValue(std::string const& key, float value) { auto param = downcast_check(GetParameterByKey(key)); param->SetMinimumValue(value); } -void Application::SetMaximumParameterFloatValue(std::string key, float value) +void Application::SetMaximumParameterFloatValue(std::string const& key, float value) { auto param = downcast_check(GetParameterByKey(key)); param->SetMaximumValue(value); } -void Application::SetListViewSingleSelectionMode(std::string key, bool status) +void Application::SetListViewSingleSelectionMode(std::string const& key, bool status) { auto param = downcast_check(GetParameterByKey(key)); param->SetSingleSelection(status); @@ -1195,56 +1195,56 @@ bool Application::GetListViewSingleSelectionMode(const std::string& key) return param->GetSingleSelection(); } -void Application::SetParameterOutputImage(std::string key, FloatVectorImageType* value) +void Application::SetParameterOutputImage(std::string const& key, FloatVectorImageType* value) { auto param = downcast_check(GetParameterByKey(key)); param->SetValue(value); } -void Application::SetParameterOutputImagePixelType(std::string key, ImagePixelType pixelType) +void Application::SetParameterOutputImagePixelType(std::string const& key, ImagePixelType pixelType) { auto param = downcast_check(GetParameterByKey(key)); param->SetPixelType(pixelType); } -void Application::SetParameterOutputVectorData(std::string key, VectorDataType* value) +void Application::SetParameterOutputVectorData(std::string const& key, VectorDataType* value) { auto param = downcast_check(GetParameterByKey(key)); param->SetValue(value); } -std::string Application::GetParameterName(std::string parameter) +std::string Application::GetParameterName(std::string const& parameter) { // get the actual parameter, even if it is a proxy Parameter* param = GetParameterByKey(parameter,false); return param->GetName(); } -std::string Application::GetParameterDescription(std::string parameter) +std::string Application::GetParameterDescription(std::string const& parameter) { // get the actual parameter, even if it is a proxy Parameter* param = GetParameterByKey(parameter,false); return param->GetDescription(); } -void Application::SetParameterDescription(std::string parameter, std::string desc) +void Application::SetParameterDescription(std::string const& parameter, std::string desc) { // get the actual parameter, even if it is a proxy Parameter* param = GetParameterByKey(parameter,false); param->SetDescription(desc); } -int Application::GetParameterInt(std::string key) const +int Application::GetParameterInt(std::string const& key) const { return GetParameterByKey(key)->ToInt(); } -float Application::GetParameterFloat(std::string key) const +float Application::GetParameterFloat(std::string const& key) const { return GetParameterByKey(key)->ToFloat(); } -std::string Application::GetParameterString(std::string key) const +std::string Application::GetParameterString(std::string const& key) const { return GetParameterByKey(key)->ToString(); } @@ -1254,113 +1254,113 @@ std::vector Application::GetParameterStringList(const std::string& return GetParameterByKey(key)->ToStringList(); } -void Application::SetParameterInputImage(std::string key, ImageBaseType* inputImage) +void Application::SetParameterInputImage(std::string const& key, ImageBaseType* inputImage) { auto param = downcast_check(GetParameterByKey(key)); param->SetImage(inputImage); } -ImageBaseType* Application::GetParameterOutputImage(std::string key) +ImageBaseType* Application::GetParameterOutputImage(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetValue(); } -void Application::AddImageToParameterInputImageList(std::string key, ImageBaseType* img) +void Application::AddImageToParameterInputImageList(std::string const& key, ImageBaseType* img) { auto param = downcast_check(GetParameterByKey(key)); param->AddImage(img); } -void Application::SetNthParameterInputImageList(std::string key, const unsigned int& id, ImageBaseType* img) +void Application::SetNthParameterInputImageList(std::string const& key, const unsigned int& id, ImageBaseType* img) { auto param = downcast_check(GetParameterByKey(key)); param->SetNthImage(id, img); } -void Application::AddParameterStringList(std::string key, const std::string& str) +void Application::AddParameterStringList(std::string const& key, const std::string& str) { auto param = downcast_check(GetParameterByKey(key)); param->AddFromFileName(str); } -void Application::SetNthParameterStringList(std::string key, const unsigned int& id, const std::string& str) +void Application::SetNthParameterStringList(std::string const& key, const unsigned int& id, const std::string& str) { auto param = downcast_check(GetParameterByKey(key)); param->SetNthFileName(id, str); } -void Application::ClearParameterInputImageList(std::string key) +void Application::ClearParameterInputImageList(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); param->ClearValue(); } -unsigned int Application::GetNumberOfElementsInParameterInputImageList(std::string key) +unsigned int Application::GetNumberOfElementsInParameterInputImageList(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->Size(); } -FloatVectorImageType* Application::GetParameterImage(std::string parameter) +FloatVectorImageType* Application::GetParameterImage(std::string const& parameter) { return this->GetParameterImage(parameter); } -FloatVectorImageListType* Application::GetParameterImageList(std::string key) +FloatVectorImageListType* Application::GetParameterImageList(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetImageList(); } -VectorDataType* Application::GetParameterVectorData(std::string key) +VectorDataType* Application::GetParameterVectorData(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetVectorData(); } -VectorDataListType* Application::GetParameterVectorDataList(std::string key) +VectorDataListType* Application::GetParameterVectorDataList(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetVectorDataList(); } -std::string Application::GetParameterAsString(std::string key) +std::string Application::GetParameterAsString(std::string const& key) { return GetParameterString(key); } -ImagePixelType Application::GetParameterOutputImagePixelType(std::string key) +ImagePixelType Application::GetParameterOutputImagePixelType(std::string const& key) { auto param = downcast_check(GetParameterByKey(key)); return param->GetPixelType(); } void -Application::AddChoice(std::string paramKey, std::string paramName) +Application::AddChoice(std::string const& paramKey, std::string const& paramName) { GetParameterList()->AddChoice(paramKey, paramName); } void -Application::ClearChoices(std::string paramKey) +Application::ClearChoices(std::string const& paramKey) { GetParameterList()->ClearChoices(paramKey); } std::vector -Application::GetSelectedItems(std::string param) +Application::GetSelectedItems(std::string const& param) { return GetParameterList()->GetSelectedItems(param); } void -Application::AddParameter(ParameterType type, std::string paramKey, std::string paramName) +Application::AddParameter(ParameterType type, std::string const& paramKey, std::string const& paramName) { GetParameterList()->AddParameter(type, paramKey, paramName); } -void Application::AddRAMParameter(std::string paramKey, std::string paramName, unsigned int defaultValue) +void Application::AddRAMParameter(std::string const& paramKey, std::string const& paramName, unsigned int defaultValue) { GetParameterList()->AddParameter(ParameterType_RAM, paramKey, paramName); SetDefaultParameterInt(paramKey, defaultValue); @@ -1368,7 +1368,7 @@ void Application::AddRAMParameter(std::string paramKey, std::string paramName, u } // paramKey default value = ram -void Application::AddRAMParameter(std::string paramKey) +void Application::AddRAMParameter(std::string const& paramKey) { // Get the RAM Parameter from the configuration manager AddRAMParameter(paramKey, "Available RAM (MB)", otb::ConfigurationManager::GetMaxRAMHint()); @@ -1376,7 +1376,7 @@ void Application::AddRAMParameter(std::string paramKey) SetParameterDescription(paramKey, "Available memory for processing (in MB)."); } -void Application::AddRANDParameter(std::string paramKey, std::string paramName, unsigned int defaultValue) +void Application::AddRANDParameter(std::string const& paramKey, std::string const& paramName, unsigned int defaultValue) { GetParameterList()->AddParameter(ParameterType_Int, paramKey, paramName); SetDefaultParameterInt(paramKey, defaultValue); @@ -1384,7 +1384,7 @@ void Application::AddRANDParameter(std::string paramKey, std::string paramName, } // paramKey default value = rand -void Application::AddRANDParameter(std::string paramKey) +void Application::AddRANDParameter(std::string const& paramKey) { // Get the RAND Parameter from the configuration file @@ -1711,7 +1711,7 @@ Application::GetImageBasePixelType(const std::string & key, unsigned int idx) } #define otbGetParameterImageMacro( Image ) \ - Image##Type * Application::GetParameter##Image(std::string parameter) \ + Image##Type * Application::GetParameter##Image(std::string const& parameter) \ { \ Parameter* param = GetParameterByKey(parameter); \ InputImageParameter* paramDown = dynamic_cast(param); \ -- GitLab From 26405bbff5615c3c2c17c39ac875294e4e3ba6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Thu, 8 Aug 2019 18:50:32 +0200 Subject: [PATCH 23/24] ENH: split the DoExecute() method in several parts --- .../include/otbVectorPrediction.h | 30 ++++ .../include/otbVectorPrediction.hxx | 159 +++++++++++------- 2 files changed, 132 insertions(+), 57 deletions(-) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.h b/Modules/Applications/AppClassification/include/otbVectorPrediction.h index d895324665..65fe591977 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.h +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.h @@ -98,7 +98,37 @@ private: /** Method returning whether the confidence map should be computed, depending on the regression mode and input parameters */ bool shouldComputeConfidenceMap() const; + /** Method returning the input list sample from the input layer */ + typename ListSampleType::Pointer ReadInputListSample(otb::ogr::Layer const& layer); + + /** Normalize a list sample using the statistic file given */ + typename ListSampleType::Pointer NormalizeListSample(ListSampleType::Pointer input); + + /** Create the output DataSource, in update mode the input layer is buffered and the input + * data source is re opened in update mode. */ + otb::ogr::DataSource::Pointer CreateOutputDataSource(otb::ogr::DataSource::Pointer source, + otb::ogr::Layer & layer, + bool updateMode); + + /** Add a prediction field in the output layer if it does not exist. + * If computeConfidenceMap evaluates to true a confidence field will be + * added. */ + void AddPredictionField(otb::ogr::Layer & outLayer, + otb::ogr::Layer const& layer, + bool computeConfidenceMap); + + /** Fill the output layer with the predicted values and optionnaly the confidence */ + void FillOutputLayer(otb::ogr::Layer & outLayer, + otb::ogr::Layer const& layer, + typename LabelListSampleType::Pointer target, + typename ConfidenceListSampleType::Pointer quality, + bool updateMode, + bool computeConfidenceMap); + ModelPointerType m_Model; + + /** Name used for the confidence field */ + std::string confFieldName = "confidence"; }; } } diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 20d8d357aa..54b8d889d1 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -73,13 +73,10 @@ void VectorPrediction::DoUpdateParameters() } template -void VectorPrediction::DoExecute() +typename VectorPrediction::ListSampleType::Pointer +VectorPrediction +::ReadInputListSample(otb::ogr::Layer const& layer) { - auto shapefileName = GetParameterString("in"); - - auto source = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read); - auto layer = source->GetLayer(0); - typename ListSampleType::Pointer input = ListSampleType::New(); const int nbFeatures = GetSelectedItems("feat").size(); @@ -110,7 +107,16 @@ void VectorPrediction::DoExecute() } input->PushBack(mv); } + return input; +} +template +typename VectorPrediction::ListSampleType::Pointer +VectorPrediction +::NormalizeListSample(ListSampleType::Pointer input) +{ + const int nbFeatures = GetSelectedItems("feat").size(); + // Statistics for shift/scale MeasurementType meanMeasurementVector; MeasurementType stddevMeasurementVector; @@ -139,39 +145,31 @@ void VectorPrediction::DoExecute() otbAppLogINFO("standard deviation used: " << stddevMeasurementVector); otbAppLogINFO("Loading model"); - m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), MachineLearningModelFactoryType::ReadMode); - - if (m_Model.IsNull()) - { - otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); - } - - m_Model->SetRegressionMode(RegressionMode); - - m_Model->Load(GetParameterString("model")); - otbAppLogINFO("Model loaded"); - - ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput(); - - typename ConfidenceListSampleType::Pointer quality; + + return trainingShiftScaleFilter->GetOutput(); +} - bool computeConfidenceMap = shouldComputeConfidenceMap(); - typename LabelListSampleType::Pointer target; - if (computeConfidenceMap) +template +otb::ogr::DataSource::Pointer +VectorPrediction +::CreateOutputDataSource(otb::ogr::DataSource::Pointer source, otb::ogr::Layer & layer, bool updateMode) +{ + ogr::DataSource::Pointer output; + ogr::DataSource::Pointer buffer = ogr::DataSource::New(); + if (updateMode) { - quality = ConfidenceListSampleType::New(); - target = m_Model->PredictBatch(listSample, quality); + // Update mode + 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->Clear(); + // Re-open input data source in update mode + output = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::Update_LayerUpdate); } else - { - target = m_Model->PredictBatch(listSample); - } - - ogr::DataSource::Pointer output; - ogr::DataSource::Pointer buffer = ogr::DataSource::New(); - bool updateMode = false; - if (IsParameterEnabled("out") && HasValue("out")) { // Create new OGRDataSource output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); @@ -184,32 +182,18 @@ void VectorPrediction::DoExecute() newLayer.CreateField(fieldDefn); } } - else - { - // Update mode - 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->Clear(); - // Re-open input data source in update mode - output = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Update_LayerUpdate); - } - otb::ogr::Layer outLayer = output->GetLayer(0); + return output; +} - OGRErr errStart = outLayer.ogr().StartTransaction(); - if (errStart != OGRERR_NONE) - { - itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); - } +template +void +VectorPrediction +::AddPredictionField(otb::ogr::Layer & outLayer, otb::ogr::Layer const& layer, bool computeConfidenceMap) +{ OGRFeatureDefn& layerDefn = layer.GetLayerDefn(); - // Add the field of prediction in the output layer if field not exist - const OGRFieldType labelType = RegressionMode ? OFTReal : OFTInteger; int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str()); @@ -226,7 +210,6 @@ void VectorPrediction::DoExecute() } // Add confidence field in the output layer - std::string confFieldName("confidence"); if (computeConfidenceMap) { idx = layerDefn.GetFieldIndex(confFieldName.c_str()); @@ -244,8 +227,14 @@ void VectorPrediction::DoExecute() outLayer.CreateField(confFieldDefn); } } +} - // Fill output layer +template +void +VectorPrediction +::FillOutputLayer(otb::ogr::Layer & outLayer, otb::ogr::Layer const& layer, typename LabelListSampleType::Pointer target, + typename ConfidenceListSampleType::Pointer quality, bool updateMode, bool computeConfidenceMap) +{ unsigned int count = 0; std::string classfieldname = GetParameterString("cfield"); for (auto const& feature : layer) @@ -281,6 +270,62 @@ void VectorPrediction::DoExecute() } count++; } +} + +template +void VectorPrediction::DoExecute() +{ + m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), MachineLearningModelFactoryType::ReadMode); + + if (m_Model.IsNull()) + { + otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type"); + } + + m_Model->SetRegressionMode(RegressionMode); + + m_Model->Load(GetParameterString("model")); + otbAppLogINFO("Model loaded"); + + auto shapefileName = GetParameterString("in"); + + auto source = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read); + auto layer = source->GetLayer(0); + + auto input = ReadInputListSample(layer); + + ListSampleType::Pointer listSample = NormalizeListSample(input); + + typename LabelListSampleType::Pointer target; + + // The quality listSample containing confidence values is defined here, but is only used when + // computeConfidenceMap evaluates to true. This listSample is also used in FillOutputLayer(...) + const bool computeConfidenceMap = shouldComputeConfidenceMap(); + typename ConfidenceListSampleType::Pointer quality; + + if (computeConfidenceMap) + { + quality = ConfidenceListSampleType::New(); + target = m_Model->PredictBatch(listSample, quality); + } + else + { + target = m_Model->PredictBatch(listSample); + } + + const bool updateMode = !(IsParameterEnabled("out") && HasValue("out")); + + auto output = CreateOutputDataSource(source, layer, updateMode); + otb::ogr::Layer outLayer = output->GetLayer(0); + + OGRErr errStart = outLayer.ogr().StartTransaction(); + if (errStart != OGRERR_NONE) + { + itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); + } + + AddPredictionField(outLayer, layer, computeConfidenceMap); + FillOutputLayer(outLayer, layer, target, quality, updateMode, computeConfidenceMap); if (outLayer.ogr().TestCapability("Transactions")) { -- GitLab From 181690b3b3350a6242e2db5019bb4bb35241767b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= Date: Fri, 9 Aug 2019 10:25:49 +0200 Subject: [PATCH 24/24] BUG: add template before the use of a template function --- .../AppClassification/include/otbVectorPrediction.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx index 54b8d889d1..fde557da10 100644 --- a/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx +++ b/Modules/Applications/AppClassification/include/otbVectorPrediction.hxx @@ -259,7 +259,7 @@ VectorPrediction itkExceptionMacro(<< "incorrect field type: " << field.GetType() << "."); } if (computeConfidenceMap) - dstFeature[confFieldName].SetValue(quality->GetMeasurementVector(count)[0]); + dstFeature[confFieldName].template SetValue(quality->GetMeasurementVector(count)[0]); if (updateMode) { outLayer.SetFeature(dstFeature); -- GitLab