Commit 1ffa7b13 authored by Mickael Savinaud's avatar Mickael Savinaud
Browse files

Merge branch 'develop' into improve_CompareImages_app

parents 82d427e0 239e3c73
......@@ -109,8 +109,13 @@ otb_create_application(
NAME PolygonClassStatistics
SOURCES otbPolygonClassStatistics.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME SampleSelection
SOURCES otbSampleSelection.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME SampleExtraction
SOURCES otbSampleExtraction.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
/*=========================================================================
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 "otbImageSampleExtractorFilter.h"
namespace otb
{
namespace Wrapper
{
class SampleExtraction : public Application
{
public:
/** Standard class typedefs. */
typedef SampleExtraction Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(SampleExtraction, otb::Application);
/** Filters typedef */
typedef otb::ImageSampleExtractorFilter<FloatVectorImageType> FilterType;
private:
SampleExtraction() {}
void DoInit()
{
SetName("SampleExtraction");
SetDescription("Extracts samples values from an image.");
// Documentation
SetDocName("Sample Extraction");
SetDocLongDescription("The application extracts samples values from an"
"image using positions contained in a vector data file. ");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso(" ");
AddDocTag(Tags::Learning);
AddParameter(ParameterType_InputImage, "in", "InputImage");
SetParameterDescription("in", "Support image");
AddParameter(ParameterType_InputFilename, "vec", "Input sampling positions");
SetParameterDescription("vec","Vector data file containing sampling"
"positions. (OGR format)");
AddParameter(ParameterType_OutputFilename, "out", "Output samples");
SetParameterDescription("out","Output vector data file storing sample"
"values (OGR format). If not given, the input vector data file is updated");
MandatoryOff("out");
AddParameter(ParameterType_Choice, "outfield", "Output field names");
SetParameterDescription("outfield", "Choice between naming method for output fields");
AddChoice("outfield.prefix","Use a prefix and an incremental counter");
SetParameterDescription("outfield.prefix","Use a prefix and an incremental counter");
AddParameter(ParameterType_String, "outfield.prefix.name", "Output field prefix");
SetParameterDescription("outfield.prefix.name","Prefix used to form the field names that"
"will contain the extracted values.");
SetParameterString("outfield.prefix.name", "value_");
AddChoice("outfield.list","Use the given name list");
SetParameterDescription("outfield.list","Use the given name list");
AddParameter(ParameterType_StringList, "outfield.list.names", "Output field names");
SetParameterDescription("outfield.list.names","Full list of output field names.");
AddParameter(ParameterType_String, "field", "Field Name");
SetParameterDescription("field","Name of the field carrying the class"
"name in the input vectors. This field is copied to output.");
MandatoryOff("field");
SetParameterString("field", "class");
AddParameter(ParameterType_Int, "layer", "Layer Index");
SetParameterDescription("layer", "Layer index to read in the input vector file.");
MandatoryOff("layer");
SetDefaultParameterInt("layer",0);
AddRAMParameter();
// Doc example parameter settings
SetDocExampleParameterValue("in", "support_image.tif");
SetDocExampleParameterValue("vec", "sample_positions.sqlite");
SetDocExampleParameterValue("pre","band_");
SetDocExampleParameterValue("field", "label");
SetDocExampleParameterValue("out","sample_values.sqlite");
}
void DoUpdateParameters()
{
// Nothing to do
}
void DoExecute()
{
ogr::DataSource::Pointer vectors;
ogr::DataSource::Pointer output;
if (IsParameterEnabled("out") && HasValue("out"))
{
vectors = ogr::DataSource::New(this->GetParameterString("vec"));
output = ogr::DataSource::New(this->GetParameterString("out"),
ogr::DataSource::Modes::Overwrite);
}
else
{
// Update mode
vectors = ogr::DataSource::New(this->GetParameterString("vec"),
ogr::DataSource::Modes::Update_LayerUpdate);
output = vectors;
}
std::vector<std::string> nameList;
std::string namePrefix("");
if (this->GetParameterString("outfield").compare("prefix") == 0)
{
namePrefix = this->GetParameterString("outfield.prefix.name");
}
else if (this->GetParameterString("outfield").compare("list") == 0)
{
nameList = this->GetParameterStringList("outfield.list.names");
}
else
{
otbAppLogFATAL("Unkown output field option : " << this->GetParameterString("outfield"));
}
FilterType::Pointer filter = FilterType::New();
filter->SetInput(this->GetParameterImage("in"));
filter->SetLayerIndex(this->GetParameterInt("layer"));
filter->SetSamplePositions(vectors);
filter->SetOutputSamples(output);
filter->SetClassFieldName(this->GetParameterString("field"));
filter->SetOutputFieldPrefix(namePrefix);
filter->SetOutputFieldNames(nameList);
AddProcess(filter->GetStreamer(),"Extracting sample values...");
filter->Update();
output->SyncToDisk();
}
};
} // end of namespace Wrapper
} // end of namespace otb
OTB_APPLICATION_EXPORT(otb::Wrapper::SampleExtraction)
......@@ -78,7 +78,7 @@ private:
SetDescription("Selects samples from a training vector data set.");
// Documentation
SetDocName("Polygon Class Statistics");
SetDocName("Sample Selection");
SetDocLongDescription("The application selects a set of samples from geometries "
"intended for training (they should have a field giving the associated "
"class). \n\nFirst of all, the geometries must be analyzed by the PolygonClassStatistics application "
......
......@@ -869,3 +869,14 @@ otb_test_application(NAME apTvClSampleSelection
VALID --compare-ogr ${NOTOL}
${OTBAPP_BASELINE_FILES}/apTvClSampleSelectionOut.sqlite
${TEMP}/apTvClSampleSelectionOut.sqlite)
#----------- SampleExtraction TESTS -----------------------
otb_test_application(NAME apTvClSampleExtraction
APP SampleExtraction
OPTIONS -in ${INPUTDATA}/Classification/QB_1_ortho.tif
-vec ${OTBAPP_BASELINE_FILES}/apTvClSampleSelectionOut.sqlite
-field Class
-out ${TEMP}/apTvClSampleExtractionOut.sqlite
VALID --compare-ogr ${NOTOL}
${OTBAPP_BASELINE_FILES}/apTvClSampleExtractionOut.sqlite
${TEMP}/apTvClSampleExtractionOut.sqlite)
......@@ -234,17 +234,17 @@ private:
SetParameterDescription( "out", "The output image. The output image is the segmentation of the filtered image. It is recommended to set the pixel type to uint32." );
SetDefaultOutputPixelType("out",ImagePixelType_uint32);
AddParameter(ParameterType_Float, "ranger", "Range radius");
SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
SetDefaultParameterFloat("ranger", 15);
SetMinimumParameterFloatValue("ranger", 0);
MandatoryOff("ranger");
AddParameter(ParameterType_Float, "spatialr", "Spatial radius");
SetParameterDescription("spatialr", "Spatial radius of the neighborhood.");
SetDefaultParameterFloat("spatialr", 5);
SetMinimumParameterFloatValue("spatialr", 0);
MandatoryOff("spatialr");
AddParameter(ParameterType_Float, "ranger", "Range radius");
SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
SetDefaultParameterFloat("ranger", 15);
SetMinimumParameterFloatValue("ranger", 0);
MandatoryOff("ranger");
AddParameter(ParameterType_Int, "minsize", "Minimum Region Size");
SetParameterDescription("minsize", "Minimum Region Size. If, after the segmentation, a region is of size lower than this criterion, the region is deleted.");
......@@ -276,8 +276,8 @@ private:
SetDocExampleParameterValue("in","smooth.tif");
SetDocExampleParameterValue("inpos","position.tif");
SetDocExampleParameterValue("out","segmentation.tif");
SetDocExampleParameterValue("ranger","15");
SetDocExampleParameterValue("spatialr","5");
SetDocExampleParameterValue("ranger","15");
SetDocExampleParameterValue("minsize","0");
SetDocExampleParameterValue("tilesizex","256");
SetDocExampleParameterValue("tilesizey","256");
......
......@@ -162,24 +162,25 @@ otb_add_test(NAME coTvMultiChannelROI_RGB2NG_PNG3 COMMAND otbImageBaseTestDriver
${TEMP}/coMultiChannelExtractROI_RGB2NG_PNG_300_10_250_50_channel_3.png
-startX 300 -startY 10 -sizeX 250 -sizeY 50 -channels 3 )
otb_add_test(NAME ioTvMultiDatasetReading2 COMMAND otbImageBaseTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReading2.txt
${TEMP}/ioTvMultiDatasetReading2.txt
--ignore-lines-with 1 Pointer:
otbVectorImageTest
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=5
${TEMP}/ioTvMultiDatasetReading2.txt
)
otb_add_test(NAME ioTvMultiDatasetReading1 COMMAND otbImageBaseTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReading1.txt
${TEMP}/ioTvMultiDatasetReading1.txt
--ignore-lines-with 1 Pointer:
otbVectorImageTest
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=0
${TEMP}/ioTvMultiDatasetReading1.txt
)
if(GDAL_HAS_HDF4)
otb_add_test(NAME ioTvMultiDatasetReading2 COMMAND otbImageBaseTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReading2.txt
${TEMP}/ioTvMultiDatasetReading2.txt
--ignore-lines-with 1 Pointer:
otbVectorImageTest
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=5
${TEMP}/ioTvMultiDatasetReading2.txt
)
otb_add_test(NAME ioTvMultiDatasetReading1 COMMAND otbImageBaseTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReading1.txt
${TEMP}/ioTvMultiDatasetReading1.txt
--ignore-lines-with 1 Pointer:
otbVectorImageTest
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=0
${TEMP}/ioTvMultiDatasetReading1.txt
)
endif()
otb_add_test(NAME coTvExtractROITestMetaData_TIFF COMMAND otbImageBaseTestDriver
--compare-ascii ${NOTOL}
${TEMP}/coTvExtractROITestMetaData1.txt
......@@ -631,25 +632,28 @@ otb_add_test(NAME ioTvMultiChannelROI_QuickbirdXS2TIFF COMMAND otbImageBaseTes
-startX 1000 -startY 1000 -sizeX 100 -sizeY 150
)
# Tests which read data in HDF files.
otb_add_test(NAME ioTvMultiChannelROI_HDF4_2_TIF COMMAND otbImageBaseTestDriver
--compare-image ${EPSILON_9} ${BASELINE}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1.tif
${TEMP}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1_OUT.tif
otbMultiChannelExtractROI
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=5
${TEMP}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1_OUT.tif
-startX 1400 -startY 3700 -sizeX 100 -sizeY 150
-channels 1 )
otb_add_test(NAME ioTvMultiChannelROI_HDF5_2_TIF COMMAND otbImageBaseTestDriver
--compare-image ${EPSILON_9} ${BASELINE}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1.tif
${TEMP}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1_OUT.tif
otbMultiChannelExtractROI
${INPUTDATA}/GSSTF_NCEP.2b.2008.12.31.he5?&sdataidx=3
${TEMP}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1_OUT.tif
-startX 100 -startY 20 -sizeX 200 -sizeY 100
-channels 1 )
if(GDAL_HAS_HDF4)
# Tests which read data in HDF files.
otb_add_test(NAME ioTvMultiChannelROI_HDF4_2_TIF COMMAND otbImageBaseTestDriver
--compare-image ${EPSILON_9} ${BASELINE}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1.tif
${TEMP}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1_OUT.tif
otbMultiChannelExtractROI
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf?&sdataidx=5
${TEMP}/ioExtractROI_HDF2TIF_MOD09Q1G_20_25_100_150_channel_1_OUT.tif
-startX 1400 -startY 3700 -sizeX 100 -sizeY 150
-channels 1 )
endif()
if(GDAL_HAS_HDF5)
otb_add_test(NAME ioTvMultiChannelROI_HDF5_2_TIF COMMAND otbImageBaseTestDriver
--compare-image ${EPSILON_9} ${BASELINE}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1.tif
${TEMP}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1_OUT.tif
otbMultiChannelExtractROI
${INPUTDATA}/GSSTF_NCEP.2b.2008.12.31.he5?&sdataidx=3
${TEMP}/ioExtractROI_HDF2TIF_GSSTF_NCEP_100_20_200_100_channel_1_OUT.tif
-startX 100 -startY 20 -sizeX 200 -sizeY 100
-channels 1 )
endif()
# Read an area inside one tile at resolution 0 (jpeg2000 conformance file with
# specific tile size at different resolution).
......
......@@ -35,7 +35,8 @@ PersistentStreamingStatisticsVectorImageFilter<TInputImage, TPrecision>
m_EnableSecondOrderStats(true),
m_UseUnbiasedEstimator(true),
m_IgnoreInfiniteValues(true),
m_IgnoreUserDefinedValue(false)
m_IgnoreUserDefinedValue(false),
m_UserIgnoredValue(itk::NumericTraits<InternalPixelType>::Zero)
{
// first output is a copy of the image, DataObject created by
// superclass
......@@ -506,7 +507,7 @@ PersistentStreamingStatisticsVectorImageFilter<TInputImage, TPrecision>
const PixelType& vectorValue = it.Get();
float finiteProbe = 0.;
bool userProbe = true;
bool userProbe = m_IgnoreUserDefinedValue;
for (unsigned int j = 0; j < vectorValue.GetSize(); ++j)
{
finiteProbe += (float)(vectorValue[j]);
......@@ -519,7 +520,7 @@ PersistentStreamingStatisticsVectorImageFilter<TInputImage, TPrecision>
}
else
{
if (m_IgnoreUserDefinedValue && (userProbe))
if (userProbe)
{
m_IgnoredUserPixelCount[threadId] ++;
}
......
......@@ -206,13 +206,15 @@ otb_add_test(NAME ioTuGDALImageIOCanRead_IKONOS_PAN COMMAND otbIOGDALTestDriver
otb_add_test(NAME ioTuGDALImageIOCanRead_FORMOSAT2 COMMAND otbIOGDALTestDriver otbGDALImageIOTestCanRead
LARGEINPUT{FORMOSAT/Sudouest_20071013_MS_fmsat/IMAGERY.TIF})
otb_add_test(NAME ioTvMultiDatasetReadingInfo COMMAND otbIOGDALTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReadingInfo.txt
${TEMP}/ioTvMultiDatasetReadingInfoOut.txt
otbMultiDatasetReadingInfo
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf
${TEMP}/ioTvMultiDatasetReadingInfoOut.txt
)
if(GDAL_HAS_HDF4)
otb_add_test(NAME ioTvMultiDatasetReadingInfo COMMAND otbIOGDALTestDriver
--compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvMultiDatasetReadingInfo.txt
${TEMP}/ioTvMultiDatasetReadingInfoOut.txt
otbMultiDatasetReadingInfo
${INPUTDATA}/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf
${TEMP}/ioTvMultiDatasetReadingInfoOut.txt
)
endif()
otb_add_test(NAME ioTuOGRVectorDataIOTestCanReadGML COMMAND otbIOGDALTestDriver
otbOGRVectorDataIOTestCanRead
......
/*=========================================================================
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.
=========================================================================*/
#ifndef __otbImageSampleExtractorFilter_h
#define __otbImageSampleExtractorFilter_h
#include "otbPersistentSamplingFilterBase.h"
#include "otbPersistentFilterStreamingDecorator.h"
#include "otbOGRDataSourceWrapper.h"
#include "otbImage.h"
namespace otb
{
/**
* \class PersistentImageSampleExtractorFilter
*
* \brief Persistent filter to extract sample values from an image
*
* \ingroup OTBSampling
*/
template<class TInputImage>
class ITK_EXPORT PersistentImageSampleExtractorFilter :
public PersistentSamplingFilterBase<TInputImage>
{
public:
/** Standard Self typedef */
typedef PersistentImageSampleExtractorFilter Self;
typedef PersistentSamplingFilterBase<TInputImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef TInputImage InputImageType;
typedef typename InputImageType::Pointer InputImagePointer;
typedef typename InputImageType::RegionType RegionType;
typedef typename InputImageType::PointType PointType;
typedef typename InputImageType::IndexType IndexType;
typedef typename InputImageType::PixelType PixelType;
typedef typename InputImageType::InternalPixelType InternalPixelType;
typedef ogr::DataSource OGRDataType;
typedef ogr::DataSource::Pointer OGRDataPointer;
typedef itk::DataObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Runtime information support. */
itkTypeMacro(PersistentImageSampleExtractorFilter, PersistentSamplingFilterBase);
/** Set the output samples OGR container
* (shall be equal to the input container for an 'update' mode) */
void SetOutputSamples(ogr::DataSource* data);
/** Get the output samples OGR container */
ogr::DataSource* GetOutputSamples();
virtual void Synthetize(void);
/** Reset method called before starting the streaming*/
virtual void Reset(void);
itkSetMacro(SampleFieldPrefix, std::string);
itkGetMacro(SampleFieldPrefix, std::string);
/** Directly set the output field names (the prefix won't be used) */
void SetSampleFieldNames(std::vector<std::string> &names);
/** Get the sample names */
const std::vector<std::string> & GetSampleFieldNames();
protected:
/** Constructor */
PersistentImageSampleExtractorFilter();
/** Destructor */
virtual ~PersistentImageSampleExtractorFilter() {}
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
/** process only points */
virtual void ThreadedGenerateData(const RegionType&, itk::ThreadIdType threadid);
private:
PersistentImageSampleExtractorFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
/** Initialize fields to store extracted values (Real type) */
void InitializeFields();
/** Prefix to generate field names for each input channel
* (ignored if the field names are given directly) */
std::string m_SampleFieldPrefix;
/** List of field names for each component */
std::vector<std::string> m_SampleFieldNames;
};
/**
* \class ImageSampleExtractorFilter
*
* \brief Extract sample values from an image into an OGRDataSource using a persistent filter
*
* \sa PersistentImageSampleExtractorFilter
*
* \ingroup OTBSampling
*/
template<class TInputImage>
class ITK_EXPORT ImageSampleExtractorFilter :
public PersistentFilterStreamingDecorator<PersistentImageSampleExtractorFilter<TInputImage> >
{
public:
/** Standard Self typedef */
typedef ImageSampleExtractorFilter Self;
typedef PersistentFilterStreamingDecorator
<PersistentImageSampleExtractorFilter
<TInputImage> > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef TInputImage InputImageType;
typedef otb::ogr::DataSource OGRDataType;
typedef typename Superclass::FilterType FilterType;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(ImageSampleExtractorFilter, PersistentFilterStreamingDecorator);
using Superclass::SetInput;
virtual void SetInput(const TInputImage* image);
const TInputImage* GetInput();
void SetSamplePositions(const otb::ogr::DataSource* data);
const otb::ogr::DataSource* GetSamplePositions();
void SetOutputSamples(OGRDataType::Pointer data);
const otb::ogr::DataSource* GetOutputSamples();
void SetOutputFieldPrefix(const std::string &key);
std::string GetOutputFieldPrefix();
/** Set the output field names */
void SetOutputFieldNames(std::vector<std::string> &names);
/** Get the output field names */
const std::vector<std::string> & GetOutputFieldNames();
void SetLayerIndex(int index);
int GetLayerIndex();
void SetClassFieldName(const std::string &name);
std::string GetClassFieldName(void);
protected:
/** Constructor */
ImageSampleExtractorFilter() {}
/** Destructor */
virtual ~ImageSampleExtractorFilter() {}
private:
ImageSampleExtractorFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
};
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbImageSampleExtractorFilter.txx"
#endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$