diff --git a/Examples/Projections/test/CMakeLists.txt b/Examples/Projections/test/CMakeLists.txt index d1ad300506a769e19cf24ed9747982cd7a4c5048..61c9985d0c46901bb172ebd19613d7871e78a3cd 100644 --- a/Examples/Projections/test/CMakeLists.txt +++ b/Examples/Projections/test/CMakeLists.txt @@ -48,7 +48,7 @@ otb_add_test(NAME prTeVectorDataProjectionExampleTest COMMAND ${OTB_TEST_DRIVER} ${BASELINE}/vectorDataProjectionExample.shp ${TEMP}/vectorDataProjectionExample.shp Execute $<TARGET_FILE:VectorDataProjectionExample> - ${INPUTDATA}/Capitole-Shadows.kml + ${OTB_DATA_ROOT}/Input/Capitole-Shadows.kml LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} ${TEMP}/vectorDataProjectionExample.shp ) @@ -58,7 +58,7 @@ otb_add_test(NAME prTeGeometriesProjectionTest COMMAND ${OTB_TEST_DRIVER} ${BASELINE}/geometriesProjectionExample.shp ${TEMP}/geometriesProjectionExample.shp Execute $<TARGET_FILE:GeometriesProjectionExample> - ${INPUTDATA}/Capitole-Shadows.shp + ${OTB_DATA_ROOT}/Input/Capitole-Shadows.shp LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} ${TEMP}/geometriesProjectionExample.shp ) diff --git a/Modules/Adapters/BoostAdapters/include/otbStringUtils.h b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..7b381c2285f028ea542933719f8ccaf66849fe89 --- /dev/null +++ b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h @@ -0,0 +1,171 @@ +/*========================================================================= + + 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 otbStringUtils_h +#define otbStringUtils_h + +#include <string> +#include <vector> +#include <cstdlib> +#include <iostream> +#include <boost/lexical_cast.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/predicate.hpp> + + +namespace boost { + +/* I want raw performance and I don't want to use strtod, atoi at different +* places. so here we are. */ +template<> +inline int lexical_cast(const std::string& arg) +{ + char* stop; + int res = std::strtol( arg.c_str(), &stop, 10); + if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(int), typeid(std::string))); + return res; +} + +template<> +inline float lexical_cast(const std::string& arg) +{ + char* stop; + float res = std::strtof( arg.c_str(), &stop); + if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(float), typeid(std::string))); + return res; +} + +template<> +inline double lexical_cast(const std::string& arg) +{ + char* stop; + double res = std::strtod( arg.c_str(), &stop); + if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(double), typeid(std::string))); + return res; +} + + +/* there could also be specialised vice-versa conversion below */ +// template<> +// inline std::string lexical_cast(const int& arg) +// { +// char buffer[20]; // large enough for arg < 2^200 + +// ltoa( arg, buffer, 10 ); +// return std::string( buffer ); // RVO will take place here +// } + +}//namespace boost + + +namespace otb +{ +namespace Utils +{ + +/**\ingroup Utils + * - convert a delimitter seperated string to std::vector of type T + * \tparam vec - std::vector of type T. Specialized boost::lexical_cast is used + * \tparam str - input string + * \tparam delims - delimitter space is default + * \t param T& ret - std::vector of type T + */ + +template<typename T> +void +ConvertStringToVector(std::string const &str, T& ret, const char * delims=" ") +{ + std::vector<std::string> splitted; + + boost::split(splitted, str, boost::is_any_of(delims)); + +// split(str, delims, splitted); + + for(size_t i = 0; i < splitted.size(); i++) + { + typename T::value_type value; + try + { + value = boost::lexical_cast<typename T::value_type> (splitted[i]); + } + catch (boost::bad_lexical_cast &) + { + std::cerr << "Error getting value" << value << " at " << __FILE__ << ":" << __LINE__ << std::endl; + } + + ret.push_back(value); + } +} + +/* +SplitStringToSingleKeyValue - split a given std::string of into key value based +on given delimitter string. default delimitter is '='. If the string doesnot +have a delimitter the key is set to input string and value is set to defValue. + +This function is templated over value type. It uses specialized +boost::lexical_cast if the T is not of type std::string. only primitive types + +Arugments are: + str - reference to input string of type std::string + key - reference to std::string where key will be stored + value - reference to T where value will be stored + defValue - default value if there is no delimitter found. (informally TRUE) + delims - const std::string which contains the delimtter used. Default is '=' + doTrim - option to perform boost::trim() over key and values. Default is true. +*/ +template<typename T> +void SplitStringToSingleKeyValue(const std::string& str, + std::string& key, T& value, const T& defValue, + const std::string delims="=", bool doTrim=true) +{ + std::size_t pos = str.find(delims); + if (pos == std::string::npos) + { + key = str; + value = defValue; + } + key = str.substr(0, pos); + + std::string value_ = str.substr(pos+delims.size(), str.size() - 1 ); + + //do optional trim + if(doTrim) + { + boost::trim_left(key); + boost::trim_right(value_); + } + + if(typeid(value) != typeid(key)) + { + try + { + value = boost::lexical_cast<T>(value_); + } + catch (boost::bad_lexical_cast &) + { + std::cerr << "Error getting value" << value_ << " at " << __FILE__ << ":" << __LINE__ << std::endl; + } + } + else + { + value.swap(value_); + } +} +} // end namespace Utils +} // end namespace otb + +#endif //otbStringUtils_h diff --git a/Modules/Applications/AppImageUtils/app/CMakeLists.txt b/Modules/Applications/AppImageUtils/app/CMakeLists.txt index 82ef77a5887523595bdf30570c5bdebe3b3c5cdc..637eb926408db14daecc6cfd79401ada43a884a3 100644 --- a/Modules/Applications/AppImageUtils/app/CMakeLists.txt +++ b/Modules/Applications/AppImageUtils/app/CMakeLists.txt @@ -89,6 +89,6 @@ otb_create_application( LINK_LIBRARIES ${${otb-module}_LIBRARIES}) otb_create_application( - NAME NoDataMask - SOURCES otbNoDataMask.cxx + NAME ManageNoData + SOURCES otbManageNoData.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES}) diff --git a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2449029c861368d5d34121d875608b009e79a530 --- /dev/null +++ b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx @@ -0,0 +1,145 @@ +/*========================================================================= + + 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 "otbImageToNoDataMaskFilter.h" +#include "otbChangeNoDataValueFilter.h" + +namespace otb +{ +namespace Wrapper +{ + +class ManageNoData : public Application +{ +public: + /** Standard class typedefs. */ + typedef ManageNoData Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Standard macro */ + itkNewMacro(Self); + + itkTypeMacro(ManageNoData, otb::Application); + + /** Filters typedef */ + typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType,UInt8ImageType> FilterType; + typedef otb::ChangeNoDataValueFilter<FloatVectorImageType,FloatVectorImageType> ChangeNoDataFilterType; + +private: + void DoInit() + { + SetName("ManageNoData"); + SetDescription("Manage No-Data"); + // Documentation + SetDocName("No Data management"); + SetDocLongDescription("This application has two modes. The first allows to build a mask of no-data pixels from the no-data flags read from the image file. The second allows to update the change the no-data value of an image (pixels value and metadata). This last mode also allows to replace NaN in images with a proper no-data value. To do so, one should activate the NaN is no-data option."); + SetDocLimitations("None"); + SetDocAuthors("OTB-Team"); + SetDocSeeAlso("BanMath"); + AddDocTag("Conversion"); + AddDocTag("Image Dynamic"); + AddDocTag(Tags::Manip); + + AddParameter(ParameterType_InputImage, "in", "Input image"); + SetParameterDescription("in", "Input image"); + + AddParameter(ParameterType_OutputImage, "out", "Output Image"); + SetParameterDescription("out", "Output image"); + + AddParameter(ParameterType_Empty,"usenan", "Consider NaN as no-data"); + SetParameterDescription("usenan","If active, the application will consider NaN as no-data values as well"); + MandatoryOff("usenan"); + DisableParameter("usenan"); + + AddParameter(ParameterType_Choice,"mode","No-data handling mode"); + SetParameterDescription("mode","Allows to choose between different no-data handling options"); + + AddChoice("mode.buildmask","Build a no-data Mask"); + + AddParameter(ParameterType_Float,"mode.buildmask.inv","Inside Value"); + SetParameterDescription("mode.buildmask.inv","Value given in the output mask to pixels that are not no data pixels"); + SetDefaultParameterInt("mode.buildmask.inv",1); + + AddParameter(ParameterType_Float,"mode.buildmask.outv","Outside Value"); + SetParameterDescription("mode.buildmask.outv","Value given in the output mask to pixels that are no data pixels"); + SetDefaultParameterInt("mode.buildmask.outv",0); + + AddChoice("mode.changevalue","Change the no-data value"); + + AddParameter(ParameterType_Float,"mode.changevalue.newv","The new no-data value"); + SetParameterDescription("mode.changevalue.newv","The new no-data value"); + SetDefaultParameterInt("mode.changevalue.newv",0); + + SetParameterString("mode","buildmask"); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif"); + SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8"); + SetDocExampleParameterValue("mode.buildmask.inv", "255"); + SetDocExampleParameterValue("mode.buildmask.outv", "0"); + } + + void DoUpdateParameters() + { + // Nothing to do here for the parameters : all are independent + } + + + void DoExecute() + { + FloatVectorImageType::Pointer inputPtr = this->GetParameterImage("in"); + + m_Filter = FilterType::New(); + m_Filter->SetInsideValue(this->GetParameterFloat("mode.buildmask.inv")); + m_Filter->SetOutsideValue(this->GetParameterFloat("mode.buildmask.outv")); + m_Filter->SetNaNIsNoData(IsParameterEnabled("usenan")); + m_Filter->SetInput(inputPtr); + + m_ChangeNoDataFilter = ChangeNoDataFilterType::New(); + m_ChangeNoDataFilter->SetInput(inputPtr); + m_ChangeNoDataFilter->SetNaNIsNoData(IsParameterEnabled("usenan")); + + std::vector<double> newNoData(inputPtr->GetNumberOfComponentsPerPixel(),GetParameterFloat("mode.changevalue.newv")); + + m_ChangeNoDataFilter->SetNewNoDataValues(newNoData); + + if(GetParameterString("mode") == "buildmask") + { + SetParameterOutputImage("out",m_Filter->GetOutput()); + } + else if(GetParameterString("mode") == "changevalue") + { + SetParameterOutputImage("out",m_ChangeNoDataFilter->GetOutput()); + } + } + + FilterType::Pointer m_Filter; + ChangeNoDataFilterType::Pointer m_ChangeNoDataFilter; +}; + +} +} + +OTB_APPLICATION_EXPORT(otb::Wrapper::ManageNoData) + diff --git a/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx b/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx deleted file mode 100644 index dd99a9a7949132a1bf64ab95684408b39cee873a..0000000000000000000000000000000000000000 --- a/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx +++ /dev/null @@ -1,107 +0,0 @@ -/*========================================================================= - - 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 "otbImageToNoDataMaskFilter.h" - -namespace otb -{ -namespace Wrapper -{ - - -class NoDataMask : public Application -{ -public: - /** Standard class typedefs. */ - typedef NoDataMask Self; - typedef Application Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - /** Standard macro */ - itkNewMacro(Self); - - itkTypeMacro(NoDataMask, otb::Application); - - /** Filters typedef */ - typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType,UInt8ImageType> FilterType; - -private: - void DoInit() - { - SetName("NoDataMask"); - SetDescription("NoDataMask"); - // Documentation - SetDocName("No Data Mask management"); - SetDocLongDescription("This application builds a nodata mask from the no data flags found in metadata or from NaN pixels."); - SetDocLimitations("None"); - SetDocAuthors("OTB-Team"); - SetDocSeeAlso("BanMath"); - AddDocTag("Conversion"); - AddDocTag("Image Dynamic"); - AddDocTag(Tags::Manip); - - AddParameter(ParameterType_InputImage, "in", "Input image"); - SetParameterDescription("in", "Input image"); - - AddParameter(ParameterType_OutputImage, "out", "Output Image"); - SetParameterDescription("out", "Output image"); - - AddParameter(ParameterType_Int,"inv","Inside Value"); - SetParameterDescription("inv","Value given in the output mask to pixels that are not no data pixels"); - SetDefaultParameterInt("inv",1); - - AddParameter(ParameterType_Int,"outv","Outside Value"); - SetParameterDescription("outv","Value given in the output mask to pixels that are no data pixels"); - SetDefaultParameterInt("outv",0); - - AddRAMParameter(); - - // Doc example parameter settings - SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif"); - SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8"); - SetDocExampleParameterValue("inv", "255"); - SetDocExampleParameterValue("outv", "0"); - } - - void DoUpdateParameters() - { - // Nothing to do here for the parameters : all are independent - } - - - void DoExecute() - { - m_Filter = FilterType::New(); - m_Filter->SetInsideValue(this->GetParameterInt("inv")); - m_Filter->SetOutsideValue(this->GetParameterInt("outv")); - m_Filter->SetInput(this->GetParameterImage("in")); - - SetParameterOutputImage("out",m_Filter->GetOutput()); - } - - FilterType::Pointer m_Filter; -}; - -} -} - -OTB_APPLICATION_EXPORT(otb::Wrapper::NoDataMask) - diff --git a/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx b/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx index 154c73b8c4805ade35f63410d841b2999b2fe751..9595466d47d0a1bb66768e6d241a8c26f8341f88 100644 --- a/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx +++ b/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx @@ -107,10 +107,14 @@ ImageRegionAdaptativeSplitter<VImageDimension> // Now we can handle the case where we have a tile hint and a // non-trivial requested number of splits SizeType tilesPerDim, splitsPerDim; - - tilesPerDim[0] = (m_ImageRegion.GetSize()[0] + m_TileHint[0] -1) / m_TileHint[0]; - tilesPerDim[1] = (m_ImageRegion.GetSize()[1] + m_TileHint[1] -1) / m_TileHint[1]; - + IndexType firstTileCovered; + + // First, we need to get which tiles are covered by ROI + firstTileCovered[0] = m_ImageRegion.GetIndex()[0] / m_TileHint[0]; + firstTileCovered[1] = m_ImageRegion.GetIndex()[1] / m_TileHint[1]; + tilesPerDim[0] = (m_ImageRegion.GetIndex()[0] + m_ImageRegion.GetSize()[0] -1 + m_TileHint[0] -1) / m_TileHint[0] - firstTileCovered[0]; + tilesPerDim[1] = (m_ImageRegion.GetIndex()[1] + m_ImageRegion.GetSize()[1] -1 + m_TileHint[1] -1) / m_TileHint[1] - firstTileCovered[1]; + unsigned int totalTiles = tilesPerDim[0] * tilesPerDim[1]; // In this case, we have to group input tiles @@ -134,13 +138,14 @@ ImageRegionAdaptativeSplitter<VImageDimension> i = (i+1)%2; } + splitsPerDim[0] = tilesPerDim[0] / groupTiles[0]; + splitsPerDim[1] = tilesPerDim[1] / groupTiles[1]; // Handle the last small tile if any if(tilesPerDim[0] % groupTiles[0] > 0) splitsPerDim[0]++; - splitsPerDim[1] = tilesPerDim[1] / groupTiles[1]; if(tilesPerDim[1] % groupTiles[1] > 0) splitsPerDim[1]++; @@ -157,8 +162,8 @@ ImageRegionAdaptativeSplitter<VImageDimension> newSplitSize[0] = groupTiles[0] * m_TileHint[0]; newSplitSize[1] = groupTiles[1] * m_TileHint[1]; - newSplitIndex[0] = splitx * newSplitSize[0]; - newSplitIndex[1] = splity * newSplitSize[1]; + newSplitIndex[0] = firstTileCovered[0] * m_TileHint[0] + splitx * newSplitSize[0]; + newSplitIndex[1] = firstTileCovered[1] * m_TileHint[1] + splity * newSplitSize[1]; newSplit.SetIndex(newSplitIndex); newSplit.SetSize(newSplitSize); @@ -208,8 +213,8 @@ ImageRegionAdaptativeSplitter<VImageDimension> RegionType newSplit; IndexType newSplitIndex; - newSplitIndex[0] = tilex * m_TileHint[0] + divx * splitSize[0]; - newSplitIndex[1] = tiley * m_TileHint[1] + divy * splitSize[1]; + newSplitIndex[0] = (tilex + firstTileCovered[0]) * m_TileHint[0] + divx * splitSize[0]; + newSplitIndex[1] = (tiley + firstTileCovered[1]) * m_TileHint[1] + divy * splitSize[1]; newSplit.SetIndex(newSplitIndex); newSplit.SetSize(splitSize); diff --git a/Modules/Core/Common/test/CMakeLists.txt b/Modules/Core/Common/test/CMakeLists.txt index e32118293bc838491f5be7754ed53d22c35699b3..40f89e72aeb1144f9fc5c7166c32aaef6d62870b 100644 --- a/Modules/Core/Common/test/CMakeLists.txt +++ b/Modules/Core/Common/test/CMakeLists.txt @@ -78,6 +78,24 @@ otb_add_test(NAME coTvImageRegionAdaptativeSplitterStripLargeStream COMMAND otbC ${TEMP}/coTvImageRegionAdaptativeSplitterStripLargeStreamOutput.txt ) +otb_add_test(NAME coTvImageRegionAdaptativeSplitterShiftedROILargeStream COMMAND otbCommonTestDriver + --compare-ascii ${NOTOL} + ${BASELINE_FILES}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt + ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt + otbImageRegionAdaptativeSplitter + 1000 1000 4000 4000 2000 2000 5 + ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt + ) + +otb_add_test(NAME coTvImageRegionAdaptativeSplitterShiftedROISmallStream COMMAND otbCommonTestDriver + --compare-ascii ${NOTOL} + ${BASELINE_FILES}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt + ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt + otbImageRegionAdaptativeSplitter + 1000 1000 4000 4000 2000 2000 10 + ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt + ) + otb_add_test(NAME coTuRGBAPixelConverter COMMAND otbCommonTestDriver otbRGBAPixelConverterNew ) diff --git a/Modules/Core/ImageBase/include/otbNoDataHelper.h b/Modules/Core/ImageBase/include/otbNoDataHelper.h deleted file mode 100644 index 16bfdc4cd85f916804b59d8c7ee05828d47e1897..0000000000000000000000000000000000000000 --- a/Modules/Core/ImageBase/include/otbNoDataHelper.h +++ /dev/null @@ -1,75 +0,0 @@ -/*========================================================================= - - 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 __otbNoDataHelper_h -#define __otbNoDataHelper_h -#include <vector> -#include <cassert> -#include "vnl/vnl_math.h" -#include <itkVariableLengthVector.h> - -namespace otb -{ -/** -* Test if the pixel corresponds to a no data pixel according to a -* vector of no data flags, and a vector of no data values. -* \param pixel The pixel to test -* \param flags A vector of size > 1 containing a flag per band to -* indicate if a no data value is available for this band -* \param values A vector of size > 1 corresponding to the no data -* value for each band. If flag is 0, the value will be ignored. -*/ -template<typename T> bool IsNoData(const T & pixel, const -std::vector<bool> & flags, const std::vector<double> & values) { - assert(flags.size()>0); - assert(values.size()>0); - - if(vnl_math_isnan((int)flags[0])) - return true; - - - if(flags[0]) - { - return (pixel == values[0]); - } - else - { - return false; - } -} -/** - * Specialization of IsNoData function to handle itk::VariableLengthVector - */ -template <typename T> bool IsNoData(const itk::VariableLengthVector<T> & pixel, const std::vector<bool> & flags, const std::vector<double> & values) -{ - assert(flags.size()>=pixel.Size()); - assert(values.size()>=pixel.Size()); - - for(unsigned int i = 0; i < pixel.Size();++i) - { - if(vnl_math_isnan(pixel[i]) || (flags[i] && (pixel[i] == values[i]))) - { - return true; - } - } - return false; -} - - -} // End namespace otb - -#endif diff --git a/Modules/Core/ImageBase/test/CMakeLists.txt b/Modules/Core/ImageBase/test/CMakeLists.txt index dd4ecc9d09b0a5477f4d0e66786ffeda21dab34c..46ff70cf251e17e8a4bd2be04073930a7dec7978 100644 --- a/Modules/Core/ImageBase/test/CMakeLists.txt +++ b/Modules/Core/ImageBase/test/CMakeLists.txt @@ -28,7 +28,7 @@ set(OTBImageBaseTests otbImageFunctionAdaptor.cxx otbMultiChannelExtractROINew.cxx otbMetaImageFunction.cxx - otbNoDataHelperTest.cxx + ) add_executable(otbImageBaseTestDriver ${OTBImageBaseTests}) @@ -825,6 +825,3 @@ otb_add_test(NAME ioTvOtbVectorImageTestRadarsat COMMAND otbImageBaseTestDriver otbVectorImageLegacyTest LARGEINPUT{/RADARSAT1/GOMA/SCENE01/} ${TEMP}/ioOtbVectorImageTestRadarsat.txt) - -otb_add_test(NAME coreImageBaseNoDataHelperTest COMMAND otbImageBaseTestDriver - otbNoDataHelperTest) diff --git a/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx b/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx index dcf63d236ebad2c066389989da824836833ab7d9..fc275609cb19c75305902543f926fc37e3cb3f83 100644 --- a/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx +++ b/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx @@ -31,5 +31,4 @@ void RegisterTests() REGISTER_TEST(otbMultiChannelExtractROINew); REGISTER_TEST(otbMetaImageFunction); REGISTER_TEST(otbMetaImageFunctionNew); - REGISTER_TEST(otbNoDataHelperTest); } diff --git a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h index d9209574b68c59c32b82e7c7894e3855e988a28c..8340cedac73674309f124cc4c8b24499dc3c34b3 100644 --- a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h +++ b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h @@ -107,6 +107,12 @@ public: double GetGCPZ(unsigned int GCPnum) const; // otbMetadataGetGCPnumMacro(GCPZ, double, GCPnum, unsigned int); + /** + * Get The no data flags if existing + * return False otherwise + */ + bool GetNoDataFlags(std::vector<bool> & flags, std::vector<double> & values) const; + /** Get the six coefficients of affine geoTtransform. */ VectorType GetGeoTransform() const; diff --git a/Modules/Core/Metadata/include/otbNoDataHelper.h b/Modules/Core/Metadata/include/otbNoDataHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..57d927c78fb7bf737e11e3d6663b3f60cd52d828 --- /dev/null +++ b/Modules/Core/Metadata/include/otbNoDataHelper.h @@ -0,0 +1,165 @@ +/*========================================================================= + + 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 __otbNoDataHelper_h +#define __otbNoDataHelper_h +#include <vector> +#include <cassert> +#include "vnl/vnl_math.h" +#include <itkVariableLengthVector.h> + +namespace itk +{ +class MetaDataDictionary; +} + +namespace otb +{ + +/** + * Reads no data flag from the MetaDataDictionnary dict to flags and values + * vectors. Returns true upon success. + */ +bool ReadNoDataFlags(const itk::MetaDataDictionary& dict, std::vector<bool> & flags, std::vector<double> & values); + +/** + * Write no data flags to the MetaDataDictionnary dict from flags and values + * vectors. Returns true upon success. + */ +void WriteNoDataFlags(const std::vector<bool> & flags, const std::vector<double> & values, itk::MetaDataDictionary& dict); + +/** +* Test if the pixel corresponds to a no data pixel according to a +* vector of no data flags, and a vector of no data values. +* \param pixel The pixel to test +* \param flags A vector of size > 1 containing a flag per band to +* indicate if a no data value is available for this band +* \param values A vector of size > 1 corresponding to the no data +* value for each band. If flag is 0, the value will be ignored. +* \param nanIsNoData If true, NaN values will be reported as no-data. +*/ +template<typename T> bool IsNoData(const T & pixel, const + std::vector<bool> & flags, const std::vector<double> & values, bool nanIsNoData = false) { + assert(flags.size()>0); + assert(values.size()>0); + + if(nanIsNoData && vnl_math_isnan(values[0])) + return true; + + + if(flags[0]) + { + return (pixel == values[0]); + } + else + { + return false; + } +} + +/** +* Reads a pixel and change the no data value if it is found. No data +* value is changed either if the pixel value is NaN or if the pixel +* value equals the no data value and flag is true. +* +* \param pixel The pixel to process \param flags A vector of size > 1 +* containing a flag per band to indicate if a no data value is +* available for this band +* \param values A vector of size > 1 corresponding to the current no data +* value for each band. If flag is 0, the value will be ignored. +* \param newValues A vector of size > 1 corresponding to the new no data +* value for each band. If flag is 0, the value will be ignored +* \param nanIsNoData If true, NaN values will be considered as no-data +* and changed as well. +* +*/ +template<typename T> T ChangeNoData(const T & pixel, const + std::vector<bool> & flags, + const std::vector<double> & values, + const std::vector<double> & newValues, + bool nanIsNoData = false) { + assert(flags.size()>0); + assert(values.size()>0); + assert(newValues.size()>0); + + if(nanIsNoData && vnl_math_isnan(pixel)) + { + return static_cast<T>(newValues[0]); + } + + if(flags[0] && pixel == values[0]) + { + return static_cast<T>(newValues[0]); + } + return pixel; +} + + +/** + * Specialization of IsNoData function to handle itk::VariableLengthVector + */ +template <typename T> bool IsNoData(const itk::VariableLengthVector<T> & pixel, const std::vector<bool> & flags, const std::vector<double> & values, bool nanIsNoData = false) +{ + assert(flags.size()>=pixel.Size()); + assert(values.size()>=pixel.Size()); + + for(unsigned int i = 0; i < pixel.Size();++i) + { + if((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i]))) + { + return true; + } + } + return false; +} + + +/** + * Specialization of ChangeNoData function to handle itk::VariableLengthVector + */ +template <typename T> itk::VariableLengthVector<T> ChangeNoData(const itk::VariableLengthVector<T> & pixel, + const std::vector<bool> & flags, + const std::vector<double> & values, + const std::vector<double> & newValues, + bool nanIsNoData = false) +{ + assert(flags.size()>=pixel.Size()); + assert(values.size()>=pixel.Size()); + assert(newValues.size()>=pixel.Size()); + + itk::VariableLengthVector<T> outPixel(pixel.Size()); + + for(unsigned int i = 0; i < pixel.Size();++i) + { + if((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i]))) + { + outPixel[i] = newValues[i]; + } + else + { + outPixel[i] = pixel[i]; + } + } + + return outPixel; +} + + + +} // End namespace otb + +#endif diff --git a/Modules/Core/Metadata/otb-module.cmake b/Modules/Core/Metadata/otb-module.cmake index afaff0b86e39f5762ddb10689628e7ebf1be6e61..240e6a3ee1cec76586a97c0078a34861dfb410ee 100644 --- a/Modules/Core/Metadata/otb-module.cmake +++ b/Modules/Core/Metadata/otb-module.cmake @@ -9,12 +9,12 @@ otb_module(OTBMetadata OTBITK OTBOSSIMAdapters OTBCommon - + TEST_DEPENDS OTBTestKernel OTBImageIO OTBImageBase - + DESCRIPTION "${DOCUMENTATION}" ) diff --git a/Modules/Core/Metadata/src/CMakeLists.txt b/Modules/Core/Metadata/src/CMakeLists.txt index bc3c9900f779896fc9396b52c4e36f60c0d77b57..458188d5246599d101d8cfa68384704f8e7929ae 100644 --- a/Modules/Core/Metadata/src/CMakeLists.txt +++ b/Modules/Core/Metadata/src/CMakeLists.txt @@ -24,6 +24,7 @@ set(OTBMetadata_SRC otbSarImageMetadataInterface.cxx otbPleiadesImageMetadataInterfaceFactory.cxx otbTerraSarImageMetadataInterfaceFactory.cxx + otbNoDataHelper.cxx ) add_library(OTBMetadata ${OTBMetadata_SRC}) diff --git a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx index 784f5847bca5369f0077f9b6441443aae5a35550..013e4f9c77d4932f351b2c17acfd04f4e3d2944e 100644 --- a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx +++ b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx @@ -18,9 +18,11 @@ #include "otbImageMetadataInterfaceBase.h" +#include "otbNoDataHelper.h" #include "itkMetaDataObject.h" #include "itksys/SystemTools.hxx" + namespace otb { @@ -222,6 +224,12 @@ ImageMetadataInterfaceBase::GetGCPZ(unsigned int GCPnum) const else return (0); } +bool +ImageMetadataInterfaceBase::GetNoDataFlags(std::vector<bool> & flags, std::vector<double> & values) const +{ + return ReadNoDataFlags(this->GetMetaDataDictionary(),flags,values); +} + ImageMetadataInterfaceBase::VectorType ImageMetadataInterfaceBase::GetGeoTransform() const { diff --git a/Modules/Core/Metadata/src/otbNoDataHelper.cxx b/Modules/Core/Metadata/src/otbNoDataHelper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b5edf9dc49145ba6aae8e5089cc7a11335bf7037 --- /dev/null +++ b/Modules/Core/Metadata/src/otbNoDataHelper.cxx @@ -0,0 +1,43 @@ +/*========================================================================= + + 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 "otbNoDataHelper.h" + +#include "itkMetaDataDictionary.h" +#include "itkMetaDataObject.h" +#include "otbMetaDataKey.h" + +namespace otb +{ + +bool ReadNoDataFlags(const itk::MetaDataDictionary& dict, std::vector<bool> & flags, std::vector<double> & values) +{ + bool ret = itk::ExposeMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,flags); + + if (ret) + ret = itk::ExposeMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,values); + + return ret; +} + +void WriteNoDataFlags(const std::vector<bool> & flags, const std::vector<double> & values, itk::MetaDataDictionary& dict) +{ + itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,flags); + itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,values); +} + +} // End namespace otb diff --git a/Modules/Core/Metadata/test/CMakeLists.txt b/Modules/Core/Metadata/test/CMakeLists.txt index 340324421e76181795985d0e7fea068ddb2fab43..b48fbffaef79197293daba9fec698e7fe0581bfb 100644 --- a/Modules/Core/Metadata/test/CMakeLists.txt +++ b/Modules/Core/Metadata/test/CMakeLists.txt @@ -22,6 +22,7 @@ otbTerraSarImageMetadataInterfaceNew.cxx otbWorldView2ImageMetadataInterfaceNew.cxx otbDefaultImageMetadataInterface.cxx otbImageMetadataInterfaceTest2.cxx +otbNoDataHelperTest.cxx ) add_executable(otbMetadataTestDriver ${OTBMetadataTests}) @@ -351,3 +352,7 @@ foreach( current_file ${GenericTestSPOT6_DATA_INPUTS} ) ${TEMP}/ioTvOpticalImageMetadataInterface_${current_type}_OUT.txt ) endforeach() + + +otb_add_test(NAME coreMetaDataNoDataHelperTest COMMAND otbMetadataTestDriver + otbNoDataHelperTest) diff --git a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx index d2dfb191518574ccf1829046d59c2ebb5b2550c0..cd06f2f46e9f46fb412b1f30a278374070ac7405 100644 --- a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx +++ b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx @@ -21,4 +21,5 @@ void RegisterTests() REGISTER_TEST(otbWorldView2ImageMetadataInterfaceNew); REGISTER_TEST(otbDefaultImageMetadataInterface); REGISTER_TEST(otbImageMetadataInterfaceTest2); + REGISTER_TEST(otbNoDataHelperTest); } diff --git a/Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx b/Modules/Core/Metadata/test/otbNoDataHelperTest.cxx similarity index 91% rename from Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx rename to Modules/Core/Metadata/test/otbNoDataHelperTest.cxx index 5b32ec74768b446b80c18c3e2d4a643971e5246d..4db9ba0ab9f1bd23ff180ca3edf7577476895d13 100644 --- a/Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx +++ b/Modules/Core/Metadata/test/otbNoDataHelperTest.cxx @@ -17,6 +17,7 @@ =========================================================================*/ #include "otbNoDataHelper.h" +#include "itkMetaDataDictionary.h" #include "otbMacro.h" int otbNoDataHelperTest(int itkNotUsed(argc),char * itkNotUsed(argv) []) @@ -24,6 +25,11 @@ int otbNoDataHelperTest(int itkNotUsed(argc),char * itkNotUsed(argv) []) std::vector<bool> b1(1,true); std::vector<double> v1(1,0); + itk::MetaDataDictionary dict; + + otb::WriteNoDataFlags(b1,v1,dict); + otb::ReadNoDataFlags(dict,b1,v1); + otbControlConditionTestMacro(otb::IsNoData(10,b1,v1)," wrong output of IsNoData function"); otbControlConditionTestMacro(!otb::IsNoData(0,b1,v1)," wrong output of IsNoData function"); b1[0]=false; diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h b/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..59d4fca6e387e8dae4588678c76a479b91c5ed01 --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h @@ -0,0 +1,178 @@ +/*========================================================================= + + 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 __otbChangeNoDataValueFilter_h +#define __otbChangeNoDataValueFilter_h + +#include "itkUnaryFunctorImageFilter.h" +#include "itkMetaDataObject.h" +#include "otbMetaDataKey.h" +#include "otbNoDataHelper.h" + +namespace otb +{ +namespace Functor +{ +/** \class ChangeNoDataFunctor + * \brief Functor used by ChangeNoDataValueFilter + * + * See ChangeNoDataValueFilter for complete documentation. + * \ingroup OTBImageManipulation + */ +template <typename TInputPixel, typename TOutputPixel> +class ChangeNoDataFunctor +{ +public: + ChangeNoDataFunctor(): + m_Flags(), + m_Values(), + m_NewValues(), + m_NaNIsNoData(false) + {} + virtual ~ChangeNoDataFunctor(){} + + inline TOutputPixel operator()(const TInputPixel& in) const + { + return otb::ChangeNoData(in,m_Flags,m_Values,m_NewValues,m_NaNIsNoData); + } + + std::vector<bool> m_Flags; + std::vector<double> m_Values; + std::vector<double> m_NewValues; + bool m_NaNIsNoData; +}; + +} // End namespace Functor + +/** \class ChangeNoDataValueFilter + * \brief Change no-data flags and values and replace them in image + * + * This filter reads the no-data flags (a boolean vector indicating + * for each band if a no-data value exists) and values (the actual + * value to be used as no-data for each band) from + * MetaDataDictionary, and allows to change this value. + * + * The algorithm is the following: for each pixel, for each channel + * in the pixel, if there is a no-data value for this channel + * (according to no-data flags) and the current channel value equals + * to the no-data value set for this channel, then the value is + * changed for the new no-data value specified by the + * users. Otherwise, value remains untouched. + * + * If NaNIsNoData is true: + * - NaN values will be considered as no data and replaced as well + * - Output image will have no-data flags and values for all bands + * + * If NaNIsNoData is false: + * - Band for which input no-data flags is false will remain + * untouched + * - Output image will have no-data flags and values only for bands + * for which input no-data flag is true. + * + * \ingroup Streamed + * \ingroup MultiThreaded + * \ingroup OTBImageManipulation + */ +template <typename TInputImage, typename TOutputImage> +class ChangeNoDataValueFilter + : public itk::UnaryFunctorImageFilter<TInputImage, + TOutputImage, + Functor::ChangeNoDataFunctor<typename TInputImage::PixelType, + typename TOutputImage::PixelType> > +{ +public: + typedef Functor::ChangeNoDataFunctor<typename TInputImage::PixelType,typename TOutputImage::PixelType> FunctorType; + + typedef ChangeNoDataValueFilter Self; + typedef itk::UnaryFunctorImageFilter<TInputImage, + TOutputImage, + FunctorType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Type macro */ + itkNewMacro(Self); + + /** Creation through object factory macro */ + itkTypeMacro(ChangeNoDataValueFilter, itk::ImageToImageFilter); + + /** + * Set the new no-data values + * \param newValues The vector of new no-data values (size should be + * >= to number of bands) + */ + void SetNewNoDataValues(std::vector<double> & newValues) + { + this->GetFunctor().m_NewValues = newValues; + } + + /** + * Set the NaN is no data flags + * \param nanIsNoData If true, NaN values will be considered as + * no-data as well (default is false) + */ + void SetNaNIsNoData(bool nanIsNoData) + { + this->GetFunctor().m_NaNIsNoData = nanIsNoData; + } + +protected: + ChangeNoDataValueFilter() + {} + + virtual ~ChangeNoDataValueFilter() + {} + + virtual void GenerateOutputInformation() + { + Superclass::GenerateOutputInformation(); + + std::vector<bool> noDataValueAvailable; + std::vector<double> noDataValues; + + bool ret = ReadNoDataFlags(this->GetInput()->GetMetaDataDictionary(),noDataValueAvailable,noDataValues); + + if(!ret) + { + noDataValueAvailable.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),false); + noDataValues.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),0); + } + + this->GetFunctor().m_Flags = noDataValueAvailable; + this->GetFunctor().m_Values = noDataValues; + + std::vector<bool> flags = noDataValueAvailable; + + if(this->GetFunctor().m_NaNIsNoData) + { + flags = std::vector<bool>(flags.size(),true); + } + + WriteNoDataFlags(flags,this->GetFunctor().m_NewValues,this->GetOutput()->GetMetaDataDictionary()); + } + +private: + ChangeNoDataValueFilter(const Self&); // purposely not implemented + void operator =(const Self&); // purposely not implemented + +}; + +} // End namespace otb + + + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h b/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h index 02e09dd22ec43533330cf59a4a41345d5aaa7570..a790b37a0ea031c3695ac7fcb8058d313f51e0ea 100644 --- a/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h +++ b/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h @@ -27,6 +27,12 @@ namespace otb { namespace Functor { +/** \class NoDataFunctor + * \brief Functor used by ImageToNoDataMaskFilter + * + * See ImageToNoDataMaskFilter for complete documentation. + * \ingroup OTBImageManipulation + */ template <typename TInputPixel, typename TOutputPixel> class NoDataFunctor { @@ -35,25 +41,42 @@ public: m_Flags(), m_Values(), m_OutsideValue(0), - m_InsideValue(1) + m_InsideValue(1), + m_NaNIsNoData(false) {} virtual ~NoDataFunctor(){} inline TOutputPixel operator()(const TInputPixel& in) const { - return otb::IsNoData(in,m_Flags,m_Values)?m_OutsideValue:m_InsideValue; + return otb::IsNoData(in,m_Flags,m_Values,m_NaNIsNoData)?m_OutsideValue:m_InsideValue; } std::vector<bool> m_Flags; std::vector<double> m_Values; TOutputPixel m_OutsideValue; TOutputPixel m_InsideValue; + bool m_NaNIsNoData; }; } // End namespace Functor - +/** \class ImageToNoDataMaskFilter + * \brief Builds a no-data mask image from no-data flags and values + * + * This filter reads the no-data flags (a boolean vector indicating + * for each band if a no-data value exists) and values (the actual + * value to be used as no-data for each band) from + * MetaDataDictionary, and builds a binary mask indicating presence + * or absence of no-data for each pixel. + * + * If NaNIsNoData is true, NaN pixels will also be considered as + * no-data pixels. + * + * \ingroup Streamed + * \ingroup MultiThreaded + * \ingroup OTBImageManipulation + */ template <typename TInputImage, typename TOutputImage> class ImageToNoDataMaskFilter : public itk::UnaryFunctorImageFilter<TInputImage, @@ -77,15 +100,31 @@ public: /** Creation through object factory macro */ itkTypeMacro(SpectralAngleDistanceImageFilter, itk::ImageToImageFilter); + /** + * Set inside value of output mask. This value will be used to + * indicate absence of no-data for the pixel in the output mask + */ void SetInsideValue(const typename TOutputImage::PixelType & value) { this->GetFunctor().m_InsideValue = value; } - + /** + * Set outside value of output mask. This value will be used to + * indicate presence of no-data for the pixel in the output mask + */ void SetOutsideValue(const typename TOutputImage::PixelType & value) { this->GetFunctor().m_OutsideValue = value; } + /** + * Set the NaN is no data flags + * \param nanIsNoData If true, NaN values will be considered as + * no-data as well (default is false) + */ + void SetNaNIsNoData(bool nanIsNoData) + { + this->GetFunctor().m_NaNIsNoData=nanIsNoData; + } protected: ImageToNoDataMaskFilter() @@ -97,23 +136,11 @@ protected: virtual void BeforeThreadedGenerateData() { std::vector<bool> noDataValueAvailable; - bool ret = itk::ExposeMetaData<std::vector<bool> >(this->GetInput()->GetMetaDataDictionary(),MetaDataKey::NoDataValueAvailable,noDataValueAvailable); - - if(!ret) - { - noDataValueAvailable.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),false); - } - - this->GetFunctor().m_Flags = noDataValueAvailable; - std::vector<double> noDataValues; - ret = itk::ExposeMetaData<std::vector<double> >(this->GetInput()->GetMetaDataDictionary(),MetaDataKey::NoDataValue,noDataValues); - - if(!ret) - { - noDataValues.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),0); - } + ReadNoDataFlags(this->GetInput()->GetMetaDataDictionary(),noDataValueAvailable,noDataValues); + + this->GetFunctor().m_Flags = noDataValueAvailable; this->GetFunctor().m_Values = noDataValues; } diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h new file mode 100644 index 0000000000000000000000000000000000000000..18f1465b0941b453bd5c9330dda92e2873f69d4f --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h @@ -0,0 +1,92 @@ +/*========================================================================= + + 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 __otbNRIBandImagesToOneNComplexBandsImage_h +#define __otbNRIBandImagesToOneNComplexBandsImage_h + +#include "itkImageToImageFilter.h" +#include "itkImage.h" +#include "itkNumericTraits.h" + +/* + * Inputs : N images made of two real bands + * Output : one single image made of N complex bands + * + * */ + + +namespace otb +{ + + +template <class TInputImage, class TOutputImage> +class ITK_EXPORT NRIBandImagesToOneNComplexBandsImage : public itk::ImageToImageFilter<TInputImage, TOutputImage> +{ +public: + /** Extract input and output image dimension */ + itkStaticConstMacro(InputImageDimension, + unsigned int, + TInputImage::ImageDimension); + itkStaticConstMacro(OutputImageDimension, + unsigned int, + TOutputImage::ImageDimension); + + typedef TInputImage InputImageType; + typedef TOutputImage OutputImageType; + + /** standard class typedefs */ + typedef NRIBandImagesToOneNComplexBandsImage Self; + typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Object factory management */ + itkNewMacro(Self); + + /** typemacro */ + itkTypeMacro(NRIBandImagesToOneNComplexBandsImage, ImageToImageFilter); + + typedef typename InputImageType::PixelType InputPixelType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + + +protected: + NRIBandImagesToOneNComplexBandsImage(); + virtual ~NRIBandImagesToOneNComplexBandsImage() {} + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + void GenerateOutputInformation(void); + void BeforeThreadedGenerateData(void); + void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId); + +private: + NRIBandImagesToOneNComplexBandsImage(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbNRIBandImagesToOneNComplexBandsImage.txx" +#endif + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx new file mode 100644 index 0000000000000000000000000000000000000000..46abbf79efee49136fe17fc0be5d36e9e6ae13cf --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx @@ -0,0 +1,139 @@ +/*========================================================================= + + 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 __otbNRIBandImagesToOneNComplexBandsImage_txx +#define __otbNRIBandImagesToOneNComplexBandsImage_txx + +#include "otbNRIBandImagesToOneNComplexBandsImage.h" + +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" +#include "itkProgressReporter.h" +#include "itkVariableLengthVector.h" + + + + +namespace otb +{ + +/** + * + */ +template <class TInputImage, class TOutputImage> +NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::NRIBandImagesToOneNComplexBandsImage() +{ + //this->SetNumberOfThreads(1); +} + +/** + * GenerateOutputInformation + */ +template<class TInputImage, class TOutputImage> +void +NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage> +::GenerateOutputInformation(void) +{ + Superclass::GenerateOutputInformation(); + + unsigned int nbInputs = this->GetNumberOfInputs(); + this->GetOutput()->SetNumberOfComponentsPerPixel(nbInputs); + +} + +/** + * BeforeThreadedGenerateData + */ +template <class TInputImage, class TOutputImage> +void +NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage> +::BeforeThreadedGenerateData(void) +{ + unsigned int nbInputs = this->GetNumberOfInputs(); + + for (unsigned int i=0; i<nbInputs; i++) + if (this->GetInput(i)->GetNumberOfComponentsPerPixel() != 2 ) + itkExceptionMacro("Input images must be made of two bands and only two (see input #" << i << ")."); + +} + +/** + * ThreadedGenerateData + */ +template<class TInputImage, class TOutputImage> +void NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData( + const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId + ) +{ + + // support progress methods/callbacks + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + unsigned int nbInputs = this->GetNumberOfInputs(); + + itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbInputs); + + std::vector< typename itk::ImageRegionConstIterator<TInputImage> > vInIt; + for (unsigned int i=0; i<nbInputs; i++) + vInIt.push_back( itk::ImageRegionConstIterator<TInputImage>(this->GetInput(i), outputRegionForThread) ); + + + itk::ImageRegionIterator<OutputImageType> outIt; + outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread); + + for (unsigned int i=0; i<nbInputs; i++) + vInIt[i].GoToBegin(); + outIt.GoToBegin(); + + while (!outIt.IsAtEnd()) + { + + + for (unsigned int i=0; i<nbInputs; i++) + { + vlv[i] = std::complex< typename InputPixelType::ValueType >(vInIt[i].Get()[0],vInIt[i].Get()[1]); + //std::cout << "i = " << i << " " << vInIt[i].Get()[0] << " " << vInIt[i].Get()[1] << std::endl; + } + + + outIt.Set(vlv); + + //std::cout << "outIt.Get() = " << outIt.Get() << std::endl; + + for (unsigned int i=0; i<nbInputs; i++) + ++vInIt[i]; + ++outIt; + + progress.CompletedPixel(); + } + +} + +/** + * Standard "PrintSelf" method + */ +template <class TInputImage, class TOutput> +void +NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace otb + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h new file mode 100644 index 0000000000000000000000000000000000000000..745199721496ff2f6b9797cfa5e031ab3ec4ebde --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h @@ -0,0 +1,91 @@ +/*========================================================================= + + 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 __otbOneRIBandImageToOneComplexBandImage_h +#define __otbOneRIBandImageToOneComplexBandImage_h + +#include "itkImageToImageFilter.h" +#include "itkImage.h" +#include "itkNumericTraits.h" + + +/* + * Inputs : one image made of two real bands + * Output : one image made of one complex band + * + * */ + +namespace otb +{ + + +template <class TInputImage, class TOutputImage> +class ITK_EXPORT OneRIBandImageToOneComplexBandImage : public itk::ImageToImageFilter<TInputImage, TOutputImage> +{ +public: + /** Extract input and output image dimension */ + itkStaticConstMacro(InputImageDimension, + unsigned int, + TInputImage::ImageDimension); + itkStaticConstMacro(OutputImageDimension, + unsigned int, + TOutputImage::ImageDimension); + + typedef TInputImage InputImageType; + typedef TOutputImage OutputImageType; + + /** standard class typedefs */ + typedef OneRIBandImageToOneComplexBandImage Self; + typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Object factory management */ + itkNewMacro(Self); + + /** typemacro */ + itkTypeMacro(OneRIBandImageToOneComplexBandImage, ImageToImageFilter); + + typedef typename InputImageType::PixelType InputPixelType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + + +protected: + OneRIBandImageToOneComplexBandImage(); + virtual ~OneRIBandImageToOneComplexBandImage() {} + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + void BeforeThreadedGenerateData(void); + void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId); + +private: + OneRIBandImageToOneComplexBandImage(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbOneRIBandImageToOneComplexBandImage.txx" +#endif + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx new file mode 100644 index 0000000000000000000000000000000000000000..8a7003a8eec8066ed212245a9ff0162310f38499 --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx @@ -0,0 +1,100 @@ +/*========================================================================= + + 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 __otbOneRIBandImageToOneComplexBandImage_txx +#define __otbOneRIBandImageToOneComplexBandImage_txx + +#include "otbOneRIBandImageToOneComplexBandImage.h" + +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" +#include "itkProgressReporter.h" + +namespace otb +{ + +/** + * + */ +template <class TInputImage, class TOutputImage> +OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::OneRIBandImageToOneComplexBandImage() +{ + //this->SetNumberOfThreads(1); +} + +/** + * BeforeThreadedGenerateData + */ +template <class TInputImage, class TOutputImage> +void +OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage> +::BeforeThreadedGenerateData(void) +{ + if (this->GetInput()->GetNumberOfComponentsPerPixel() != 2 ) + itkExceptionMacro("Input image must be made of two bands and only two."); + +} + +/** + * ThreadedGenerateData + */ +template<class TInputImage, class TOutputImage> +void OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::ThreadedGenerateData( + const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId + ) +{ + + // support progress methods/callbacks + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + typename OutputImageType::Pointer output = this->GetOutput(); + typename InputImageType::ConstPointer input = this->GetInput(); + + itk::ImageRegionIterator<OutputImageType> it; + itk::ImageRegionConstIterator<TInputImage> itIn; + + itIn = itk::ImageRegionConstIterator<TInputImage>(input, outputRegionForThread); + it = itk::ImageRegionIterator<OutputImageType>(output, outputRegionForThread); + + it.GoToBegin(); + itIn.GoToBegin(); + while (!it.IsAtEnd()) + { + + it.Set(static_cast<OutputPixelType>( std::complex< typename InputPixelType::ValueType >(itIn.Get()[0],itIn.Get()[1]) )); + + ++it; + ++itIn; + progress.CompletedPixel(); + } + +} + +/** + * Standard "PrintSelf" method + */ +template <class TInputImage, class TOutput> +void +OneRIBandImageToOneComplexBandImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace otb + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h index 841117429ac4d12b5f4a3a83dae272d5164816ba..71230c936c8dc49e53e2903af502c169a1830078 100644 --- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h +++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h @@ -171,6 +171,9 @@ public: m_DisplacementFilter->SetNumberOfThreads(nbThread); } + /** Override itk::ProcessObject method to let the internal filter do the propagation */ + virtual void PropagateRequestedRegion(itk::DataObject *output); + protected: StreamingResampleImageFilter(); @@ -181,8 +184,6 @@ protected: virtual void GenerateOutputInformation(); - virtual void GenerateInputRequestedRegion(); - void PrintSelf(std::ostream& os, itk::Indent indent) const; private: diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx index 03ad4382b8651617bc2104bf0b3c89d22010afa4..8543b9e8881d3f3fe80db35cff33602cbc7eae74 100644 --- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx +++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx @@ -50,7 +50,7 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy progress->RegisterInternalFilter(m_WarpFilter, 1.f); m_WarpFilter->GraftOutput(this->GetOutput()); - m_WarpFilter->Update(); + m_WarpFilter->UpdateOutputData(m_WarpFilter->GetOutput()); this->GraftOutput(m_WarpFilter->GetOutput()); } @@ -62,41 +62,14 @@ void StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType> ::GenerateOutputInformation() { - // call the superclass's implementation of this method - Superclass::GenerateOutputInformation(); - - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - outputPtr->SetSpacing( this->GetOutputSpacing() ); - outputPtr->SetOrigin( this->GetOutputOrigin() ); - - typename OutputImageType::RegionType region; - region.SetSize( this->GetOutputSize() ); - region.SetIndex(this->GetOutputStartIndex() ); - - outputPtr->SetLargestPossibleRegion(region); - // check the output spacing of the displacement field if(this->GetDisplacementFieldSpacing()== itk::NumericTraits<SpacingType>::ZeroValue()) { this->SetDisplacementFieldSpacing(2.*this->GetOutputSpacing()); } -} - -template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> -void -StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType> -::GenerateInputRequestedRegion() -{ - // Retrieve output pointer - OutputImageType * outputPtr = this->GetOutput(); - // Retrieve input pointer - const InputImageType * inputPtr = this->GetInput(); - - // Retrieve output requested region - RegionType requestedRegion = outputPtr->GetRequestedRegion(); - SizeType largestSize = outputPtr->GetLargestPossibleRegion().GetSize(); + // Retrieve output largest region + SizeType largestSize = this->GetOutputSize(); // Set up displacement field filter SizeType displacementFieldLargestSize; @@ -117,10 +90,20 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy m_DisplacementFilter->SetOutputSize(displacementFieldLargestSize); m_DisplacementFilter->SetOutputIndex(this->GetOutputStartIndex()); - // Generate input requested region - m_WarpFilter->SetInput(inputPtr); - m_WarpFilter->GetOutput()->UpdateOutputInformation(); - m_WarpFilter->GetOutput()->SetRequestedRegion(requestedRegion); + m_WarpFilter->SetInput(this->GetInput()); + m_WarpFilter->GraftOutput(this->GetOutput()); + m_WarpFilter->UpdateOutputInformation(); + this->GraftOutput(m_WarpFilter->GetOutput()); +} + +template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> +void +StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType> +::PropagateRequestedRegion(itk::DataObject *output) +{ + if (this->m_Updating) return; + + m_WarpFilter->GetOutput()->SetRequestedRegion(output); m_WarpFilter->GetOutput()->PropagateRequestedRegion(); } diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h new file mode 100644 index 0000000000000000000000000000000000000000..e60a091176e80ff21ba52c3156aa2ba0413b3a13 --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h @@ -0,0 +1,92 @@ +/*========================================================================= + + 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 __otbTwoNRIBandsImageToNComplexBandsImage_h +#define __otbTwoNRIBandsImageToNComplexBandsImage_h + +#include "itkImageToImageFilter.h" +#include "itkImage.h" +#include "itkNumericTraits.h" + +/* + * Inputs : one single image made of 2N real bands + * Output : one single image made of N complex bands + * + * */ + + +namespace otb +{ + + +template <class TInputImage, class TOutputImage> +class ITK_EXPORT TwoNRIBandsImageToNComplexBandsImage : public itk::ImageToImageFilter<TInputImage, TOutputImage> +{ +public: + /** Extract input and output image dimension */ + itkStaticConstMacro(InputImageDimension, + unsigned int, + TInputImage::ImageDimension); + itkStaticConstMacro(OutputImageDimension, + unsigned int, + TOutputImage::ImageDimension); + + typedef TInputImage InputImageType; + typedef TOutputImage OutputImageType; + + /** standard class typedefs */ + typedef TwoNRIBandsImageToNComplexBandsImage Self; + typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Object factory management */ + itkNewMacro(Self); + + /** typemacro */ + itkTypeMacro(TwoNRIBandsImageToNComplexBandsImage, ImageToImageFilter); + + typedef typename InputImageType::PixelType InputPixelType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + + +protected: + TwoNRIBandsImageToNComplexBandsImage(); + virtual ~TwoNRIBandsImageToNComplexBandsImage() {} + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + void GenerateOutputInformation(void); + void BeforeThreadedGenerateData(void); + void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId); + +private: + TwoNRIBandsImageToNComplexBandsImage(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbTwoNRIBandsImageToNComplexBandsImage.txx" +#endif + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx new file mode 100644 index 0000000000000000000000000000000000000000..c61f07a9009b4fe2365f926e55c1a9c4111b27fa --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx @@ -0,0 +1,143 @@ +/*========================================================================= + + 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 __otbTwoNRIBandsImageToNComplexBandsImage_txx +#define __otbTwoNRIBandsImageToNComplexBandsImage_txx + +#include "otbTwoNRIBandsImageToNComplexBandsImage.h" + +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" +#include "itkProgressReporter.h" +#include "itkVariableLengthVector.h" + + + + +namespace otb +{ + +/** + * + */ +template <class TInputImage, class TOutputImage> +TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::TwoNRIBandsImageToNComplexBandsImage() +{ + //this->SetNumberOfThreads(1); +} + +/** + * GenerateOutputInformation + */ +template<class TInputImage, class TOutputImage> +void +TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage> +::GenerateOutputInformation(void) +{ + Superclass::GenerateOutputInformation(); + + unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel(); + + if ( (nbCompo % 2) != 0 ) + { + itkExceptionMacro("Number of bands of the input images must be an even number"); + } + else + this->GetOutput()->SetNumberOfComponentsPerPixel(nbCompo/2); + + std::cout << "GenerateOutputInformation : " << this->GetOutput()->GetNumberOfComponentsPerPixel() << std::endl; + +} + +/** + * BeforeThreadedGenerateData + */ +template <class TInputImage, class TOutputImage> +void +TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage> +::BeforeThreadedGenerateData(void) +{ + unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel(); + + if ( (nbCompo % 2) != 0 ) + itkExceptionMacro("Number of bands of the input images must be an even number"); + +} + +/** + * ThreadedGenerateData + */ +template<class TInputImage, class TOutputImage> +void TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData( + const OutputImageRegionType& outputRegionForThread, + itk::ThreadIdType threadId + ) +{ + + unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel(); + + itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbCompo/2); + + + // support progress methods/callbacks + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + itk::ImageRegionConstIterator<TInputImage> inIt; + inIt = itk::ImageRegionConstIterator<TInputImage>(this->GetInput(), outputRegionForThread); + + itk::ImageRegionIterator<OutputImageType> outIt; + outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread); + + + inIt.GoToBegin(); + outIt.GoToBegin(); + + while (!outIt.IsAtEnd()) + { + + unsigned int k=0; + for (unsigned int i=0; i<nbCompo-1; i=i+2) + { + vlv[k] = std::complex< typename InputPixelType::ValueType >(inIt.Get()[i],inIt.Get()[i+1]); + k++; + } + + + outIt.Set(vlv); + + + ++inIt; + ++outIt; + + progress.CompletedPixel(); + } + +} + +/** + * Standard "PrintSelf" method + */ +template <class TInputImage, class TOutput> +void +TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace otb + +#endif diff --git a/Modules/Filtering/ImageManipulation/otb-module.cmake b/Modules/Filtering/ImageManipulation/otb-module.cmake index ca49464420ecf8215c1d36eacf45005fdcabc6c7..6a141566a1a1453663ce78f55c6ccf0f1742b5c8 100644 --- a/Modules/Filtering/ImageManipulation/otb-module.cmake +++ b/Modules/Filtering/ImageManipulation/otb-module.cmake @@ -10,6 +10,7 @@ otb_module(OTBImageManipulation OTBCommon OTBITK OTBImageBase + OTBMetadata OTBInterpolation OTBObjectList OTBStreaming diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt index a167f9c62b9244001dddfbc4c2d215ee88fcc9bb..86e9cd72c67dca156fc4fd293c9b220ff186fc21 100644 --- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt +++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt @@ -70,6 +70,11 @@ otbSpectralAngleDistanceImageFilter.cxx otbFunctionWithNeighborhoodToImageFilterNew.cxx otbEuclideanDistanceMetricWithMissingValue.cxx otbEuclideanDistanceMetricWithMissingValueNew.cxx +otbNRIBandImagesToOneNComplexBandsImage.cxx +otbOneRIBandImageToOneComplexBandImage.cxx +otbTwoNRIBandsImageToNComplexBandsImage.cxx +otbChangeNoDataValueFilter.cxx +otbImageToNoDataMaskFilter.cxx ) add_executable(otbImageManipulationTestDriver ${OTBImageManipulationTests}) @@ -669,3 +674,39 @@ otb_add_test(NAME bfTvEuclideanDistanceMetricWithMissingValue COMMAND otbImageMa otbEuclideanDistanceMetricWithMissingValue) otb_add_test(NAME bfTuEuclideanDistanceMetricWithMissingValueNew COMMAND otbImageManipulationTestDriver otbEuclideanDistanceMetricWithMissingValueNew) + +otb_add_test(NAME bfTvTwoNRIBandsImageToNComplexBandsImage COMMAND otbImageManipulationTestDriver + --compare-image ${EPSILON_7} + ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif + ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif + otbTwoNRIBandsImageToNComplexBandsImage + ${INPUTDATA}/RSAT_imagery_HH_HV_VV.tif + ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif + ) + + +otb_add_test(NAME bfTvNRIBandImagesToOneNComplexBandsImage COMMAND otbImageManipulationTestDriver + --compare-image ${EPSILON_7} + ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif + ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif + otbNRIBandImagesToOneNComplexBandsImage + ${INPUTDATA}/RSAT_imagery_HH.tif + ${INPUTDATA}/RSAT_imagery_HV.tif + ${INPUTDATA}/RSAT_imagery_VV.tif + ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif + ) + +otb_add_test(NAME bfTvOneRIBandImageToOneComplexBandImage COMMAND otbImageManipulationTestDriver + --compare-image ${EPSILON_3} + ${INPUTDATA}/RSAT_imageryC_HH.tif + ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif + otbOneRIBandImageToOneComplexBandImage + ${INPUTDATA}/RSAT_imagery_HH.tif + ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif + ) + +otb_add_test(NAME filteringImageManipulationChangeNoDataValueFilter COMMAND otbImageManipulationTestDriver + otbChangeNoDataValueFilter) + +otb_add_test(NAME filteringImageManipulationImageToNoDataMaskFilter COMMAND otbImageManipulationTestDriver + otbImageToNoDataMaskFilter) diff --git a/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4bd558f4a9589795edaac72e023f28d1e67f737a --- /dev/null +++ b/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.cxx @@ -0,0 +1,103 @@ +/*========================================================================= + + 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 "otbImage.h" +#include "otbChangeNoDataValueFilter.h" +#include "itkImageRegionIterator.h" + +int otbChangeNoDataValueFilter(int itkNotUsed(argc),char * itkNotUsed(argv) []) +{ + + // Build an image + typedef otb::Image<double> ImageType; + ImageType::Pointer img = ImageType::New(); + + ImageType::SizeType size; + size.Fill(20); + + ImageType::RegionType region; + region.SetSize(size); + + // Fill it with a default value + img->SetRegions(region); + img->Allocate(); + img->FillBuffer(10); + + // Write no-data flags to it + std::vector<bool> flags(1,true); + std::vector<double> values(1,-10.); + otb::WriteNoDataFlags(flags,values,img->GetMetaDataDictionary()); + + // Fill half of the pixels with no-data values + itk::ImageRegionIterator<ImageType> it(img,region); + unsigned int count = 0; + for(it.GoToBegin();!it.IsAtEnd();++it,++count) + { + if (count%2 == 0) + it.Set(-10.); + } + + // Instanciate filter + typedef otb::ChangeNoDataValueFilter<ImageType,ImageType> FilterType; + FilterType::Pointer filter = FilterType::New(); + + std::vector<double> newValues(1,-20.); + + filter->SetInput(img); + filter->SetNewNoDataValues(newValues); + filter->Update(); + + // Check output + it = itk::ImageRegionIterator<ImageType>(filter->GetOutput(),region); + count = 0; + + bool failed = false; + + for(it.GoToBegin();!it.IsAtEnd();++it,++count) + { + if (count%2 == 0 and it.Get()!=-20.) + { + std::cerr<<"Pixel should have new no-data value"<<std::endl; + failed = true; + } + else if(count%2 == 1 and it.Get()!=10.) + { + std::cerr<<"Pixel value should be unchanged"<<std::endl; + failed = true; + } + } + + otb::ReadNoDataFlags(filter->GetOutput()->GetMetaDataDictionary(),flags,values); + + if(flags.empty() || !flags[0]) + { + std::cerr<<"Output no-data flag should be [1] "<<std::endl; + failed = true; + } + + if(values.empty() || values[0]!=-20) + { + std::cerr<<"Output no-data value should be [-20.]"<<std::endl; + failed = true; + } + + if(failed) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx index 361248a4fcbb5551d81813d644053459597fe768..f732d0d2a493a927ccfd34f1f5633d85b3508cf3 100644 --- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx +++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx @@ -76,4 +76,9 @@ void RegisterTests() REGISTER_TEST(otbFunctionWithNeighborhoodToImageFilterNew); REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValue); REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValueNew); + REGISTER_TEST(otbNRIBandImagesToOneNComplexBandsImage); + REGISTER_TEST(otbOneRIBandImageToOneComplexBandImage); + REGISTER_TEST(otbTwoNRIBandsImageToNComplexBandsImage); + REGISTER_TEST(otbChangeNoDataValueFilter); + REGISTER_TEST(otbImageToNoDataMaskFilter); } diff --git a/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..109a2ec7d44c4ad2ff420337613260d64ba66b8a --- /dev/null +++ b/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx @@ -0,0 +1,88 @@ +/*========================================================================= + + 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 "otbImage.h" +#include "otbImageToNoDataMaskFilter.h" +#include "itkImageRegionIterator.h" + +int otbImageToNoDataMaskFilter(int itkNotUsed(argc),char * itkNotUsed(argv) []) +{ + + // Build an image + typedef otb::Image<double> ImageType; + ImageType::Pointer img = ImageType::New(); + + ImageType::SizeType size; + size.Fill(20); + + ImageType::RegionType region; + region.SetSize(size); + + // Fill it with a default value + img->SetRegions(region); + img->Allocate(); + img->FillBuffer(10); + + // Write no-data flags to it + std::vector<bool> flags(1,true); + std::vector<double> values(1,-10.); + otb::WriteNoDataFlags(flags,values,img->GetMetaDataDictionary()); + + // Fill half of the pixels with no-data values + itk::ImageRegionIterator<ImageType> it(img,region); + unsigned int count = 0; + for(it.GoToBegin();!it.IsAtEnd();++it,++count) + { + if (count%2 == 0) + it.Set(-10.); + } + + // Instanciate filter + typedef otb::ImageToNoDataMaskFilter<ImageType,ImageType> FilterType; + FilterType::Pointer filter = FilterType::New(); + + filter->SetInput(img); + filter->SetInsideValue(255); + filter->SetOutsideValue(0); + filter->Update(); + + // Check output + it = itk::ImageRegionIterator<ImageType>(filter->GetOutput(),region); + count = 0; + + bool failed = false; + + for(it.GoToBegin();!it.IsAtEnd();++it,++count) + { + if (count%2 == 0 and it.Get()!=0) + { + std::cerr<<"Pixel should be masked"<<std::endl; + failed = true; + } + else if(count%2 == 1 and it.Get()!=255) + { + std::cerr<<"Pixel should not be masked"<<std::endl; + failed = true; + } + } + + if(failed) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx new file mode 100644 index 0000000000000000000000000000000000000000..778f42146ea0b8ddd85ef72a63e121cf245d15c1 --- /dev/null +++ b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx @@ -0,0 +1,62 @@ +/*========================================================================= + + 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 "itkMacro.h" + +#include "otbNRIBandImagesToOneNComplexBandsImage.h" + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int otbNRIBandImagesToOneNComplexBandsImage(int itkNotUsed(argc), char * argv[]) +{ + + typedef double PixelType; + typedef otb::VectorImage<PixelType, 2> InputImageType; + + typedef std::complex<double> OutputPixelType; + typedef otb::VectorImage<OutputPixelType, 2> OutputImageType; + + + typedef otb::NRIBandImagesToOneNComplexBandsImage<InputImageType, OutputImageType> FilterType; + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::ImageFileWriter<OutputImageType> WriterType; + + ReaderType::Pointer readerA = ReaderType::New(); + ReaderType::Pointer readerB = ReaderType::New(); + ReaderType::Pointer readerC = ReaderType::New(); + FilterType::Pointer filter = FilterType::New(); + WriterType::Pointer writer = WriterType::New(); + + + readerA->SetFileName(argv[1]); + readerB->SetFileName(argv[2]); + readerC->SetFileName(argv[3]); + writer->SetFileName(argv[4]); + + filter->SetInput(0,readerA->GetOutput()); + filter->SetInput(1,readerB->GetOutput()); + filter->SetInput(2,readerC->GetOutput()); + writer->SetInput(filter->GetOutput()); + writer->Update(); + + + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bbc4682269f0f3b7ea6f3bc3243810dd80d3099f --- /dev/null +++ b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx @@ -0,0 +1,56 @@ +/*========================================================================= + + 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 "itkMacro.h" + +#include "otbOneRIBandImageToOneComplexBandImage.h" + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int otbOneRIBandImageToOneComplexBandImage(int itkNotUsed(argc), char * argv[]) +{ + + typedef double PixelType; + typedef otb::VectorImage<PixelType, 2> InputImageType; + + typedef std::complex<double> OutputPixelType; + typedef otb::Image<OutputPixelType, 2> OutputImageType; + + + typedef otb::OneRIBandImageToOneComplexBandImage<InputImageType, OutputImageType> FilterType; + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::ImageFileWriter<OutputImageType> WriterType; + + ReaderType::Pointer reader = ReaderType::New(); + FilterType::Pointer filter = FilterType::New(); + WriterType::Pointer writer = WriterType::New(); + + + reader->SetFileName(argv[1]); + writer->SetFileName(argv[2]); + + filter->SetInput(reader->GetOutput()); + writer->SetInput(filter->GetOutput()); + writer->Update(); + + + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b4fed1963178ae79497fcdc18161b99261205dbc --- /dev/null +++ b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx @@ -0,0 +1,56 @@ +/*========================================================================= + + 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 "itkMacro.h" + +#include "otbTwoNRIBandsImageToNComplexBandsImage.h" + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int otbTwoNRIBandsImageToNComplexBandsImage(int itkNotUsed(argc), char * argv[]) +{ + + typedef double PixelType; + typedef otb::VectorImage<PixelType, 2> InputImageType; + + typedef std::complex<double> OutputPixelType; + typedef otb::VectorImage<OutputPixelType, 2> OutputImageType; + + + typedef otb::TwoNRIBandsImageToNComplexBandsImage<InputImageType, OutputImageType> FilterType; + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::ImageFileWriter<OutputImageType> WriterType; + + ReaderType::Pointer reader = ReaderType::New(); + FilterType::Pointer filter = FilterType::New(); + WriterType::Pointer writer = WriterType::New(); + + + reader->SetFileName(argv[1]); + writer->SetFileName(argv[2]); + + filter->SetInput(0,reader->GetOutput()); + writer->SetInput(filter->GetOutput()); + writer->Update(); + + + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h index 26ac0e5470207740a37447551324c499a33afb2a..0aa2d8665815ca14c7005fd99fc32eb9f3532b64 100644 --- a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h +++ b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h @@ -79,34 +79,29 @@ public: const double M12 = static_cast<double>(Mueller[1]); const double M13 = static_cast<double>(Mueller[2]); const double M14 = static_cast<double>(Mueller[3]); - const double M21 = static_cast<double>(Mueller[4]); const double M22 = static_cast<double>(Mueller[5]); const double M23 = static_cast<double>(Mueller[6]); const double M24 = static_cast<double>(Mueller[7]); - const double M31 = static_cast<double>(Mueller[8]); - const double M32 = static_cast<double>(Mueller[9]); const double M33 = static_cast<double>(Mueller[10]); const double M34 = static_cast<double>(Mueller[11]); - const double M41 = static_cast<double>(Mueller[12]); - const double M42 = static_cast<double>(Mueller[13]); - const double M43 = static_cast<double>(Mueller[14]); const double M44 = static_cast<double>(Mueller[15]); - const ComplexType hhhh(M11+M22+M12+M21, 0.0); - const ComplexType hvhv(M11+M12-M21-M22, 0.0); - const ComplexType vvvv(M11+M22-M12-M21, 0.0); - const ComplexType hhhv(M13+M23, M14+M24); - const ComplexType hhvv(-M33-M44, M43-M34); - const ComplexType hvvv(M32-M31, M41-M42); - - result[0] = static_cast<OutputValueType>( hhhh ); - result[1] = static_cast<OutputValueType>( 2.* hhhv ); - result[2] = static_cast<OutputValueType>( hhvv ); - result[3] = static_cast<OutputValueType>( 4.* hvhv ); - result[4] = static_cast<OutputValueType>( 2.* hvvv ); - result[5] = static_cast<OutputValueType>( vvvv ); - - return 0.5*result; + + const ComplexType A(0.5*(M11+M22+2*M12)); + const ComplexType B(0.5*vcl_sqrt(2.0)*(M13+M23), 0.5*vcl_sqrt(2.0)*(M14+M24)); + const ComplexType C(-0.5*(M33+M44), -M34); + const ComplexType E(M11-M22, 0.0); + const ComplexType F(0.5*vcl_sqrt(2.0)*(M13-M23), 0.5*vcl_sqrt(2.0)*(M14-M24)); + const ComplexType I(0.5*(M11+M22-2*M12)); + + result[0] = static_cast<OutputValueType>( A ); + result[1] = static_cast<OutputValueType>( B ); + result[2] = static_cast<OutputValueType>( C ); + result[3] = static_cast<OutputValueType>( E ); + result[4] = static_cast<OutputValueType>( F ); + result[5] = static_cast<OutputValueType>( I ); + + return result; } unsigned int GetOutputSize() diff --git a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx index d465a986214b438a1ad706d0ae208eaa9770d064..e5539846c767445733336cd7952e937a42f6e60f 100644 --- a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx +++ b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx @@ -40,6 +40,7 @@ MultiChannelsPolarimetricSynthesisFilter<TInputImage, TOutputImage, TFunction> SetEmissionH(false); SetEmissionV(false); SetGain(1); + SetMode(0); m_ArchitectureType = PolarimetricData::New(); } diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h index 1081c263d908c91f7411bbadcc837b028aa0275d..a025d9c337a32c5865a964452bba75a247bb0373 100644 --- a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h +++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h @@ -30,26 +30,36 @@ namespace Functor { * \brief Evaluate the reciprocal Mueller matrix from the reciprocal coherency matrix image * * Outpus are: - * - channel #0 : \f$ 0.5*\mathcal{Re}( Coherency[0]+Coherency[3]+Coherency[5]) \f$ - * - channel #1 : \f$ 0.5*\mathcal{Re}( Coherency[0]+Coherency[3]-Coherency[5]) \f$ - * - channel #2 : \f$ 0.5*\mathcal{Re}( Coherency[0]-Coherency[3]+Coherency[5]) \f$ - * - channel #3 : \f$ 0.5*\mathcal{Re}(-Coherency[0]+Coherency[3]+Coherency[5]) \f$ - * - channel #4 : \f$ \mathcal{Re}(Coherency[1]) \f$ - * - channel #5 : \f$ \mathcal{Re}(Coherency[2]) \f$ - * - channel #6 : \f$ \mathcal{Im}(Coherency[4]) \f$ - * - channel #7 : \f$ \mathcal{Re}(Coherency[4]) \f$ - * - channel #8 : \f$ \mathcal{Im}(Coherency[2]) \f$ - * - channel #9 : \f$ \mathcal{Im}(Coherency[1]) \f$ + * - channel #0 : \f$ 0.5*( C_{11}+C_{22}+C_{33} ) \f$ + * - channel #1 : \f$ Re(C_{12}) + Im(C_{22}) \f$ + * - channel #2 : \f$ Re(C_{13}) \f$ + * - channel #3 : \f$ Im(C_{23}) \f$ + * - channel #4 : \f$ Re(C_{12}) \f$ + * - channel #5 : \f$ 0.5*( C_{11}+C_{22}-C_{33} ) \f$ + * - channel #6 : \f$ Re(C_{23}) \f$ + * - channel #7 : \f$ Im(C_{13}) \f$ + * - channel #8 : \f$ -Re(C_{13}) \f$ + * - channel #9 : \f$ -Re(C_{23}) \f$ + * - channel #10 : \f$ 0.5.Re(VAL1) \f$ + * - channel #11 : \f$ 0.5.Im(VAL0) \f$ + * - channel #12 : \f$ Im(C_{23}) \f$ + * - channel #13 : \f$ Im(C_{13}) \f$ + * - channel #14 : \f$ 0.5.Im(VAL1^{*}) \f$ + * - channel #15 : \f$ 0.5.Re(VAL0) \f$ * + * With: + * VAL0 = C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*} + * VAL1 = -C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*} + * * Where Coherency is the input pixel and contains: - * - channel #0 : \f$ (S_{hh}+S_{vv}).(S_{hh}+S_{vv})^{*} \f$ - * - channel #1 : \f$ (S_{hh}+S_{vv}).(S_{hh}-S_{vv})^{*} \f$ - * - channel #2 : \f$ (S_{hh}+S_{vv}).(2*S_{hv})^{*} \f$ - * - channel #3 : \f$ (S_{hh}-S_{vv}).(S_{hh}-S_{vv})^{*} \f$ - * - channel #4 : \f$ (S_{hh}-S_{vv}).(2*S_{hv})^{*} \f$ - * - channel #5 : \f$ (2*S_{hv}).(2*S_{hv})^{*} \f$ + * - channel #0 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}+S_{vv})^{*} \f$ + * - channel #1 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}-S_{vv})^{*} \f$ + * - channel #2 : \f$ 0.5*(S_{hh}+S_{vv}).(2*S_{hv})^{*} \f$ + * - channel #3 : \f$ 0.5*(S_{hh}-S_{vv}).(S_{hh}-S_{vv})^{*} \f$ + * - channel #4 : \f$ 0.5*(S_{hh}-S_{vv}).(2*S_{hv})^{*} \f$ + * - channel #5 : \f$ 0.5*(2*S_{hv}).(2*S_{hv})^{*} \f$ * - * The output pixel has 10 channels : the diagonal and the upper element of the matrix. + * The output pixel has 16 channels * Element are stored from left to right, line by line. * * \ingroup SARPolarimetry @@ -72,17 +82,28 @@ public: const double T1 = static_cast<double>(Coherency[0].real()); const double T2 = static_cast<double>(Coherency[3].real()); const double T3 = static_cast<double>(Coherency[5].real()); - - result[0] = 0.5*(T1+T2+T3); // A0+B0 - result[1] = 0.5*(T1+T2-T3); // A0+B - result[2] = 0.5*(T1-T2+T3); // A0-B - result[3] = 0.5*(-T1+T2+T3); // -A0+B0 - result[4] = static_cast<double>( Coherency[1].real() ); // C - result[5] = static_cast<double>( Coherency[2].real() ); // H - result[6] = static_cast<double>( Coherency[4].imag() ); // F - result[7] = static_cast<double>( Coherency[4].real() ); // E - result[8] = static_cast<double>( Coherency[2].imag() ); // G - result[9] = -static_cast<double>( Coherency[1].imag() ); // D + + ComplexType VAL4 = static_cast<ComplexType>( (Coherency[1] - Coherency[3]) ); + ComplexType VAL5 = static_cast<ComplexType>( (Coherency[1] - Coherency[0]) ); + ComplexType VAL0 = static_cast<ComplexType>( Coherency[5] ) + VAL5 - vcl_conj(VAL4); + ComplexType VAL1 = static_cast<ComplexType>( -Coherency[5] ) + VAL5 - vcl_conj(VAL4); + + result[0] = 0.5*(T1+T2+T3); + result[1] = static_cast<double>( Coherency[1].real()+Coherency[3].imag() ); + result[2] = static_cast<double>( Coherency[2].real() ); + result[3] = static_cast<double>( Coherency[4].imag() ); + result[4] = static_cast<double>( Coherency[1].real() ); + result[5] = 0.5*(T1+T2-T3); + result[6] = static_cast<double>( Coherency[4].real() ); + result[7] = static_cast<double>( Coherency[2].imag() ); + result[8] = static_cast<double>( -Coherency[2].real() ); + result[9] = static_cast<double>( -Coherency[4].real() ); + result[10] = static_cast<double>( 0.5*VAL1.real() ); + result[11] = static_cast<double>( 0.5*VAL0.imag() ); + result[12] = static_cast<double>( Coherency[4].imag() ); + result[13] = static_cast<double>( Coherency[2].imag() ); + result[14] = static_cast<double>( 0.5*vcl_conj(VAL1).imag() ); + result[15] = static_cast<double>( 0.5*VAL0.real() ); return result; } @@ -99,7 +120,7 @@ public: virtual ~ReciprocalCoherencyToReciprocalMuellerFunctor() {} private: - itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 10); + itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 16); }; } diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h index 3ad4b0b79e093552605135c1ac7be75493ead173..f34b83c5035cb68cb302dfa1856a282298d65e9f 100644 --- a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h +++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h @@ -30,12 +30,12 @@ namespace Functor { * \brief Evaluate the Coherency matrix from the Covariance image * * Output value are: - * - channel #0 : \f$ 0.5 * (S_{hh}+S_{vv}.(S_{hh}+S_{vv})^{*} \f$ - * - channel #1 : \f$ 0.5 * (S_{hh}+S_{vv}.(S_{hh}-S_{vv})^{*} \f$ - * - channel #2 : \f$ (S_{hh}+S_{vv}.(S_{hv})^{*} \f$ - * - channel #3 : \f$ 0.5 * (S_{hh}-S_{vv}.(S_{hh}-S_{vv})^{*} \f$ - * - channel #4 : \f$ (S_{hh}-S_{vv}.(S_{hv})^{*} \f$ - * - channel #5 : \f$ 2.0*S_{hv}.S_{hv}^{*} \f$ + * - channel #0 : \f$ 0.5 . (C33 + C13 + C13^{*} + C11) \f$ + * - channel #1 : \f$ 0.5 . (-C33 - C13 + C13^{*} + C11) \f$ + * - channel #2 : \f$ 0.5 . (\sqrt{2}.C12 + \sqrt{2}.C23^{*}) \f$ + * - channel #3 : \f$ 0.5 . (C33 - C13 - C13^{*} + C11 \f$) + * - channel #4 : \f$ 0.5 . (\sqrt{2}.C12 - \sqrt{2}.C23^{*}) \f$ + * - channel #5 : \f$ 0.5 . (2 . C22) \f$ * * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix. * Element are stored from left to right, line by line. @@ -61,31 +61,25 @@ public: TOutput result; result.SetSize(m_NumberOfComponentsPerPixel); - /* Using the convention - * \f$ C_{11} = S_{hh}*S_{hh}^* \f$ - * \f$ C_{12} = S_{hh}*S_{hv}^* \f$ - * \f$ C_{13} = S_{hh}*S_{vv}^* \f$ - * \f$ C_{22} = S_{hv}*S_{hv}^* \f$ - * \f$ C_{23} = S_{hv}*S_{vv}^* \f$ - * \f$ C_{33} = S_{vv}*S_{vv}^* \f$ - */ + const ComplexType C11 = static_cast<ComplexType>(Covariance[0]); const ComplexType C12 = static_cast<ComplexType>(Covariance[1]); const ComplexType C13 = static_cast<ComplexType>(Covariance[2]); const ComplexType C22 = static_cast<ComplexType>(Covariance[3]); const ComplexType C23 = static_cast<ComplexType>(Covariance[4]); const ComplexType C33 = static_cast<ComplexType>(Covariance[5]); - - //const ComplexType C21 = vcl_conj(C12); - const ComplexType C31 = vcl_conj(C13); - const ComplexType C32 = vcl_conj(C23); - - result[0] = static_cast<OutputValueType>( 0.5*(C11 + C13 + C31 + C33) ); - result[1] = static_cast<OutputValueType>( 0.5*(C11 - C13 + C31 - C33) ); - result[2] = static_cast<OutputValueType>( C12 + C32 ); - result[3] = static_cast<OutputValueType>( 0.5*(C11 - C13 - C31 + C33) ); - result[4] = static_cast<OutputValueType>( C12 - C32 ); - result[5] = static_cast<OutputValueType>( 2.0 * C22 ); + + const ComplexType two = ComplexType(2.0, 0.0); + const ComplexType rootTwo = ComplexType(vcl_sqrt(2.0), 0.0); + + result[0] = static_cast<OutputValueType>( C33 + C13 + vcl_conj(C13) + C11 ); + result[1] = static_cast<OutputValueType>( -C33 - C13 + vcl_conj(C13) + C11 ); + result[2] = static_cast<OutputValueType>( rootTwo*C12 + rootTwo*vcl_conj(C23) ); + result[3] = static_cast<OutputValueType>( C33 - C13 - vcl_conj(C13) + C11 ); + result[4] = static_cast<OutputValueType>( rootTwo*C12 - rootTwo*vcl_conj(C23) ); + result[5] = static_cast<OutputValueType>( two * C22 ); + + result /= 2.0; return result; } diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h index 227b46a90d9f99523c1e70ece1d0784f24ad4b7b..8a8caa7b31c69756801047673bbab3706c614945 100644 --- a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h +++ b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h @@ -20,6 +20,7 @@ #define __ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter_h #include "itkUnaryFunctorImageFilter.h" +#include "vcl_complex.h" namespace otb { @@ -31,23 +32,14 @@ namespace Functor { * Extract from Antennas for radar and communications Harold Mott p 317. * * Output value are: - * - channel #0 : \f$ 0.25 * (C_{1}+C_{3}+4*C_{2}-2*C_{6}-4*C_{5}-4*C_{9}) \f$ - * - channel #1 : \f$ 0.25 * (C_{1}-C_{3}+2*C_{5}+2*C_{9} - 0.5\mathcal{i}.(C_{4}+C_{7}+C_{8}) \f$ - * - channel #2 : \f$ 0.25 * (C_{1}+C_{3}-4*C_{2}-2*C_{6} - \mathcal{i}.(C_{4}+C_{8}) \f$ - * - channel #3 : \f$ 0.25 * (C_{1}+C_{3}+2*C_{6} \f$ - * - channel #4 : \f$ 0.25 * (C_{1}-C_{3}+2*C_{5}-2*C_{9} - 0.5\mathcal{i}.(C_{4}-C_{7}+C_{8}) \f$ - * - channel #5 : \f$ 0.25 * (C_{1}+C_{3}+4*C_{2}-2*C_{6}+4*C_{5}+4*C_{9}) \f$ + * - channel #0 : \f$ 0.25 * (C33-i.\sqrt{2}.C23-C13+i.\sqrt{2}.C23^{*}-C13^{*}+2.C22-i.\sqrt{2}.C12+i.\sqrt{2}.C12^{*}+C11) \f$ + * - channel #1 : \f$ 0.25 * (i.\sqrt{2}.C33+2.C23-i.\sqrt{2}.C13+i.\sqrt{2}.C13^{*}+2.C12^{*}-i.\sqrt{2}.C11) \f$ + * - channel #2 : \f$ 0.25 * (-C33+i.\sqrt{2}.C23+C13+i.\sqrt{2}.C23^{*}+C13^{*}+2.C22-i.\sqrt{2}.C12-i.\sqrt{2}.C12^{*}-C11 ) \f$ + * - channel #3 : \f$ 0.25 * (2.C33+2.C13+2.C13^{*}+2.C11)\f$ + * - channel #4 : \f$ 0.25 * (i.\sqrt{2}.C33+i.\sqrt{2}.C13+2.C23^{*}-i.\sqrt{2}.C13^{*}+2.C12-i.\sqrt{2}.C11) \f$ + * - channel #5 : \f$ 0.25 * (C33+i.\sqrt{2}.C23-C13-i.\sqrt{2}.C23^{*}-C13^{*}+2.C22+i.\sqrt{2}.C12-i.\sqrt{2}.C12^{*}+C11) \f$ * - * Where: - * - \f$ C_{1} = S_{hh}*S_{hh}}^{*} = \mathcal{Re}(input[0]) \f$ - * - \f$ C_{2} = S_{hv}*S_{hv}}^{*} = \mathcal{Re}(input[3]) \f$ - * - \f$ C_{3} = S_{vv}*S_{vv}}^{*} = \mathcal{Re}(input[5]) \f$ - * - \f$ C_{4} = \mathcal{Re}(S_{hh}*S_{hv}}^{*}) = \mathcal{Re}(input[1]) \f$ - * - \f$ C_{5} = \mathcal{Im}(S_{hh}*S_{hv}}^{*}) = \mathcal{Im}(input[1]) \f$ - * - \f$ C_{6} = \mathcal{Re}(S_{hh}*S_{vv}}^{*}) = \mathcal{Re}(input[2]) \f$ - * - \f$ C_{7} = \mathcal{Im}(S_{hh}*S_{vv}}^{*}) = \mathcal{Im}(input[2]) \f$ - * - \f$ C_{8} = \mathcal{Re}(S_{hv}*S_{vv}}^{*}) = \mathcal{Re}(input[4]) \f$ - * - \f$ C_{9} = \mathcal{Im}(S_{hv}*S_{vv}}^{*} = \mathcal{Im}(input[4])) \f$ + * Where Cij are related to the elements of the reciprocal linear covariance matrix. * * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix. * Element are stored from left to right, line by line. @@ -74,32 +66,27 @@ public: TOutput result; result.SetSize(m_NumberOfComponentsPerPixel); result.Fill(0.0); - - const RealType C1 = static_cast<RealType>(Covariance[0].real()); // C1 <hh.hh*> - const RealType C2 = static_cast<RealType>(Covariance[3].real()); // C2 <hv.hv*> - const RealType C3 = static_cast<RealType>(Covariance[5].real()); // C3 <vv.vv*> - const RealType C4 = static_cast<RealType>(Covariance[1].real()); // C4 Re<hh.hv*> - const RealType C5 = static_cast<RealType>(Covariance[1].imag()); // C5 Im<hh.hv*> - const RealType C6 = static_cast<RealType>(Covariance[2].real()); // C6 Re<hh.vv*> - const RealType C7 = static_cast<RealType>(Covariance[2].imag()); // C7 Im<hh.vv*> - const RealType C8 = static_cast<RealType>(Covariance[4].real()); // C8 Re<hv.vv*> - const RealType C9 = static_cast<RealType>(Covariance[4].imag()); // C9 Im<hv.vv*> - - const RealType llrrReal = 0.25 * ( C1 + C3 - 4*C2 -2*C6); - const RealType llrrImag = -(C4 + C8); - - const RealType lllrReal = 0.25 * ( C1 - C3 - 2*C5 + 2*C9); - const RealType lllrImag = -0.5*(C7+C4+C8); - - const RealType rrlrReal = 0.25 * ( C1 -C3 + 2*C5 - 2*C9); - const RealType rrlrImag = 0.5 * (C4+C8-C7); - - result[0] = ComplexType(0.25 * ( C1 + C3 + 4*C2 - 2*C6 - 4*C5 - 4*C9)); - result[1] = ComplexType(lllrReal, lllrImag); - result[2] = ComplexType(llrrReal, llrrImag); - result[3] = ComplexType(0.25 * ( C1 + C3 + 2*C6)); - result[4] = ComplexType(rrlrReal, -rrlrImag); - result[5] = ComplexType(0.25 * ( C1 + C3 + 4*C2 - 2*C6 + 4*C5 + 4*C9)); + + + const ComplexType C11 = static_cast<ComplexType>( Covariance[0] ); // <hh.hh*> + const ComplexType C12 = static_cast<ComplexType>( Covariance[1] ); // <sqrt(2).hh.hv*> + const ComplexType C13 = static_cast<ComplexType>( Covariance[2] ); // <hh.vv*> + const ComplexType C22 = static_cast<ComplexType>( Covariance[3] ); // <2.hv.hv*> + const ComplexType C23 = static_cast<ComplexType>( Covariance[4] ); // <sqrt(2).hv.vv*> + const ComplexType C33 = static_cast<ComplexType>( Covariance[5] ); // <vv.vv*> + + + const ComplexType cst1 = ComplexType(0.0, vcl_sqrt(2.0)); + const ComplexType two = ComplexType(2.0, 0 ); + + result[0] = static_cast<ComplexType>( C33-cst1*C23-C13+cst1*vcl_conj(C23)-vcl_conj(C13)+two*C22-cst1*C12+cst1*vcl_conj(C12)+C11 ) ; + result[1] = static_cast<ComplexType>( cst1*C33+two*C23-cst1*C13+cst1*vcl_conj(C13)+two*vcl_conj(C12)-cst1*C11 ); + result[2] = static_cast<ComplexType>( -C33+cst1*C23+C13+cst1*vcl_conj(C23)+vcl_conj(C13)+two*C22-cst1*C12-cst1*vcl_conj(C12)-C11 ) ; + result[3] = static_cast<ComplexType>( two*C33+two*C13+two*vcl_conj(C13)+two*C11 ) ; + result[4] = static_cast<ComplexType>( cst1*C33+cst1*C13+two*vcl_conj(C23)-cst1*vcl_conj(C13)+two*C12-cst1*C11 ) ; + result[5] = static_cast<ComplexType>( C33+cst1*C23-C13-cst1*vcl_conj(C23)-vcl_conj(C13)+two*C22+cst1*C12-cst1*vcl_conj(C12)+C11 ) ; + + result /= 4.0; return result; } diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h index c3d4f81404863d17f6b9bcd8ae54354d2b35d4eb..08e10da87a53b51cbd79ae565c598240911c4965 100644 --- a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h +++ b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h @@ -42,9 +42,9 @@ namespace Functor * - channel #9 : \f$ S_{rr}.S_{rr}^{*} \f$ * * With: - * - \f$ S_{ll} = 0.5 * (-S_{hh}-i*S_{hv}-i*S_{vh}+S_{vv}) \f$ - * - \f$ S_{lr} = 0.5 * (-S_{hh}+i*S_{hv}-i*S_{vh}+S_{vv}) \f$ - * - \f$ S_{rl} = 0.5 * (-S_{hh}-i*S_{hv}+i*S_{vh}-S_{vv}) \f$ + * - \f$ S_{ll} = 0.5 * (S_{hh}+i*S_{hv}+i*S_{vh}-S_{vv}) \f$ + * - \f$ S_{lr} = 0.5 * (i*S_{hh}+S_{hv}-S_{vh}+i*S_{vv}) \f$ + * - \f$ S_{rl} = 0.5 * (i*S_{hh}-S_{hv}+S_{vh}+i*S_{vv}) \f$ * - \f$ S_{rr} = 0.5 * (-S_{hh}+i*S_{hv}+i*S_{vh}+S_{vv}) \f$ * * Extract from Antennas for radar and communications Harold Mott p 317. @@ -89,12 +89,14 @@ public: result.SetSize(m_NumberOfComponentsPerPixel); const ComplexType jS_hv = S_hv * ComplexType(0., 1.); const ComplexType jS_vh = S_vh * ComplexType(0., 1.); - + const ComplexType jS_hh = S_hh * ComplexType(0., 1.); + const ComplexType jS_vv = S_vv * ComplexType(0., 1.); + const ComplexType coef(0.5); - const ComplexType Sll = coef*( -S_hh-jS_hv-jS_vh+S_vv ); - const ComplexType Slr = coef*( -S_hh+jS_hv-jS_vh-S_vv ); - const ComplexType Srl = coef*( -S_hh-jS_hv+jS_vh-S_vv ); + const ComplexType Sll = coef*( S_hh+jS_hv+jS_vh-S_vv ); + const ComplexType Slr = coef*( jS_hh+S_hv-S_vh+jS_vv ); + const ComplexType Srl = coef*( jS_hh-S_hv+S_vh+jS_vv ); const ComplexType Srr = coef*( -S_hh+jS_hv+jS_vh+S_vv ); //const ComplexType conjSll = vcl_conj(Sll); diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h index 5d31c330b76a66d0ddd7d8230cb00a06aae11bae..4bd338ccef5c7dbf1fcdd8eb92b79723a925ccf1 100644 --- a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h +++ b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h @@ -50,8 +50,8 @@ namespace Functor * With : * - \f$ T_{xx} = -S_{hh} \f$ * - \f$ T_{xy} = -S_{hv} \f$ - * - \f$ T_{yx} = -S_{vh} \f$ - * - \f$ T_{yy} = -S_{vv} \f$ + * - \f$ T_{yx} = S_{vh} \f$ + * - \f$ T_{yy} = S_{vv} \f$ * * Output is a not a complex. The output pixel has 16 channels : each element of the Mueller matrix. * The order of the channels corresponds to : diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h index 53c62b6339bd7760c3f6ec3cdedfc0ec28c548ec..7dbb8322dc7cd0f7f01a5d0f0cd21f20c65c8c3b 100644 --- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h +++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h @@ -80,14 +80,14 @@ public: const ComplexType coef(0.5); const ComplexType j2S_hv = S_hv * ComplexType(0.0, 2.0); + const ComplexType jS_hh = S_hh * ComplexType(0.0, 1.0); + const ComplexType jS_vv = S_vv * ComplexType(0.0, 1.0); - const ComplexType Sll = coef * ( -S_hh-j2S_hv+S_vv ); - const ComplexType Slr = coef * ( -S_hh+-S_vv ); + + const ComplexType Sll = coef * ( S_hh+j2S_hv-S_vv ); + const ComplexType Slr = coef * ( jS_hh + jS_vv ); const ComplexType Srr = coef * ( -S_hh+j2S_hv+S_vv ); - //const ComplexType conjSll = vcl_conj(Sll); - //const ComplexType conjSlr = vcl_conj(Slr); - //const ComplexType conjSrr = vcl_conj(Srr); SinclairToReciprocalCovarianceFunctorType funct; return ( funct(Sll, Slr, Srr ) ); diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h index 98c7bba8edc51233f4a44b05522198f19515ff10..8ad714abef0d6c103c84e882489cf7d3fa634226 100644 --- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h +++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h @@ -30,10 +30,10 @@ namespace Functor * * Output value are: * - channel #0 : \f$ S_{hh}.S_{hh}^{*} \f$ - * - channel #1 : \f$ S_{hh}.S_{hv}^{*} \f$ + * - channel #1 : \f$ \sqrt{2}.S_{hh}.S_{hv}^{*} \f$ * - channel #2 : \f$ S_{hh}.S_{vv}^{*} \f$ - * - channel #3 : \f$ S_{hv}.S_{hv}^{*} \f$ - * - channel #4 : \f$ S_{hv}.S_{vv}^{*} \f$ + * - channel #3 : \f$ 2.S_{hv}.S_{hv}^{*} \f$ + * - channel #4 : \f$ \sqrt{2}.S_{hv}.S_{vv}^{*} \f$ * - channel #5 : \f$ S_{vv}.S_{vv}^{*} \f$ * * This is a adaptation of the SinclairToCovarianceMatrixFunctor, where \f$ S_{hv}=S_{vh} \f$. @@ -71,12 +71,12 @@ public: const ComplexType S_hh = static_cast<ComplexType>(Shh); const ComplexType S_hv = static_cast<ComplexType>(Shv); const ComplexType S_vv = static_cast<ComplexType>(Svv); - + result[0] = static_cast<OutputValueType>( std::norm( S_hh ) ); - result[1] = static_cast<OutputValueType>( S_hh*vcl_conj(S_hv) ); + result[1] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hh*vcl_conj(S_hv) ); result[2] = static_cast<OutputValueType>( S_hh*vcl_conj(S_vv) ); - result[3] = static_cast<OutputValueType>( std::norm( S_hv ) ); - result[4] = static_cast<OutputValueType>( S_hv*vcl_conj(S_vv) ); + result[3] = static_cast<OutputValueType>( 2.0*std::norm( S_hv ) ); + result[4] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hv*vcl_conj(S_vv) ); result[5] = static_cast<OutputValueType>( std::norm( S_vv ) ); return (result); diff --git a/Modules/Filtering/Polarimetry/test/CMakeLists.txt b/Modules/Filtering/Polarimetry/test/CMakeLists.txt index f5657bab1c4723d1e3a977c4e2fa0cb725194698..c3825403977252f806d4e27ec4fa085eefcdbb5e 100644 --- a/Modules/Filtering/Polarimetry/test/CMakeLists.txt +++ b/Modules/Filtering/Polarimetry/test/CMakeLists.txt @@ -72,7 +72,7 @@ otb_add_test(NAME saTuReciprocalLinearCovarianceToReciprocalCircularCovarianceIm ) otb_add_test(NAME saTvReciprocalCovarianceToReciprocalCoherencyImageFilter COMMAND otbPolarimetryTestDriver - --compare-image ${EPSILON_12} ${BASELINE}/saTvMLCToCoherencyImageFilter.tif + --compare-image ${EPSILON_12} ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif ${TEMP}/saTvMLCToCoherencyImageFilter.tif otbReciprocalCovarianceToReciprocalCoherencyImageFilter ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif @@ -291,7 +291,7 @@ otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCoherenc otb_add_test(NAME saTvReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter COMMAND otbPolarimetryTestDriver - --compare-image ${EPSILON_12} ${BASELINE}/saTvMLCToCircularCoherencyDegreeImageFilter.tif + --compare-image ${EPSILON_12} ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix.tif ${TEMP}/saTvMLCToCircularCoherencyDegreeImageFilter.tif otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif @@ -299,7 +299,7 @@ otb_add_test(NAME saTvReciprocalLinearCovarianceToReciprocalCircularCovarianceIm ) otb_add_test(NAME saTvReciprocalCoherencyToReciprocalMuellerImageFilter COMMAND otbPolarimetryTestDriver - --compare-image ${EPSILON_12} ${BASELINE}/saTvReciprocalCoherencyToMuellerImageFilter.tif + --compare-image ${EPSILON_12} ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif ${TEMP}/saTvReciprocalCoherencyToMuellerImageFilter.tif otbReciprocalCoherencyToReciprocalMuellerImageFilter ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif @@ -315,7 +315,7 @@ otb_add_test(NAME saTuReciprocalCovarianceToCoherencyDegreeImageFilterNew COMMAN ) otb_add_test(NAME saTvMuellerToReciprocalCovarianceImageFilter COMMAND otbPolarimetryTestDriver - --compare-image ${EPSILON_12} ${BASELINE}/saTvMuellerToMLCImageFilter.tif + --compare-image ${EPSILON_12} ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif ${TEMP}/saTvMuellerToMLCImageFilter.tif otbMuellerToReciprocalCovarianceImageFilter ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif diff --git a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx index e52054bd84825297e2fc4ae96b0c31f18e06206e..db596e64ebcca9b864e8e457e095775a9fd8fdde 100644 --- a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx +++ b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx @@ -43,12 +43,12 @@ int otbMuellerToReciprocalCovarianceFunctor(int itkNotUsed(argc), char * itkNotU val += 0.5; } - result[0] = ComplexType(2.5, 0.); - result[1] = ComplexType(4., 5.); - result[2] = ComplexType(-6.25, 0.75); - result[3] = ComplexType(-8, 0.); - result[4] = ComplexType(0.5, -0.5); - result[5] = ComplexType(0., 0.); + result[0] = ComplexType(1.75,0); + result[1] = ComplexType(2.82842712474619,3.53553390593274); + result[2] = ComplexType(-6.25,-5.5); + result[3] = ComplexType(-2.5,0); + result[4] = ComplexType(-1.4142135623731,-1.4142135623731); + result[5] = ComplexType(0.75,0); FunctorType funct; outputFunct = funct.operator ()( input ); diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx index c883bdef933ac1ec90774d660e887c80d54bf66a..030cc9b5d4fdcecd6a6bacd7530423a2cde0baed 100644 --- a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx +++ b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx @@ -31,14 +31,14 @@ int otbSinclairToCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * it OutputType outputFunct; result[0] = ComplexType( 32., 0. ); - result[1] = ComplexType( 0., 24. ); - result[2] = ComplexType( 0., 16.); - result[3] = ComplexType( -8., 0 ); + result[1] = ComplexType( 24., 0. ); + result[2] = ComplexType( 16., 0.); + result[3] = ComplexType( 8., 0 ); result[4] = ComplexType( 18., 0. ); result[5] = ComplexType( 12. , 0. ); - result[6] = ComplexType( 0. , 6. ); + result[6] = ComplexType( 6. , 0. ); result[7] = ComplexType( 8, 0. ); - result[8] = ComplexType( 0, 4. ); + result[8] = ComplexType( 4., 0. ); result[9] = ComplexType( 2, 0. ); outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) ); diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx index 18c8d486a0e19f3b05b6e44e1a370b20e31c1b7f..af4666a19856e67e98264dbaff90863a30a8b0d6 100644 --- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx +++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx @@ -31,11 +31,11 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc), OutputType outputFunct; result[0] = ComplexType( 25., 0.); - result[1] = ComplexType( 1., 18.); - result[2] = ComplexType(-11., 2.); - result[3] = ComplexType( 13., 0.); - result[4] = ComplexType( 1., 8.); - result[5] = ComplexType( 5., 0.); + result[1] = ComplexType( 25.4558441227157,-1.4142135623731); + result[2] = ComplexType( 11., -2.); + result[3] = ComplexType( 26., 0.); + result[4] = ComplexType( 11.3137084989848,-1.41421356237309); + result[5] = ComplexType( 5, .0); outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) ); @@ -46,6 +46,7 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc), vcl_abs(result[4]-outputFunct[4]) > 1e-10 || vcl_abs(result[5]-outputFunct[5]) > 1e-10 ) { + std::cout.precision(15); std::cout<<"Test gives :"<<std::endl; std::cout<<outputFunct<<std::endl; std::cout<<"Wanted results are :"<<std::endl; diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx index 36ee6b133758ed2d680afa01fe146a129352ee56..bdf3ce3a36542b1365b8e07eaf23700fef75be57 100644 --- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx +++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx @@ -32,10 +32,10 @@ int otbSinclairToReciprocalCovarianceMatrixFunctor(int itkNotUsed(argc), char * OutputType outputFunct; result[0] = ComplexType(17., 0.); - result[1] = ComplexType(14., 5.); + result[1] = ComplexType(19.7989898732233,7.07106781186548); result[2] = ComplexType(11., 10.); - result[3] = ComplexType(13., 0.); - result[4] = ComplexType(12., 5.); + result[3] = ComplexType(26., 0.); + result[4] = ComplexType(16.9705627484771,7.07106781186548); result[5] = ComplexType(13., 0.); outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) ); diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h index 2b5c5a7f4d7c5c2af5f873172a490d6ca4c1db68..9442c163080f9e2770395788828ccfacdee21dae 100644 --- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h +++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h @@ -264,6 +264,9 @@ public: m_Resampler->SetDisplacementFilterNumberOfThreads(nbThread); } + /** Override itk::ProcessObject method to let the internal filter do the propagation */ + virtual void PropagateRequestedRegion(itk::DataObject *output); + protected: GenericRSResampleImageFilter(); /** Destructor */ @@ -273,8 +276,6 @@ protected: virtual void GenerateOutputInformation(); - virtual void GenerateInputRequestedRegion(); - virtual void UpdateTransform(); void PrintSelf(std::ostream& os, itk::Indent indent) const; diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx index 42eedb9ba479812413b7fae52aacad766fc6a243..a18dabf09aa8fb846a47750566db9bc813af35b7 100644 --- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx +++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx @@ -67,7 +67,7 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage> progress->RegisterInternalFilter(m_Resampler, 1.f); m_Resampler->GraftOutput(this->GetOutput()); - m_Resampler->Update(); + m_Resampler->UpdateOutputData(m_Resampler->GetOutput()); this->GraftOutput(m_Resampler->GetOutput()); } @@ -82,20 +82,8 @@ void GenericRSResampleImageFilter<TInputImage, TOutputImage> ::GenerateOutputInformation() { - // call the superclass's implementation of this method - Superclass::GenerateOutputInformation(); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - outputPtr->SetSpacing( this->GetOutputSpacing() ); - outputPtr->SetOrigin( this->GetOutputOrigin() ); - - typename OutputImageType::RegionType region; - region.SetSize(this->GetOutputSize()); - region.SetIndex(this->GetOutputStartIndex() ); - - outputPtr->SetLargestPossibleRegion(region); - // Get the Output MetaData Dictionary itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary(); @@ -112,6 +100,13 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage> // Estimate the output rpc Model if needed if (m_EstimateOutputRpcModel) this->EstimateOutputRpcModel(); + + m_Resampler->SetInput(this->GetInput()); + m_Resampler->SetTransform(m_Transform); + m_Resampler->SetDisplacementFieldSpacing(this->GetDisplacementFieldSpacing()); + m_Resampler->GraftOutput(this->GetOutput()); + m_Resampler->UpdateOutputInformation(); + this->GraftOutput(m_Resampler->GetOutput()); } /** @@ -128,7 +123,11 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage> // Temp image : not allocated but with the same metadata than the // output typename OutputImageType::Pointer tempPtr = OutputImageType::New(); - tempPtr->SetRegions(this->GetOutput()->GetLargestPossibleRegion()); + + typename OutputImageType::RegionType region; + region.SetSize(this->GetOutputSize()); + region.SetIndex(this->GetOutputStartIndex() ); + tempPtr->SetRegions(region); // Encapsulate the output metadata in the temp image itk::MetaDataDictionary& tempDict = tempPtr->GetMetaDataDictionary(); @@ -171,41 +170,26 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage> m_Transform->InstanciateTransform(); } - /** - * Generate Input requested region does only propagate the output - * requested region. - */ - template <class TInputImage, class TOutputImage> - void - GenericRSResampleImageFilter<TInputImage, TOutputImage> - ::GenerateInputRequestedRegion() - { - // Retrieve output pointer - OutputImageType * outputPtr = this->GetOutput(); - - // Retrieve input pointer - const InputImageType * inputPtr = this->GetInput(); - - // Retrieve output requested region - RegionType requestedRegion = outputPtr->GetRequestedRegion(); - - // Estimate the input rpc model if it is needed - if (m_EstimateInputRpcModel && !m_RpcEstimationUpdated) - { - this->EstimateInputRpcModel(); - } - - // Instanciate the RS transform - this->UpdateTransform(); - - // Generate input requested region - m_Resampler->SetInput(inputPtr); - m_Resampler->SetTransform(m_Transform); - m_Resampler->SetDisplacementFieldSpacing(this->GetDisplacementFieldSpacing()); - m_Resampler->GetOutput()->UpdateOutputInformation(); - m_Resampler->GetOutput()->SetRequestedRegion(requestedRegion); - m_Resampler->GetOutput()->PropagateRequestedRegion(); - } +template <class TInputImage, class TOutputImage> +void +GenericRSResampleImageFilter<TInputImage, TOutputImage> +::PropagateRequestedRegion(itk::DataObject *output) +{ + if (this->m_Updating) return; + + // Estimate the input rpc model if it is needed + if (m_EstimateInputRpcModel && !m_RpcEstimationUpdated) + { + this->EstimateInputRpcModel(); + } + + // Instanciate the RS transform + this->UpdateTransform(); + + // Retrieve output requested region + m_Resampler->GetOutput()->SetRequestedRegion(output); + m_Resampler->GetOutput()->PropagateRequestedRegion(); +} /** diff --git a/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx b/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx index 32172e5b4ad969ae2859b0f251dff1a7db17942d..2a2a030b36e0fe027a133f51fb461646cbf4c93b 100644 --- a/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx +++ b/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx @@ -193,13 +193,13 @@ MDMDNMFImageFilter<TInputImage, TOutputImage> // = (A*S-X) * (transpose(S)) + m_LambdD*(A-1/nbBands*ones(L, L)*A) // = (A*S-X) * (transpose(S)) + m_LambdD*A- m_LambdD*/nbBands*ones(L, L)*A) - MatrixType onesA; VectorType sumColulmnsOfA; sumColulmnsOfA.set_size(A.cols()); unsigned int nbBands = A.rows(); - // Computing vector onesA - for (unsigned int j=0; j<onesA.size(); ++j) + // Computing ones*A : all rows are the same, + // (ones*A)[i,j] = sum(k=0 to nbBands, A[k,j]) + for (unsigned int j=0; j<A.cols(); ++j) { sumColulmnsOfA(j) = A.get_column(j).sum(); } diff --git a/Modules/Learning/LearningBase/include/otbSEMClassifier.txx b/Modules/Learning/LearningBase/include/otbSEMClassifier.txx index afe3461be635e80be725cacfb0aaa4ddeff2fe4a..b4ef42b3e8423882433e97aa0c13ad60311989c5 100644 --- a/Modules/Learning/LearningBase/include/otbSEMClassifier.txx +++ b/Modules/Learning/LearningBase/include/otbSEMClassifier.txx @@ -150,7 +150,7 @@ SEMClassifier<TInputImage, TOutputImage> else { otbMsgDebugMacro(<< "m_ClassLabels size = " << GetClassLabels().size() << " / m_Sample size = " << m_NbSamples); - throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size missmatch", ITK_LOCATION); + throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size mismatch", ITK_LOCATION); } } @@ -214,7 +214,7 @@ SEMClassifier<TInputImage, TOutputImage> otbMsgDebugMacro( << "m_ClassLabels size = " << GetClassLabels().size() << " size of the image = " << theSize << " / m_Sample size = " << m_NbSamples); - throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size missmatch", ITK_LOCATION); + throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size mismatch", ITK_LOCATION); } } @@ -264,7 +264,7 @@ SEMClassifier<TInputImage, TOutputImage> typename TInputImage::SizeType size = m_Sample->GetBufferedRegion().GetSize(); if ((size[0] * size[1]) != m_ClassLabels.size()) throw itk::ExceptionObject(__FILE__, __LINE__, - "Vector size missmatch", ITK_LOCATION); + "Vector size mismatch", ITK_LOCATION); } } @@ -315,7 +315,7 @@ SEMClassifier<TInputImage,TOutputImage> m_ComponentVector.clear(); m_ComponentVector.resize(this->GetNumberOfClasses()); m_ComponentDeclared = 0; - + } template <class TInputImage, class TOutputImage> @@ -353,7 +353,7 @@ SEMClassifier<TInputImage, TOutputImage> { //label = (int) floor( 0.5 + nbClassesDbl * ran / double(RAND_MAX+1) ); label = rand() % nbClasses; - if (label >= nbClasses) + if (label >= nbClasses) { label = nbClasses - 1; } diff --git a/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx b/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx index 4a08c8aca428b1a7a998f6ce20192c08807d20ab..efe218959c07b79c16d06361340e916908d9df80 100644 --- a/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx +++ b/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx @@ -70,7 +70,7 @@ ConfusionMatrixCalculator<TRefListLabel, TProdListLabel> { otbMsgDebugMacro(<< "refLabels size = " << m_ReferenceLabels->Size() << " / proLabels size = " << m_ProducedLabels->Size()); - throw itk::ExceptionObject(__FILE__, __LINE__, "ListSample size missmatch", ITK_LOCATION); + throw itk::ExceptionObject(__FILE__, __LINE__, "ListSample size mismatch", ITK_LOCATION); } m_NumberOfSamples = m_ReferenceLabels->Size(); diff --git a/SuperBuild/CMake/External_gdal.cmake b/SuperBuild/CMake/External_gdal.cmake index 7f501aad6459f5c5e7a089577f0170d6f8028e13..a76075af1adfc2996686a606df020c750f99f151 100644 --- a/SuperBuild/CMake/External_gdal.cmake +++ b/SuperBuild/CMake/External_gdal.cmake @@ -52,7 +52,7 @@ else() DOWNLOAD_DIR ${DOWNLOAD_LOCATION} DEPENDS ${${proj}_DEPENDENCIES} UPDATE_COMMAND ${CMAKE_COMMAND} -E copy_directory ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR} - PATCH_COMMAND ${CMAKE_COMMAND} -E touch ${GDAL_SB_SRC}/config.rpath COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/GDAL/GNUmakefile ${GDAL_SB_SRC}/swig/python/GNUmakefile + PATCH_COMMAND ${CMAKE_COMMAND} -E touch ${GDAL_SB_SRC}/config.rpath CONFIGURE_COMMAND # use 'env' because CTest launcher doesn't perform shell interpretation ${SB_ENV_CONFIGURE_CMD} @@ -86,7 +86,7 @@ else() INSTALL_DIR ${SB_INSTALL_PREFIX} DOWNLOAD_DIR ${DOWNLOAD_LOCATION} DEPENDS ${${proj}_DEPENDENCIES} - PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/GDAL/GNUmakefile ${GDAL_SB_SRC}/swig/python/GNUmakefile + PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR} CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/${proj}/ogrsqlitevirtualogr.cpp ${GDAL_SB_BUILD_DIR}/ogr/ogrsf_frmts/sqlite/ogrsqlitevirtualogr.cpp BUILD_COMMAND nmake /f ${GDAL_SB_BUILD_DIR}/makefile.vc MSVC_VER=${MSVC_VERSION} EXT_NMAKE_OPT=${CMAKE_BINARY_DIR}/nmake_gdal_extra.opt diff --git a/SuperBuild/patches/GDAL/GNUmakefile b/SuperBuild/patches/GDAL/GNUmakefile deleted file mode 100644 index c9d481886286983c42ca8e3dc6ad6aea7d3f0859..0000000000000000000000000000000000000000 --- a/SuperBuild/patches/GDAL/GNUmakefile +++ /dev/null @@ -1,95 +0,0 @@ - - -include ../../GDALmake.opt - -ifndef PYTHON - PYTHON=python -endif - -all: build - -BINDING = python -include ../SWIGmake.base - -PACKAGE_DIR=osgeo -SWIGOUTPUTDIR=extensions/ - -SCRIPTS = `ls ./scripts` -PY_COMMANDS = epsg_tr.py gdalchksum.py gdal2xyz.py gcps2wld.py \ - gdalimport.py gdal_merge.py pct2rgb.py rgb2pct.py \ - gcps2vec.py -PY_MODULES = ${PACKAGE_DIR}/gdal.py ${PACKAGE_DIR}/ogr.py ${PACKAGE_DIR}/osr.py ${PACKAGE_DIR}/gdalconst.py ${PACKAGE_DIR}/gdal_array.py - -clean: - -rm -f ${PACKAGE_DIR}/*.pyc - -rm -rf build - -rm -f *.pyc - -rm -rf *.egg-info - -rm -f *.so ./osgeo/*.so - -rm -rf dist - -SWIGARGS += -outdir "${PACKAGE_DIR}" - - -veryclean: clean - -rm -f ${WRAPPERS} ${PY_MODULES} - -rm -f ${SWIGOUTPUTDIR}/gdal_wrap.cpp - -rm -f ${SWIGOUTPUTDIR}/gdalconst_wrap.c - -rm -f ${SWIGOUTPUTDIR}/ogr_wrap.cpp - -rm -f ${SWIGOUTPUTDIR}/osr_wrap.cpp - -rm -f ${SWIGOUTPUTDIR}/gdal_array_wrap.cpp - -gdal_wrap.cpp: ../include/python/gdal_python.i - -ogr_wrap.cpp: ../include/python/ogr_python.i - -osr_wrap.cpp: ../include/python/osr_python.i - -gdal_array_wrap.cpp: ../include/gdal_array.i ../include/python/typemaps_python.i - $(SWIG) $(SWIGARGS) $(SWIGDEFINES) -I$(GDAL_ROOT) -c++ -$(BINDING) -o $(SWIGOUTPUTDIR)$@ gdal_array.i - -# A few hacks (cat, mv) : the first one for SWIG < 1.3.36 and the second one for SWIG <= 1.3.39 python 3.X on 64bit platforms -# The python3.2.patch is from https://sourceforge.net/tracker/?func=detail&aid=3057804&group_id=1645&atid=101645 -# and is no longer necessary with swig 2.0.4 -generate: ${WRAPPERS} gdal_array_wrap.cpp - for i in gdal_wrap.cpp gdalconst_wrap.c ogr_wrap.cpp osr_wrap.cpp gdal_array_wrap.cpp; do sed "s/PyErr_Format(PyExc_RuntimeError, mesg)/PyErr_SetString(PyExc_RuntimeError, mesg)/" ${SWIGOUTPUTDIR}/$$i | sed "s/int len;/Py_ssize_t len;/" > ${SWIGOUTPUTDIR}/$$i.tmp; mv -f ${SWIGOUTPUTDIR}/$$i.tmp ${SWIGOUTPUTDIR}/$$i; done - -grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && patch -p0 < python3.2.patch - -grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/ogr_wrap/" | patch -p0 - -grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/osr_wrap/" | patch -p0 - -grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap\.cpp/gdalconst_wrap\.c/" | patch -p0 - -grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/gdal_array_wrap/" | patch -p0 - -build: - $(PYTHON) setup.py build - -egg: - $(PYTHON) setup.py bdist_egg - -install: - -ifeq ($(PY_HAVE_SETUPTOOLS),1) - $(PYTHON) setup.py install -else - $(PYTHON) setup.py install --prefix=$(DESTDIR) --prefix=$(prefix) -endif - - for f in $(SCRIPTS) ; do $(INSTALL) ./scripts/$$f $(DESTDIR)$(INST_BIN) ; done - -docs: - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrlayer_8cpp.xml ../include/python/docs/ogr_layer_docs.i OGRLayerShadow OGR_L_ - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrgeometry_8cpp.xml ../include/python/docs/ogr_geometry_docs.i OGRGeometryShadow OGR_G_ - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrdatasource_8cpp.xml ../include/python/docs/ogr_datasource_docs.i OGRDataSourceShadow OGR_DS_ - - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrsfdriver_8cpp.xml ../include/python/docs/ogr_driver_docs.i OGRDriverShadow OGR_Dr_ - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfeature_8cpp.xml ../include/python/docs/ogr_feature_docs.i OGRFeatureShadow OGR_F_ - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfeaturedefn_8cpp.xml ../include/python/docs/ogr_featuredef_docs.i OGRFeatureDefnShadow OGR_FD_ - - $(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfielddefn_8cpp.xml ../include/python/docs/ogr_fielddef_docs.i OGRFieldDefnShadow OGR_Fld_ - -epydoc: generate - epydoc --config epydoc.conf