From b7b7f0338d4875771c9223de1f00fd24fafd2fda Mon Sep 17 00:00:00 2001 From: Julien Michel <julien.michel@c-s.fr> Date: Thu, 30 Nov 2006 12:02:57 +0000 Subject: [PATCH] Ajout du calcul des bounding box minimales. --- ...naryImageMinimalBoundingRegionCalculator.h | 90 +++++++++ ...ryImageMinimalBoundingRegionCalculator.txx | 174 ++++++++++++++++++ .../otbImageToImageRCC8Calculator.txx | 10 - Testing/Code/BasicFilters/CMakeLists.txt | 21 +++ .../BasicFilters/otbBasicFiltersTests.cxx | 2 + ...ryImageMinimalBoundingRegionCalculator.cxx | 94 ++++++++++ ...mageMinimalBoundingRegionCalculatorNew.cxx | 48 +++++ .../otbImageToImageRCC8Calculator.cxx | 1 + 8 files changed, 430 insertions(+), 10 deletions(-) create mode 100644 Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.h create mode 100644 Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.txx create mode 100644 Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.cxx create mode 100644 Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculatorNew.cxx diff --git a/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.h b/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.h new file mode 100644 index 0000000000..7d7a268be4 --- /dev/null +++ b/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.h @@ -0,0 +1,90 @@ +/*========================================================================= + + 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 _otbBinaryImageMinimalBoundingRegionCalculator_h +#define _otbBinaryImageMinimalBoundingRegionCalculator_h + +#include "itkImageToImageFilter.h" +#include "itkObjectFactory.h" + +namespace otb +{ +/** + * \class BinaryImageMinimalBoundingRegionCalculator + * \brief This class compute the smallest region of the image + * containing every pixel with the foreground value. + * + * This class is used for instance in the RCC8 calculator filter, + * where the input region used for computation has to be the smallest possible + * for costs reasons. The Pad flag allows the user to get a region 1 pixel larger + * at each bound in case a security margin has to be kept. + * + * \sa ImageToImageRCC8Calculator + */ +template <class TInputImage> +class BinaryImageMinimalBoundingRegionCalculator + : public itk::ImageToImageFilter<TInputImage,TInputImage> +{ +public: + /** Standard typedefs */ + typedef BinaryImageMinimalBoundingRegionCalculator Self; + typedef itk::ImageToImageFilter<TInputImage,TInputImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + /** Creation through object factory macro */ + itkNewMacro(Self); + /** Type macro */ + itkTypeMacro(BinaryImageMinimalBoundingRegionCalculator, ImageToImageFilter); + + typedef TInputImage InputImageType; + typedef typename InputImageType::PixelType PixelType; + typedef typename InputImageType::RegionType RegionType; + typedef typename InputImageType::Pointer InputImagePointerType; + /** Toogle the pad option */ + itkBooleanMacro(Pad); + itkGetMacro(Region,RegionType); + itkSetMacro(InsideValue,PixelType); + itkGetMacro(InsideValue,PixelType); + itkSetMacro(Pad,bool); + itkGetMacro(Pad,bool); + +protected: + /** Constructor */ + BinaryImageMinimalBoundingRegionCalculator(); + /** Destructor */ + virtual ~BinaryImageMinimalBoundingRegionCalculator() {}; + /** Main computation method */ + void GenerateData(void); + /** PrintSelf method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const; +private: + BinaryImageMinimalBoundingRegionCalculator(const Self&); // purposely not implemented + void operator=(const Self&); // purposely not implemented + /** The computed region */ + RegionType m_Region; + /** Toogle if pad wanted */ + bool m_Pad; + /** Inside value */ + PixelType m_InsideValue; +}; +} // End namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbBinaryImageMinimalBoundingRegionCalculator.txx" +#endif + +#endif diff --git a/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.txx b/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.txx new file mode 100644 index 0000000000..bd1a826d35 --- /dev/null +++ b/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.txx @@ -0,0 +1,174 @@ +/*========================================================================= + + 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 _otbBinaryImageMinimalBoundingRegionCalculator_txx +#define _otbBinaryImageMinimalBoundingRegionCalculator_txx + +#include "otbBinaryImageMinimalBoundingRegionCalculator.h" +#include "itkImageSliceConstIteratorWithIndex.h" +#include "otbMacro.h" + +namespace otb +{ +/* + * Constructor + */ +template <class TInputImage> +BinaryImageMinimalBoundingRegionCalculator<TInputImage> +::BinaryImageMinimalBoundingRegionCalculator() +{ + m_Pad=false; + typename InputImageType::SizeType size; + typename InputImageType::IndexType index; + size[0]=0; + size[1]=0; + index[0]=0; + index[1]=1; + m_Region.SetSize(size); + m_Region.SetIndex(index); + m_InsideValue=static_cast<PixelType>(255); +} +/** + * Main computation method + */ +template <class TInputImage> +void +BinaryImageMinimalBoundingRegionCalculator<TInputImage> +::GenerateData(void) +{ + // Input images pointers + const InputImageType* image = this->GetInput(); + // Iterator definition + typedef itk::ImageSliceConstIteratorWithIndex<InputImageType> SliceIteratorType; + // Indexes containing upper-left and lower-right corner + typename InputImageType::IndexType min; + typename InputImageType::IndexType max; + min[0]=0; + min[1]=0; + max[1]=0; + max[1]=0; + for ( unsigned int axis = 0; axis < InputImageType::ImageDimension; axis++ ) + { // Create the forward iterator to find lower bound + SliceIteratorType fit(image,image->GetLargestPossibleRegion()); + + fit.SetFirstDirection( !axis ); + fit.SetSecondDirection( axis ); + fit.GoToBegin(); +; + // Walk through the two images line by line + while (!fit.IsAtEnd()) + { + while (!fit.IsAtEndOfSlice()) + { + while(!fit.IsAtEndOfLine()) + { + // If a common intersection is found + if (fit.Get()==m_InsideValue) + { + // then the lower bound is found + min[axis]=fit.GetIndex()[axis]; + fit.GoToReverseBegin(); // skip to the end + break; + } + ++fit; + } + fit.NextLine(); + } + fit.NextSlice(); + } + // Create the reverse iterator to find upper bound + SliceIteratorType rit(image,image->GetLargestPossibleRegion()); + rit.SetFirstDirection(!axis); + rit.SetSecondDirection(axis); + rit.GoToReverseBegin(); + // Walk through the two images line by line + while (!rit.IsAtReverseEnd()) + { + while (!rit.IsAtReverseEndOfSlice()) + { + while (!rit.IsAtReverseEndOfLine()) + { + // If a common intersection is found + if (rit.Get()==m_InsideValue) + { + max[axis]=rit.GetIndex()[axis]; + rit.GoToBegin(); //Skip to reverse end + break; + } + --rit; + + } + rit.PreviousLine(); + + } + rit.PreviousSlice(); + } + } + otbMsgDebugMacro(<<"BinaryImageMinimalBoundingBoxCalculator: min "<<min); + otbMsgDebugMacro(<<"BinaryImageMinimalBoundingBoxCalculator: max "<<max); + typename InputImageType::SizeType size; + typename InputImageType::IndexType index; + RegionType maxRegion = image->GetLargestPossibleRegion(); + + if(m_Pad) + { + for(int i=0;i<InputImageType::ImageDimension;i++) + { + if(min[i]> maxRegion.GetIndex()[i]) + { + index[i]= min[i]-1; + } + else + { + index[i]= maxRegion.GetIndex()[i]; + } + if (index[i]+max[i]-min[i]+2<=maxRegion.GetIndex()[i]+maxRegion.GetSize()[i]) + { + size[i]=max[i]-min[i]+2; + } + else + { + size[i]=maxRegion.GetSize()[i]+maxRegion.GetIndex()[i] + -max[i]+min[i]-index[i]; + } + } + } + else + { + for(int i=0;i<InputImageType::ImageDimension;i++) + { + size[i]=max[i]-min[i]+1; + index[i]=min[i]; + } + } + m_Region.SetIndex(index); + m_Region.SetSize(size); +} +/** + * PrintSelf method + */ +template <class TInputImage> +void +BinaryImageMinimalBoundingRegionCalculator<TInputImage> +::PrintSelf( std::ostream& os,itk::Indent indent ) const + { + Superclass::PrintSelf(os,indent); + } + +} // End namespace otb + +#endif diff --git a/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx b/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx index 27ac2c8ef4..08e52a6e35 100644 --- a/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx +++ b/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx @@ -44,8 +44,6 @@ namespace otb m_Level1APrioriKnowledge=false; m_Level3APrioriKnowledge=false; this->SetNumberOfRequiredInputs(2); -// this->SetNumberOfOutputs(0); -// this->SetNumberOfRequiredOutputs(0); } /** * Set the first input image. @@ -103,7 +101,6 @@ namespace otb ImageToImageRCC8Calculator<TInputImage> ::GetValue(void) { - this->Update(); return m_Value; } /** @@ -531,13 +528,6 @@ ImageToImageRCC8Calculator<TInputImage> ::PrintSelf( std::ostream& os,itk::Indent indent ) const { Superclass::PrintSelf(os,indent); - - // os << indent << "RelationIndex: " - // << m_RelationIndex - // << std::endl; - // os << indent << "RelationName: " - // << m_RelationName - // << std::endl; } } // end namespace itk diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt index e6ac43de2c..785448aa8e 100755 --- a/Testing/Code/BasicFilters/CMakeLists.txt +++ b/Testing/Code/BasicFilters/CMakeLists.txt @@ -86,6 +86,25 @@ ADD_TEST(bfTvClosingOpeningFilter ${BASICFILTERS_TESTS} ${TEMP}/bfFiltreClosingOpening_1.tif 1) + +# ------- otb::BinaryImageMinimalBoundingRegionCalculator ---------------------------- + +ADD_TEST(bfTuBoundingRegionCalculatorNew ${BASICFILTERS_TESTS} + otbBinaryImageMinimalBoundingRegionCalculatorNew) + +ADD_TEST(bfTvBoundingRegionCalculator ${BASICFILTERS_TESTS} + --compare-ascii ${TOL} + ${BASELINE_FILES}/bfBoundingRegionCalculatorOutput.txt + ${TEMP}/bfBoundingRegionCalculatorOutput.txt + otbBinaryImageMinimalBoundingRegionCalculator + 4 + ${TEMP}/bfBoundingRegionCalculatorOutput.txt + ${INPUTDATA}/rcc8_mire1.png + ${INPUTDATA}/rcc8_mire2.png + ${INPUTDATA}/rcc8_mire3.png + ${INPUTDATA}/rcc8_mire4.png + ) + # A enrichir SET(BasicFilters_SRCS otbLeeFilter.cxx @@ -99,6 +118,8 @@ otbOpeningClosingMorphologicalFilterNew.cxx otbOpeningClosingMorphologicalFilter.cxx otbClosingOpeningMorphologicalFilterNew.cxx otbClosingOpeningMorphologicalFilter.cxx +otbBinaryImageMinimalBoundingRegionCalculatorNew.cxx +otbBinaryImageMinimalBoundingRegionCalculator.cxx ) diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx index 08e590f765..a124fa8a1f 100755 --- a/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx +++ b/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx @@ -38,4 +38,6 @@ REGISTER_TEST(otbOpeningClosingMorphologicalFilterNew); REGISTER_TEST(otbOpeningClosingMorphologicalFilter); REGISTER_TEST(otbClosingOpeningMorphologicalFilterNew); REGISTER_TEST(otbClosingOpeningMorphologicalFilter); +REGISTER_TEST(otbBinaryImageMinimalBoundingRegionCalculatorNew); +REGISTER_TEST(otbBinaryImageMinimalBoundingRegionCalculator); } diff --git a/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.cxx b/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.cxx new file mode 100644 index 0000000000..6eb794571e --- /dev/null +++ b/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculator.cxx @@ -0,0 +1,94 @@ +/*========================================================================= + + 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 "itkExceptionObject.h" +#include "otbImage.h" +#include "otbBinaryImageMinimalBoundingRegionCalculator.h" +#include "otbImageFileReader.h" +#include "otbImageList.h" + +int otbBinaryImageMinimalBoundingRegionCalculator(int argc, char* argv[]) +{ +try + { + const unsigned int Dimension = 2; + + int nbImages = atoi(argv[1]); + char * outfile = argv[2]; + + typedef unsigned char PixelType; + typedef otb::Image<PixelType,Dimension> ImageType; + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef otb::BinaryImageMinimalBoundingRegionCalculator<ImageType> + BoundingRegionCalculatorType; + typedef BoundingRegionCalculatorType::RegionType RegionType; + typedef otb::ImageList<ImageType> ImageListType; + typedef ImageListType::Iterator IteratorType; + // reference image list + ImageListType::Pointer images = ImageListType::New(); + + // Reading input images + std::ofstream out; + out.open(outfile,std::ios::out); + out<<"Test results from otbBinaryImageBoundingRegionCalculator test."<<std::endl; + for(int i=1;i<=nbImages;++i) + { + ReaderType::Pointer reader = ReaderType::New(); + out<<argv[2+i]<<std::endl; + reader->SetFileName(argv[2+i]); + reader->Update(); + images->PushBack(reader->GetOutput()); + } + out<<std::endl; + + // Declaration + BoundingRegionCalculatorType::Pointer brct; + // Computing bounding region for each image + for(IteratorType it=images->Begin();it!=images->End();++it) + { + brct = BoundingRegionCalculatorType::New(); + brct->SetInput(it.Get()); + brct->Update(); + RegionType region = brct->GetRegion(); + out<<region.GetIndex()<<"\t"<<region.GetSize()<<std::endl; + } + out<<std::endl<<"Testing the pad option"<<std::endl<<std::endl; +for(IteratorType it=images->Begin();it!=images->End();++it) + { + brct = BoundingRegionCalculatorType::New(); + brct->SetPad(true); + brct->SetInput(it.Get()); + brct->Update(); + RegionType region = brct->GetRegion(); + out<<region.GetIndex()<<"\t"<<region.GetSize()<<std::endl; + } + + out.close(); + } + catch( itk::ExceptionObject & err ) + { + std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "Unknown exception thrown !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculatorNew.cxx b/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculatorNew.cxx new file mode 100644 index 0000000000..bf851d2d9c --- /dev/null +++ b/Testing/Code/BasicFilters/otbBinaryImageMinimalBoundingRegionCalculatorNew.cxx @@ -0,0 +1,48 @@ +/*========================================================================= + + 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 "itkExceptionObject.h" +#include "otbImage.h" +#include "otbBinaryImageMinimalBoundingRegionCalculator.h" + +int otbBinaryImageMinimalBoundingRegionCalculatorNew(int argc, char* argv[]) +{ +try + { + const unsigned int Dimension = 2; + + typedef unsigned char PixelType; + typedef otb::Image<PixelType,Dimension> ImageType; + typedef otb::BinaryImageMinimalBoundingRegionCalculator<ImageType> + BoundingRegionCalculatorType; + + //Instantiation + BoundingRegionCalculatorType::Pointer brct = BoundingRegionCalculatorType::New(); + } + catch( itk::ExceptionObject & err ) + { + std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "Unknown exception thrown !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/Testing/Code/SpatialReasoning/otbImageToImageRCC8Calculator.cxx b/Testing/Code/SpatialReasoning/otbImageToImageRCC8Calculator.cxx index bba223dfa0..7c603738dc 100644 --- a/Testing/Code/SpatialReasoning/otbImageToImageRCC8Calculator.cxx +++ b/Testing/Code/SpatialReasoning/otbImageToImageRCC8Calculator.cxx @@ -65,6 +65,7 @@ try calc=CalculatorType::New(); calc->SetInput1(it1.Get()); calc->SetInput2(it2.Get()); + calc->Update(); out<<calc->GetValue()<<"\t"; j++; } -- GitLab