diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in new file mode 100644 index 0000000000000000000000000000000000000000..fed0791c2f768fa4cad229ac626e991f2488ec83 --- /dev/null +++ b/CMake/cmake_uninstall.cmake.in @@ -0,0 +1,22 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") + return() +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + execute_process(COMMAND + "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE out_var + RESULT_VARIABLE res_var + ) + if(NOT "${res_var}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else() + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach(file) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e7581a8500754e5c4e1ff84d7820ce58e5414cd..bd5e0311dee78f8641c58cf9974b74dd50d7fb0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,6 +364,15 @@ endif() # Create target to download data from the OTBData group. This must come after # all tests have been added that reference the group, so we put it last. +# uninstall target +configure_file( + "${CMAKE_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in" + "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake) + #macro to put a fixed space between key, value in summary macro(get_white_spaces var res) string(LENGTH "${var}" len) diff --git a/Modules/Applications/AppClassification/app/CMakeLists.txt b/Modules/Applications/AppClassification/app/CMakeLists.txt index 651336c88214d87625a561fa82b12f48d5d5d98f..3f46b917da7fa5c1e6d2e17623635bb6cbcd6e38 100644 --- a/Modules/Applications/AppClassification/app/CMakeLists.txt +++ b/Modules/Applications/AppClassification/app/CMakeLists.txt @@ -45,6 +45,12 @@ otb_create_application( SOURCES otbTrainOGRLayersClassifier.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES}) +otb_create_application( + NAME TrainVectorClassifier + SOURCES otbTrainVectorClassifier.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES}) + + otb_create_application( NAME ComputeConfusionMatrix SOURCES otbComputeConfusionMatrix.cxx diff --git a/Modules/Applications/AppClassification/app/otbTrainOGRLayersClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainOGRLayersClassifier.cxx index 5dc706145af502e65ebe30ab45ae55e5a8fbe873..b461ac2a89f97fda7b2b2308d6e6f08ce5834964 100644 --- a/Modules/Applications/AppClassification/app/otbTrainOGRLayersClassifier.cxx +++ b/Modules/Applications/AppClassification/app/otbTrainOGRLayersClassifier.cxx @@ -56,8 +56,11 @@ private: SetName("TrainOGRLayersClassifier"); SetDescription("Train a SVM classifier based on labeled geometries and a list of features to consider."); - SetDocName("TrainOGRLayersClassifier"); - SetDocLongDescription("This application trains a SVM classifier based on labeled geometries and a list of features to consider for classification."); + SetDocName("TrainOGRLayersClassifier (DEPRECATED)"); + SetDocLongDescription("This application trains a SVM classifier based on " + "labeled geometries and a list of features to consider for classification." + " This application is deprecated, prefer using TrainVectorClassifier which" + " offers access to all the classifiers."); SetDocLimitations("Experimental. For now only shapefiles are supported. Tuning of SVM classifier is not available."); SetDocAuthors("David Youssefi during internship at CNES"); SetDocSeeAlso("OGRLayerClassifier,ComputeOGRLayersFeaturesStatistics"); diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ee4c3a8f92724f359378fd8dcc4e5ce6227c7658 --- /dev/null +++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx @@ -0,0 +1,520 @@ +/*========================================================================= + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "otbLearningApplicationBase.h" + +#include "otbOGRDataSourceWrapper.h" +#include "otbOGRFeatureWrapper.h" +#include "otbStatisticsXMLFileWriter.h" + +#include "itkVariableLengthVector.h" +#include "otbStatisticsXMLFileReader.h" + +#include "itkListSample.h" +#include "otbShiftScaleSampleListFilter.h" + +// Validation +#include "otbConfusionMatrixCalculator.h" + +#include <algorithm> +#include <locale> + +namespace otb +{ +namespace Wrapper +{ + +/** Utility function to negate std::isalnum */ +bool IsNotAlphaNum(char c) + { + return !std::isalnum(c); + } + +class TrainVectorClassifier : public LearningApplicationBase<float,int> +{ +public: + typedef TrainVectorClassifier Self; + typedef LearningApplicationBase<float, int> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + itkNewMacro(Self) + + itkTypeMacro(Self, Superclass) + + typedef Superclass::SampleType SampleType; + typedef Superclass::ListSampleType ListSampleType; + typedef Superclass::TargetListSampleType TargetListSampleType; + typedef Superclass::SampleImageType SampleImageType; + + typedef double ValueType; + typedef itk::VariableLengthVector<ValueType> MeasurementType; + + typedef otb::StatisticsXMLFileReader<SampleType> StatisticsReader; + + typedef otb::Statistics::ShiftScaleSampleListFilter<ListSampleType, ListSampleType> ShiftScaleFilterType; + + // Estimate performance on validation sample + typedef otb::ConfusionMatrixCalculator<TargetListSampleType, TargetListSampleType> ConfusionMatrixCalculatorType; + typedef ConfusionMatrixCalculatorType::ConfusionMatrixType ConfusionMatrixType; + typedef ConfusionMatrixCalculatorType::MapOfIndicesType MapOfIndicesType; + typedef ConfusionMatrixCalculatorType::ClassLabelType ClassLabelType; + +private: + void DoInit() + { + SetName("TrainVectorClassifier"); + SetDescription("Train a classifier based on labeled geometries and a list of features to consider."); + + SetDocName("Train Vector Classifier"); + SetDocLongDescription("This application trains a classifier based on " + "labeled geometries and a list of features to consider for classification."); + SetDocLimitations(" "); + SetDocAuthors("OTB Team"); + SetDocSeeAlso(" "); + + //Group IO + AddParameter(ParameterType_Group, "io", "Input and output data"); + SetParameterDescription("io", "This group of parameters allows setting input and output data."); + + AddParameter(ParameterType_InputVectorData, "io.vd", "Input Vector Data"); + SetParameterDescription("io.vd", "Input geometries used for training (note : all geometries from the layer will be used)"); + + AddParameter(ParameterType_InputFilename, "io.stats", "Input XML image statistics file"); + MandatoryOff("io.stats"); + SetParameterDescription("io.stats", "XML file containing mean and variance of each feature."); + + AddParameter(ParameterType_OutputFilename, "io.confmatout", "Output confusion matrix"); + SetParameterDescription("io.confmatout", "Output file containing the confusion matrix (.csv format)."); + MandatoryOff("io.confmatout"); + + AddParameter(ParameterType_OutputFilename, "io.out", "Output model"); + SetParameterDescription("io.out", "Output file containing the model estimated (.txt format)."); + + AddParameter(ParameterType_ListView, "feat", "Field names for training features."); + SetParameterDescription("feat","List of field names in the input vector data to be used as features for training."); + + AddParameter(ParameterType_String,"cfield","Field containing the class id for supervision"); + SetParameterDescription("cfield","Field containing the class id for supervision. " + "Only geometries with this field available will be taken into account."); + SetParameterString("cfield","class"); + + AddParameter(ParameterType_Int, "layer", "Layer Index"); + SetParameterDescription("layer", "Index of the layer to use in the input vector file."); + MandatoryOff("layer"); + SetDefaultParameterInt("layer",0); + + AddParameter(ParameterType_Group, "valid", "Validation data"); + SetParameterDescription("valid", "This group of parameters defines validation data."); + + AddParameter(ParameterType_InputVectorData, "valid.vd", "Validation Vector Data"); + SetParameterDescription("valid.vd", "Geometries used for validation " + "(must contain the same fields used for training, all geometries from the layer will be used)"); + MandatoryOff("valid.vd"); + + AddParameter(ParameterType_Int, "valid.layer", "Layer Index"); + SetParameterDescription("valid.layer", "Index of the layer to use in the validation vector file."); + MandatoryOff("valid.layer"); + SetDefaultParameterInt("valid.layer",0); + + // Add parameters for the classifier choice + Superclass::DoInit(); + + AddRANDParameter(); + // Doc example parameter settings + SetDocExampleParameterValue("io.vd", "vectorData.shp"); + SetDocExampleParameterValue("io.stats", "meanVar.xml"); + SetDocExampleParameterValue("io.out", "svmModel.svm"); + SetDocExampleParameterValue("feat", "perimeter area width"); + SetDocExampleParameterValue("cfield", "predicted"); + } + + void DoUpdateParameters() + { + if ( HasValue("io.vd") ) + { + std::string vectorFile = GetParameterString("io.vd"); + ogr::DataSource::Pointer ogrDS = + ogr::DataSource::New(vectorFile, ogr::DataSource::Modes::Read); + ogr::Layer layer = ogrDS->GetLayer(this->GetParameterInt("layer")); + ogr::Feature feature = layer.ogr().GetNextFeature(); + + ClearChoices("feat"); + for(int iField=0; iField<feature.ogr().GetFieldCount(); iField++) + { + std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef(); + key = item; + std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum); + std::transform(key.begin(), end, key.begin(), tolower); + key="feat."+key.substr(0, end - key.begin()); + AddChoice(key,item); + } + } + } + + +void LogConfusionMatrix(ConfusionMatrixCalculatorType* confMatCalc) +{ + ConfusionMatrixCalculatorType::ConfusionMatrixType matrix = confMatCalc->GetConfusionMatrix(); + + // Compute minimal width + size_t minwidth = 0; + + for (unsigned int i = 0; i < matrix.Rows(); i++) + { + for (unsigned int j = 0; j < matrix.Cols(); j++) + { + std::ostringstream os; + os << matrix(i, j); + size_t size = os.str().size(); + + if (size > minwidth) + { + minwidth = size; + } + } + } + + MapOfIndicesType mapOfIndices = confMatCalc->GetMapOfIndices(); + + MapOfIndicesType::const_iterator it = mapOfIndices.begin(); + MapOfIndicesType::const_iterator end = mapOfIndices.end(); + + for (; it != end; ++it) + { + std::ostringstream os; + os << "[" << it->second << "]"; + + size_t size = os.str().size(); + if (size > minwidth) + { + minwidth = size; + } + } + + // Generate matrix string, with 'minwidth' as size specifier + std::ostringstream os; + + // Header line + for (size_t i = 0; i < minwidth; ++i) + os << " "; + os << " "; + + it = mapOfIndices.begin(); + end = mapOfIndices.end(); + for (; it != end; ++it) + { + os << "[" << it->second << "]" << " "; + } + + os << std::endl; + + // Each line of confusion matrix + for (unsigned int i = 0; i < matrix.Rows(); i++) + { + ConfusionMatrixCalculatorType::ClassLabelType label = mapOfIndices[i]; + os << "[" << std::setw(minwidth - 2) << label << "]" << " "; + for (unsigned int j = 0; j < matrix.Cols(); j++) + { + os << std::setw(minwidth) << matrix(i, j) << " "; + } + os << std::endl; + } + + otbAppLogINFO("Confusion matrix (rows = reference labels, columns = produced labels):\n" << os.str()); +} + + +void DoExecute() + { + std::string shapefile = GetParameterString("io.vd"); + std::string modelfile = GetParameterString("io.out"); + typedef int LabelPixelType; + typedef itk::FixedArray<LabelPixelType,1> LabelSampleType; + typedef itk::Statistics::ListSample <LabelSampleType> LabelListSampleType; + + const int nbFeatures = GetSelectedItems("feat").size(); + + // Statistics for shift/scale + MeasurementType meanMeasurementVector; + MeasurementType stddevMeasurementVector; + if (HasValue("io.stats") && IsParameterEnabled("io.stats")) + { + StatisticsReader::Pointer statisticsReader = StatisticsReader::New(); + std::string XMLfile = GetParameterString("io.stats"); + statisticsReader->SetFileName(XMLfile); + meanMeasurementVector = statisticsReader->GetStatisticVectorByName("mean"); + stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev"); + } + else + { + meanMeasurementVector.SetSize(nbFeatures); + meanMeasurementVector.Fill(0.); + stddevMeasurementVector.SetSize(nbFeatures); + stddevMeasurementVector.Fill(1.); + } + + ogr::DataSource::Pointer source = ogr::DataSource::New(shapefile, ogr::DataSource::Modes::Read); + ogr::Layer layer = source->GetLayer(this->GetParameterInt("layer")); + ogr::Feature feature = layer.ogr().GetNextFeature(); + bool goesOn = feature.addr() != 0; + + ListSampleType::Pointer input = ListSampleType::New(); + LabelListSampleType::Pointer target = LabelListSampleType::New(); + input->SetMeasurementVectorSize(nbFeatures); + + int cFieldIndex=-1; + std::vector<int> featureFieldIndex = GetSelectedItems("feat"); + if (feature.addr()) + { + cFieldIndex = feature.ogr().GetFieldIndex(GetParameterString("cfield").c_str()); + } + + // Check that the class field exists + if (cFieldIndex < 0) + { + std::ostringstream oss; + std::vector<std::string> names = GetChoiceNames("feat"); + for (unsigned int i=0 ; i<names.size() ; i++) + { + if (i) oss << ", "; + oss << names[i]; + } + otbAppLogFATAL("The field name for class label ("<<GetParameterString("cfield") + <<") has not been found in the input vector file! Choices are "<< oss.str()); + } + + while(goesOn) + { + if(feature.ogr().IsFieldSet(cFieldIndex)) + { + MeasurementType mv; + mv.SetSize(nbFeatures); + for(int idx=0; idx < nbFeatures; ++idx) + mv[idx] = feature.ogr().GetFieldAsDouble(featureFieldIndex[idx]); + + input->PushBack(mv); + target->PushBack(feature.ogr().GetFieldAsInteger(cFieldIndex)); + } + feature = layer.ogr().GetNextFeature(); + goesOn = feature.addr() != 0; + } + + ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New(); + trainingShiftScaleFilter->SetInput(input); + trainingShiftScaleFilter->SetShifts(meanMeasurementVector); + trainingShiftScaleFilter->SetScales(stddevMeasurementVector); + trainingShiftScaleFilter->Update(); + + ListSampleType::Pointer listSample; + LabelListSampleType::Pointer labelListSample; + + listSample = trainingShiftScaleFilter->GetOutput(); + labelListSample = target; + + ListSampleType::Pointer trainingListSample = listSample; + LabelListSampleType::Pointer trainingLabeledListSample = labelListSample; + + //-------------------------- + // Estimate model + //-------------------------- + this->Train(trainingListSample,trainingLabeledListSample,GetParameterString("io.out")); + + //-------------------------- + // Performances estimation + //-------------------------- + ListSampleType::Pointer validationListSample=ListSampleType::New(); + TargetListSampleType::Pointer validationLabeledListSample = TargetListSampleType::New(); + + // Import validation data + if (HasValue("valid.vd") && IsParameterEnabled("valid.vd")) + { + std::string validFile = this->GetParameterString("valid.vd"); + source = ogr::DataSource::New(validFile, ogr::DataSource::Modes::Read); + layer = source->GetLayer(this->GetParameterInt("valid.layer")); + feature = layer.ogr().GetNextFeature(); + goesOn = feature.addr() != 0; + + // find usefull field indexes + + // TODO : detect corresponding indexes in validation data set, for the moment + // Assume they have the same fields, in the same order. + + input = ListSampleType::New(); + target = LabelListSampleType::New(); + input->SetMeasurementVectorSize(nbFeatures); + while(goesOn) + { + if(feature.ogr().IsFieldSet(cFieldIndex)) + { + MeasurementType mv; + mv.SetSize(nbFeatures); + for(int idx=0; idx < nbFeatures; ++idx) + mv[idx] = feature.ogr().GetFieldAsDouble(featureFieldIndex[idx]); + + input->PushBack(mv); + target->PushBack(feature.ogr().GetFieldAsInteger(cFieldIndex)); + } + feature = layer.ogr().GetNextFeature(); + goesOn = feature.addr() != 0; + } + + ShiftScaleFilterType::Pointer validShiftScaleFilter = ShiftScaleFilterType::New(); + validShiftScaleFilter->SetInput(input); + validShiftScaleFilter->SetShifts(meanMeasurementVector); + validShiftScaleFilter->SetScales(stddevMeasurementVector); + validShiftScaleFilter->Update(); + + validationListSample = validShiftScaleFilter->GetOutput(); + validationLabeledListSample = target; + } + + //Test the input validation set size + TargetListSampleType::Pointer predictedList = TargetListSampleType::New(); + ListSampleType::Pointer performanceListSample; + TargetListSampleType::Pointer performanceLabeledListSample; + if(validationLabeledListSample->Size() != 0) + { + performanceListSample = validationListSample; + performanceLabeledListSample = validationLabeledListSample; + } + else + { + otbAppLogWARNING("The validation set is empty. The performance estimation is done using the input training set in this case."); + performanceListSample = trainingListSample; + performanceLabeledListSample = trainingLabeledListSample; + } + + this->Classify(performanceListSample, predictedList, GetParameterString("io.out")); + + ConfusionMatrixCalculatorType::Pointer confMatCalc = ConfusionMatrixCalculatorType::New(); + + otbAppLogINFO("Predicted list size : " << predictedList->Size()); + otbAppLogINFO("ValidationLabeledListSample size : " << performanceLabeledListSample->Size()); + confMatCalc->SetReferenceLabels(performanceLabeledListSample); + confMatCalc->SetProducedLabels(predictedList); + confMatCalc->Compute(); + + otbAppLogINFO("training performances"); + LogConfusionMatrix(confMatCalc); + + for (unsigned int itClasses = 0; itClasses < confMatCalc->GetNumberOfClasses(); itClasses++) + { + ConfusionMatrixCalculatorType::ClassLabelType classLabel = confMatCalc->GetMapOfIndices()[itClasses]; + + otbAppLogINFO("Precision of class [" << classLabel << "] vs all: " << confMatCalc->GetPrecisions()[itClasses]); + otbAppLogINFO("Recall of class [" << classLabel << "] vs all: " << confMatCalc->GetRecalls()[itClasses]); + otbAppLogINFO( + "F-score of class [" << classLabel << "] vs all: " << confMatCalc->GetFScores()[itClasses] << "\n"); + } + otbAppLogINFO("Global performance, Kappa index: " << confMatCalc->GetKappaIndex()); + + + if (this->HasValue("io.confmatout")) + { + // Writing the confusion matrix in the output .CSV file + + MapOfIndicesType::iterator itMapOfIndicesValid, itMapOfIndicesPred; + ClassLabelType labelValid = 0; + + ConfusionMatrixType confusionMatrix = confMatCalc->GetConfusionMatrix(); + MapOfIndicesType mapOfIndicesValid = confMatCalc->GetMapOfIndices(); + + unsigned int nbClassesPred = mapOfIndicesValid.size(); + + ///////////////////////////////////////////// + // Filling the 2 headers for the output file + const std::string commentValidStr = "#Reference labels (rows):"; + const std::string commentPredStr = "#Produced labels (columns):"; + const char separatorChar = ','; + std::ostringstream ossHeaderValidLabels, ossHeaderPredLabels; + + // Filling ossHeaderValidLabels and ossHeaderPredLabels for the output file + ossHeaderValidLabels << commentValidStr; + ossHeaderPredLabels << commentPredStr; + + itMapOfIndicesValid = mapOfIndicesValid.begin(); + + while (itMapOfIndicesValid != mapOfIndicesValid.end()) + { + // labels labelValid of mapOfIndicesValid are already sorted in otbConfusionMatrixCalculator + labelValid = itMapOfIndicesValid->second; + + otbAppLogINFO("mapOfIndicesValid[" << itMapOfIndicesValid->first << "] = " << labelValid); + + ossHeaderValidLabels << labelValid; + ossHeaderPredLabels << labelValid; + + ++itMapOfIndicesValid; + + if (itMapOfIndicesValid != mapOfIndicesValid.end()) + { + ossHeaderValidLabels << separatorChar; + ossHeaderPredLabels << separatorChar; + } + else + { + ossHeaderValidLabels << std::endl; + ossHeaderPredLabels << std::endl; + } + } + + std::ofstream outFile; + outFile.open(this->GetParameterString("io.confmatout").c_str()); + outFile << std::fixed; + outFile.precision(10); + + ///////////////////////////////////// + // Writing the 2 headers + outFile << ossHeaderValidLabels.str(); + outFile << ossHeaderPredLabels.str(); + ///////////////////////////////////// + + unsigned int indexLabelValid = 0, indexLabelPred = 0; + + for (itMapOfIndicesValid = mapOfIndicesValid.begin(); itMapOfIndicesValid != mapOfIndicesValid.end(); ++itMapOfIndicesValid) + { + indexLabelPred = 0; + + for (itMapOfIndicesPred = mapOfIndicesValid.begin(); itMapOfIndicesPred != mapOfIndicesValid.end(); ++itMapOfIndicesPred) + { + // Writing the confusion matrix (sorted in otbConfusionMatrixCalculator) in the output file + outFile << confusionMatrix(indexLabelValid, indexLabelPred); + if (indexLabelPred < (nbClassesPred - 1)) + { + outFile << separatorChar; + } + else + { + outFile << std::endl; + } + ++indexLabelPred; + } + + ++indexLabelValid; + } + + outFile.close(); + } // END if (this->HasValue("io.confmatout")) + } + +}; +} +} + +OTB_APPLICATION_EXPORT(otb::Wrapper::TrainVectorClassifier) diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt index a48f3cf0a61e7f7803f01eca3edd2b48e2731c3c..d517ff822deeca638a8c2d31d591bc2c38c5b6e3 100644 --- a/Modules/Applications/AppClassification/test/CMakeLists.txt +++ b/Modules/Applications/AppClassification/test/CMakeLists.txt @@ -8,7 +8,7 @@ otb_test_application(NAME apTvClComputeOGRLayersFeaturesStatistics VALID --compare-ascii ${NOTOL} ${OTBAPP_BASELINE_FILES}/apTvClComputeOGRLayersFeaturesStatistics.xml ${TEMP}/apTvClComputeOGRLayersFeaturesStatistics.xml) - + #----------- SOMClassification TESTS ---------------- otb_test_application(NAME apTvClSOMClassificationSmall APP SOMClassification @@ -323,7 +323,7 @@ otb_test_application(NAME apTvClTrainOGRLayersClassifier ${OTBAPP_BASELINE_FILES}/apTvClModel.svm ${TEMP}/apTvClModel.svm) -set_tests_properties(apTvClTrainOGRLayersClassifier PROPERTIES DEPENDS apTvClComputeOGRLayersFeaturesStatistics) +set_tests_properties(apTvClTrainOGRLayersClassifier PROPERTIES DEPENDS apTvClComputeOGRLayersFeaturesStatistics) #----------- ComputeConfusionMatrix TESTS ---------------- otb_test_application(NAME apTvComputeConfusionMatrixV @@ -580,7 +580,7 @@ otb_test_application(NAME apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_gt ${OTBAPP_BASELINE_FILES}/cdbTvComputePolylineFeatureFromImage_LI_NOBUIL_gt.shp ${TEMP}/apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_gt.shp) -set_tests_properties(apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_gt PROPERTIES DEPENDS apTvCdbComputePolylineFeatureFromImage_LI_ROADSA_gt) +set_tests_properties(apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_gt PROPERTIES DEPENDS apTvCdbComputePolylineFeatureFromImage_LI_ROADSA_gt) otb_test_application(NAME apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_RoadExtractionApplication APP ComputePolylineFeatureFromImage @@ -593,7 +593,7 @@ otb_test_application(NAME apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_RoadE ${OTBAPP_BASELINE_FILES}/cdbTvComputePolylineFeatureFromImage_LI_NOBUIL_RoadExtractionApplication.shp ${TEMP}/apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_RoadExtractionApplication.shp) -set_tests_properties(apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_RoadExtractionApplication PROPERTIES DEPENDS apTvCdbComputePolylineFeatureFromImage_LI_ROADSA_RoadExtractionApplication) +set_tests_properties(apTvCdbComputePolylineFeatureFromImage_LI_NOBUIL_RoadExtractionApplication PROPERTIES DEPENDS apTvCdbComputePolylineFeatureFromImage_LI_ROADSA_RoadExtractionApplication) endif() #----------- KMeansClassification TESTS ---------------- @@ -874,9 +874,22 @@ otb_test_application(NAME apTvClSampleSelection otb_test_application(NAME apTvClSampleExtraction APP SampleExtraction OPTIONS -in ${INPUTDATA}/Classification/QB_1_ortho.tif - -vec ${OTBAPP_BASELINE_FILES}/apTvClSampleSelectionOut.sqlite + -vec ${INPUTDATA}/Classification/apTvClSampleSelectionOut.sqlite -field Class -out ${TEMP}/apTvClSampleExtractionOut.sqlite VALID --compare-ogr ${NOTOL} ${OTBAPP_BASELINE_FILES}/apTvClSampleExtractionOut.sqlite ${TEMP}/apTvClSampleExtractionOut.sqlite) + +#----------- TrainVectorClassifier TESTS ---------------- +otb_test_application(NAME apTvClTrainVectorClassifier + APP TrainVectorClassifier + OPTIONS -io.vd ${INPUTDATA}/Classification/apTvClSampleExtractionOut.sqlite + -feat value_0 value_1 value_2 value_3 + -cfield class + -classifier rf + -io.confmatout ${TEMP}/apTvClTrainVectorClassifierConfMat.txt + -io.out ${TEMP}/apTvClTrainVectorClassifierModel.rf + VALID --compare-ascii ${NOTOL} + ${OTBAPP_BASELINE_FILES}/apTvClTrainVectorClassifierModel.rf + ${TEMP}/apTvClTrainVectorClassifierModel.rf) diff --git a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx index 6084c38755b3e54cb51fb29bdda94f2f7bdfbefa..7cc5fec08428478bb239073828e314cc96e7d24f 100644 --- a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx +++ b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx @@ -109,6 +109,10 @@ private: AddParameter(ParameterType_Float, "psnr", "PSNR"); SetParameterDescription("psnr", "Peak Signal to Noise Ratio value"); SetParameterRole("psnr", Role_Output); + + AddParameter(ParameterType_Float, "count", "count"); + SetParameterDescription("count", "Nb of pixels which are different"); + SetParameterRole("count", Role_Output); // Doc example parameter settings SetDocExampleParameterValue("ref.in", "GomaApres.png"); @@ -208,10 +212,12 @@ private: otbAppLogINFO( << "MSE: " << m_CompareFilter->GetMSE() ); otbAppLogINFO( << "MAE: " << m_CompareFilter->GetMAE() ); otbAppLogINFO( << "PSNR: " << m_CompareFilter->GetPSNR() ); + otbAppLogINFO( << "Number of Pixel different: " << m_CompareFilter->GetDiffCount() ); SetParameterFloat( "mse", m_CompareFilter->GetMSE() ); SetParameterFloat( "mae", m_CompareFilter->GetMAE() ); SetParameterFloat( "psnr", m_CompareFilter->GetPSNR() ); + SetParameterFloat( "count", m_CompareFilter->GetDiffCount() ); } diff --git a/Modules/Feature/Descriptors/include/otbFourierMellinDescriptorsImageFunction.txx b/Modules/Feature/Descriptors/include/otbFourierMellinDescriptorsImageFunction.txx index 9fc9bd0612b42e937f55a9298136fb4d26cc1c7c..b09664aa84a46554cf431e8b4f53268dad9dbafb 100644 --- a/Modules/Feature/Descriptors/include/otbFourierMellinDescriptorsImageFunction.txx +++ b/Modules/Feature/Descriptors/include/otbFourierMellinDescriptorsImageFunction.txx @@ -112,12 +112,12 @@ FourierMellinDescriptorsImageFunction<TInputImage, TCoordRep> for (unsigned int q= 0; q <= m_Qmax; q++) { ScalarComplexType power(double(p-2.0+m_Sigma)/2.0, -double(q)/2.0); - - if (x!=0 || y!=0) // vcl_pow limitations - { - coefs.at(p).at(q) += vcl_pow(xplusiy, -p) * vcl_pow(x2plusy2, power) * value; - } - } + + if(x!=0 || y !=0) // vcl_pow limitation + { + coefs.at(p).at(q) += vcl_pow(xplusiy, -static_cast<double>(p)) * vcl_pow(x2plusy2, power) * value; + } + } } } diff --git a/Modules/Feature/Moments/include/otbComplexMomentsImageFunction.txx b/Modules/Feature/Moments/include/otbComplexMomentsImageFunction.txx index 87a6c081c194efb9c2de109bcb001010f874ebcd..349ba6028c63032453e9538a5002d3dfb3fd988e 100644 --- a/Modules/Feature/Moments/include/otbComplexMomentsImageFunction.txx +++ b/Modules/Feature/Moments/include/otbComplexMomentsImageFunction.txx @@ -106,11 +106,23 @@ ComplexMomentsImageFunction<TInputImage, TCoordRep> { for (unsigned int q= 0; q <= m_Qmax; q++) { - moments.at(p).at(q) += vcl_pow(xpy, p) * vcl_pow(xqy, q) * value; + ScalarComplexType pow1(1,0); + ScalarComplexType pow2(1,0); + if(p!=0 || x!=0 || y != 0) + { + pow1=vcl_pow(xpy,p); + } + if(q!=0 || x!=0 || y != 0) + { + pow2=vcl_pow(xqy,q); + } + + moments.at(p).at(q) += pow1 * pow2 * value; + } } } - + // Normalisation for (int p = m_Pmax; p >= 0; p--) { diff --git a/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.h b/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.h index 12eba3b2ecb48936f45c96cfdb7acb94f3e589d9..dc4c43787601a3ea71f9d7adae682281b9fa03a9 100644 --- a/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.h +++ b/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.h @@ -123,6 +123,14 @@ public: } RealObjectType* GetMAEOutput(); const RealObjectType* GetMAEOutput() const; + + /** Return the Number of Pixel which are different. */ + RealType GetDiffCount() const + { + return this->GetDiffCountOutput()->Get(); + } + RealObjectType* GetDiffCountOutput(); + const RealObjectType* GetDiffCountOutput() const; itkGetMacro(PhysicalSpaceCheck,bool); itkSetMacro(PhysicalSpaceCheck,bool); @@ -164,6 +172,7 @@ private: itk::Array<PixelType> m_ThreadMinRef; itk::Array<PixelType> m_ThreadMaxRef; itk::Array<long> m_Count; + itk::Array<long> m_DiffCount; bool m_PhysicalSpaceCheck; }; // end of class PersistentCompareImageFilter @@ -278,6 +287,20 @@ public: { return this->GetFilter()->GetMAEOutput(); } + + /** Return the Number of Pixel different. */ + RealType GetDiffCount() const + { + return this->GetFilter()->GetDiffCountOutput()->Get(); + } + RealObjectType* GetDiffCountOutput() + { + return this->GetFilter()->GetDiffCountOutput(); + } + const RealObjectType* GetDiffCountOutput() const + { + return this->GetFilter()->GetDiffCountOutput(); + } /** Set the PhysicalSpaceCheck flag */ void SetPhysicalSpaceCheck(bool flag) diff --git a/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.txx b/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.txx index 9d91807f162bcc89b288009b1002e91ac4229873..7c1c39f35a06c83538cfe65a262767a6a42ea3ab 100644 --- a/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.txx +++ b/Modules/Filtering/Statistics/include/otbStreamingCompareImageFilter.txx @@ -21,6 +21,7 @@ #include "itkImageRegionIterator.h" #include "itkProgressReporter.h" +#include "itkMath.h" #include "otbMacro.h" namespace otb @@ -29,7 +30,7 @@ namespace otb template<class TInputImage> PersistentCompareImageFilter<TInputImage> ::PersistentCompareImageFilter() : m_SquareOfDifferences(1), m_AbsoluteValueOfDifferences(1), - m_ThreadMinRef(1), m_ThreadMaxRef(1), m_Count(1), m_PhysicalSpaceCheck(true) + m_ThreadMinRef(1), m_ThreadMaxRef(1), m_Count(1), m_DiffCount(1), m_PhysicalSpaceCheck(true) { this->SetNumberOfRequiredInputs( 2 ); // first output is a copy of the image, DataObject created by @@ -37,7 +38,7 @@ PersistentCompareImageFilter<TInputImage> // allocate the data objects for the outputs which are // just decorators around real types - for (int i = 1; i < 4; ++i) + for (int i = 1; i < 5; ++i) { typename RealObjectType::Pointer output = static_cast<RealObjectType*>(this->MakeOutput(i).GetPointer()); @@ -47,6 +48,7 @@ PersistentCompareImageFilter<TInputImage> this->GetPSNROutput()->Set(itk::NumericTraits<RealType>::max()); this->GetMSEOutput()->Set(itk::NumericTraits<RealType>::max()); this->GetMAEOutput()->Set(itk::NumericTraits<RealType>::max()); + this->GetDiffCountOutput()->Set(itk::NumericTraits<RealType>::Zero); this->Reset(); } @@ -112,6 +114,7 @@ PersistentCompareImageFilter<TInputImage> case 1: case 2: case 3: + case 4: return static_cast<itk::DataObject*>(RealObjectType::New().GetPointer()); break; default: @@ -169,6 +172,22 @@ PersistentCompareImageFilter<TInputImage> return static_cast<const RealObjectType*>(this->itk::ProcessObject::GetOutput(3)); } +template<class TInputImage> +typename PersistentCompareImageFilter<TInputImage>::RealObjectType* +PersistentCompareImageFilter<TInputImage> +::GetDiffCountOutput() +{ + return static_cast<RealObjectType*>(this->itk::ProcessObject::GetOutput(4)); +} + +template<class TInputImage> +const typename PersistentCompareImageFilter<TInputImage>::RealObjectType* +PersistentCompareImageFilter<TInputImage> +::GetDiffCountOutput() const +{ + return static_cast<const RealObjectType*>(this->itk::ProcessObject::GetOutput(4)); +} + template<class TInputImage> void PersistentCompareImageFilter<TInputImage> @@ -204,7 +223,8 @@ PersistentCompareImageFilter<TInputImage> ::Synthetize() { int i; - long count; + unsigned long count; + unsigned long diffCount; RealType squareOfDifferences, absoluteValueOfDifferences; int numberOfThreads = this->GetNumberOfThreads(); @@ -216,6 +236,7 @@ PersistentCompareImageFilter<TInputImage> squareOfDifferences = absoluteValueOfDifferences = itk::NumericTraits<RealType>::Zero; count = 0; + diffCount=0; // Find min/max and the accumulate count and difference of squares over all threads minimumRef = itk::NumericTraits<PixelType>::max(); @@ -224,6 +245,7 @@ PersistentCompareImageFilter<TInputImage> for (i = 0; i < numberOfThreads; ++i) { count += m_Count[i]; + diffCount += m_DiffCount[i]; squareOfDifferences += m_SquareOfDifferences[i]; absoluteValueOfDifferences += m_AbsoluteValueOfDifferences[i]; @@ -248,6 +270,7 @@ PersistentCompareImageFilter<TInputImage> this->GetMSEOutput()->Set(mse); this->GetMAEOutput()->Set(mae); this->GetPSNROutput()->Set(psnr); + this->GetDiffCountOutput()->Set(static_cast<RealType>(diffCount)); } template<class TInputImage> @@ -259,6 +282,7 @@ PersistentCompareImageFilter<TInputImage> // Resize the thread temporaries m_Count.SetSize(numberOfThreads); + m_DiffCount.SetSize(numberOfThreads); m_SquareOfDifferences.SetSize(numberOfThreads); m_AbsoluteValueOfDifferences.SetSize(numberOfThreads); @@ -267,6 +291,7 @@ PersistentCompareImageFilter<TInputImage> // Initialize the temporaries m_Count.Fill(itk::NumericTraits<long>::Zero); + m_DiffCount.Fill(itk::NumericTraits<long>::Zero); m_SquareOfDifferences.Fill(itk::NumericTraits<RealType>::Zero); m_AbsoluteValueOfDifferences.Fill(itk::NumericTraits<RealType>::Zero); m_ThreadMinRef.Fill(itk::NumericTraits<PixelType>::max()); @@ -322,9 +347,14 @@ PersistentCompareImageFilter<TInputImage> { m_ThreadMaxRef[threadId] = value1; } - - m_SquareOfDifferences[threadId] += ( realValue1 - realValue2 ) * ( realValue1 - realValue2 ); - m_AbsoluteValueOfDifferences[threadId] += vcl_abs( realValue1 - realValue2 ); + + RealType diffVal = realValue1 - realValue2; + m_SquareOfDifferences[threadId] += diffVal * diffVal; + m_AbsoluteValueOfDifferences[threadId] += vcl_abs( diffVal ); + if (! itk::Math::FloatAlmostEqual(realValue1, realValue2)) + { + m_DiffCount[threadId]++; + } m_Count[threadId]++; ++it1; ++it2; @@ -340,7 +370,8 @@ PersistentCompareImageFilter<TImage> os << indent << "PSNR: " << this->GetPSNR() << std::endl; os << indent << "MSE: " << this->GetMSE() << std::endl; - os << indent << "MAE: " << this->GetMAE() << std::endl; + os << indent << "MAE: " << this->GetMAE() << std::endl; + os << indent << "Count: " << this->GetDiffCount() << std::endl; } } // end namespace otb #endif diff --git a/Modules/Filtering/Statistics/test/otbStreamingCompareImageFilter.cxx b/Modules/Filtering/Statistics/test/otbStreamingCompareImageFilter.cxx index 2a213139bc9b43b7cf3c54dbdf07330950180533..e6a1c7f9b9d05c8c4940fdc18e9d8606e03f06d9 100644 --- a/Modules/Filtering/Statistics/test/otbStreamingCompareImageFilter.cxx +++ b/Modules/Filtering/Statistics/test/otbStreamingCompareImageFilter.cxx @@ -73,6 +73,7 @@ int otbStreamingCompareImageFilter(int itkNotUsed(argc), char * argv[]) file << "MSE: " << filter->GetMSE() << std::endl; file << "MAE: " << filter->GetMAE() << std::endl; file << "PSNR: " << filter->GetPSNR() << std::endl; + file << "Count: " << filter->GetDiffCount() << std::endl; file.close(); diff --git a/Modules/IO/IOXML/include/otbStatisticsXMLFileReader.txx b/Modules/IO/IOXML/include/otbStatisticsXMLFileReader.txx index cf7bf353476274c0c7ffd5df6f1de1b4d061545f..92824197c7f7240e67294d24ca9ebc3dbbc563ac 100644 --- a/Modules/IO/IOXML/include/otbStatisticsXMLFileReader.txx +++ b/Modules/IO/IOXML/include/otbStatisticsXMLFileReader.txx @@ -155,9 +155,10 @@ StatisticsXMLFileReader<TMeasurementVector> itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName"); // Check that the right extension is given : expected .xml */ - if (itksys::SystemTools::GetFilenameLastExtension(m_FileName) != ".xml") + std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName); + if (itksys::SystemTools::LowerCase(extension) != ".xml") { - itkExceptionMacro(<<itksys::SystemTools::GetFilenameLastExtension(m_FileName) + itkExceptionMacro(<<extension <<" is a wrong Extension FileName : Expected .xml"); } diff --git a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx index 9f669178e2e13e6c113a9b5048a57a4210230cea..11d38b72d8fd91b33e5cbd2c2e09e30b3d73c2c0 100644 --- a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx +++ b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx @@ -69,9 +69,10 @@ StatisticsXMLFileWriter<TMeasurementVector> itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName"); // Check that the right extension is given : expected .xml */ - if (itksys::SystemTools::GetFilenameLastExtension(m_FileName) != ".xml") + std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName); + if (itksys::SystemTools::LowerCase(extension) != ".xml") { - itkExceptionMacro(<<itksys::SystemTools::GetFilenameLastExtension(m_FileName) + itkExceptionMacro(<<extension <<" is a wrong Extension FileName : Expected .xml"); } diff --git a/Modules/IO/IOXML/test/CMakeLists.txt b/Modules/IO/IOXML/test/CMakeLists.txt index 43714a9979b3a9d891e3a5773f079314ea5d8bf8..869367708d57ac2c302cf3eb74a82a550311c9e9 100644 --- a/Modules/IO/IOXML/test/CMakeLists.txt +++ b/Modules/IO/IOXML/test/CMakeLists.txt @@ -17,5 +17,5 @@ otb_add_test(NAME ioTvStatisticsXMLReaderWriter COMMAND otbIOXMLTestDriver ${TEMP}/ioTvStatisticsXMLReaderWriterOut3.xml otbStatisticsXMLFileWriteAndRead ${TEMP}/ioTvStatisticsXMLReaderWriterOut1.xml - ${TEMP}/ioTvStatisticsXMLReaderWriterOut2.xml + ${TEMP}/ioTvStatisticsXMLReaderWriterOut2.XML ${TEMP}/ioTvStatisticsXMLReaderWriterOut3.xml) diff --git a/SuperBuild/CMake/External_glew.cmake b/SuperBuild/CMake/External_glew.cmake index 85d7e86a45e458707dd8e4e900f4b0fe0eb21f0d..40e2359ba5820691bd02356044c861659819a39f 100644 --- a/SuperBuild/CMake/External_glew.cmake +++ b/SuperBuild/CMake/External_glew.cmake @@ -10,8 +10,7 @@ ExternalProject_Add(GLEW BINARY_DIR ${GLEW_SB_BUILD_DIR} DOWNLOAD_DIR ${DOWNLOAD_LOCATION} INSTALL_DIR ${SB_INSTALL_PREFIX} - CONFIGURE_COMMAND - ${SB_CMAKE_COMMAND} ${GLEW_SB_SRC}/build/cmake/ ${SB_CMAKE_CACHE_ARGS} -DBUILD_UTILS:BOOL=OFF + CONFIGURE_COMMAND ${SB_CMAKE_COMMAND} ${GLEW_SB_SRC}/build/cmake/ ${SB_CMAKE_CACHE_ARGS} -DBUILD_UTILS:BOOL=OFF ) set(_SB_GLEW_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include) diff --git a/SuperBuild/CMake/External_itk.cmake b/SuperBuild/CMake/External_itk.cmake index 4c25f8729251afde3b5dffbd62a9bb2ca7ee189c..70b72ddfeb053c4ee28ca6f7d89d0d08b3e8d450 100644 --- a/SuperBuild/CMake/External_itk.cmake +++ b/SuperBuild/CMake/External_itk.cmake @@ -137,8 +137,8 @@ set(_SB_ITK_DIR ${SB_INSTALL_PREFIX}/lib/cmake/ITK-${ITK_SB_VERSION}) ExternalProject_Add(ITK PREFIX ITK - URL "https://sourceforge.net/projects/itk/files/itk/4.10/InsightToolkit-4.10.0.tar.xz" - URL_MD5 15beb120e580ce85117496795746e628 + URL "http://downloads.sourceforge.net/project/itk/itk/4.10/InsightToolkit-4.10.0.tar.gz" + URL_MD5 8c67ba296da3835fb67bb29d98dcff3e SOURCE_DIR ${ITK_SB_SRC} BINARY_DIR ${ITK_SB_BUILD_DIR} INSTALL_DIR ${SB_INSTALL_PREFIX} diff --git a/SuperBuild/CMake/External_proj.cmake b/SuperBuild/CMake/External_proj.cmake index df7f919ce89137a99134204425e5c99864db9160..ff30d40bb0db554c8f508c205690124d75f07640 100644 --- a/SuperBuild/CMake/External_proj.cmake +++ b/SuperBuild/CMake/External_proj.cmake @@ -3,8 +3,7 @@ INCLUDE_ONCE_MACRO(PROJ) SETUP_SUPERBUILD(PROJ) if(MSVC) - - ExternalProject_Add(PROJ_build + ExternalProject_Add(PROJ PREFIX PROJ URL "http://download.osgeo.org/proj/proj-4.8.0.tar.gz" URL_MD5 d815838c92a29179298c126effbb1537 @@ -14,26 +13,11 @@ if(MSVC) DOWNLOAD_DIR ${DOWNLOAD_LOCATION} CONFIGURE_COMMAND "" BUILD_COMMAND nmake /f ${PROJ_SB_SRC}/makefile.vc - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/PROJ/CMakeLists.txt - ${CMAKE_BINARY_DIR}/PROJ/_install - ) - - ExternalProject_Add(PROJ - PREFIX PROJ/_install - DOWNLOAD_COMMAND "" - SOURCE_DIR PROJ/_install - BINARY_DIR ${PROJ_SB_SRC} - INSTALL_DIR ${SB_INSTALL_PREFIX} - DOWNLOAD_DIR ${DOWNLOAD_LOCATION} - CMAKE_CACHE_ARGS - -DCMAKE_INSTALL_PREFIX:STRING=${SB_INSTALL_PREFIX} - -DCMAKE_BUILD_TYPE:STRING=Release - -DPROJ4_BUILD_DIR:STRING=${PROJ_SB_SRC}/src - DEPENDS PROJ_build - CMAKE_COMMAND + INSTALL_COMMAND nmake /f ${PROJ_SB_SRC}/makefile.vc install-all INSTDIR=${SB_INSTALL_PREFIX_NATIVE} ) else() + ExternalProject_Add(PROJ PREFIX PROJ URL "http://download.osgeo.org/proj/proj-4.8.0.tar.gz" @@ -42,7 +26,6 @@ else() INSTALL_DIR ${SB_INSTALL_PREFIX} DOWNLOAD_DIR ${DOWNLOAD_LOCATION} CONFIGURE_COMMAND - # use 'env' because CTest launcher doesn't perform shell interpretation ${SB_ENV_CONFIGURE_CMD} ${PROJ_SB_SRC}/configure --prefix=${SB_INSTALL_PREFIX} @@ -51,12 +34,10 @@ else() INSTALL_COMMAND $(MAKE) install ) - if(APPLE) - SUPERBUILD_PATCH_SOURCE(PROJ) - endif() - endif() +SUPERBUILD_PATCH_SOURCE(PROJ) + set(_SB_PROJ_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include) if(WIN32) set(_SB_PROJ_LIBRARY ${SB_INSTALL_PREFIX}/lib/proj_i.lib) diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 01715b337040bd7df450c6bcf099c4159c6ec3ef..d24dcb8eaf8509728d72530c62b8d8c5f9a865aa 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -70,6 +70,8 @@ endif() set(SB_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +file(TO_NATIVE_PATH "${SB_INSTALL_PREFIX}" SB_INSTALL_PREFIX_NATIVE) + # Check if CMAKE_INSTALL_PREFIX is set by default if(WIN32) if(CMAKE_INSTALL_PREFIX STREQUAL "C:/Program Files (x86)/OTB-SuperBuild" diff --git a/SuperBuild/Packaging/PackageHelper.cmake b/SuperBuild/Packaging/PackageHelper.cmake index 3177c68e3cabdda5d5ee296a55a7f1528526c496..1420af8e75e6824dd14fc74c0def58edd3a03254 100644 --- a/SuperBuild/Packaging/PackageHelper.cmake +++ b/SuperBuild/Packaging/PackageHelper.cmake @@ -198,8 +198,12 @@ function(func_install_xdk_files) set(QT_REQ_DIRS) if(WIN32) #only affects windows due to regex on dll - file(GLOB LIB_FILES "${DEPENDENCIES_INSTALL_DIR}/lib/*dll.*") - install(FILES ${LIB_FILES} DESTINATION ${PKG_STAGE_DIR}/lib ) + if(MSVC) + file(GLOB LIB_FILES "${DEPENDENCIES_INSTALL_DIR}/lib/*.lib") + else() + file(GLOB LIB_FILES "${DEPENDENCIES_INSTALL_DIR}/lib/*dll.*") + endif() + install(FILES ${LIB_FILES} DESTINATION ${PKG_STAGE_DIR}/lib ) file(GLOB ITK_EXTRA_DLL_FILES_1 "${DEPENDENCIES_INSTALL_DIR}/bin/libITK*.dll") install(FILES ${ITK_EXTRA_DLL_FILES_1} DESTINATION ${PKG_STAGE_DIR}/bin) diff --git a/SuperBuild/patches/PROJ/CMakeLists.txt b/SuperBuild/patches/PROJ/CMakeLists.txt deleted file mode 100644 index 7f1ad4cbffee95e450f4b04ee6bd1a596db23ade..0000000000000000000000000000000000000000 --- a/SuperBuild/patches/PROJ/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required(VERSION 2.8.3) - -project(proj_install) - -file(GLOB ${PROJECT_NAME}_HEADERS "${PROJ4_BUILD_DIR}/projects.h" "${PROJ4_BUILD_DIR}/proj_api.h" "${PROJ_INCLUDE_DIR}/org_proj4_Projections.h" ) -file(GLOB ${PROJECT_NAME}_LIBS "${PROJ4_BUILD_DIR}/*.lib" ) -file(GLOB ${PROJECT_NAME}_DLLS "${PROJ4_BUILD_DIR}/*.dll" ) - -foreach(${PROJECT_NAME}_HEADER ${${PROJECT_NAME}_HEADERS}) -install(FILES ${${PROJECT_NAME}_HEADER} - DESTINATION include - COMPONENT Development) -endforeach() - -foreach(${PROJECT_NAME}_LIB ${${PROJECT_NAME}_LIBS}) -install(FILES ${${PROJECT_NAME}_LIB} - DESTINATION lib - COMPONENT Development) -endforeach() - -foreach(${PROJECT_NAME}_DLL ${${PROJECT_NAME}_DLLS}) -install(FILES ${${PROJECT_NAME}_DLL} - DESTINATION bin - COMPONENT Development) -endforeach() \ No newline at end of file