diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h index a683793f7708a904dd6997780ee0a9555212de0f..50994bed1ee02aa82eb5d257ecbe3e1935516ab4 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h @@ -26,6 +26,8 @@ #include "otbPersistentImageFilter.h" #include "otbPersistentFilterStreamingDecorator.h" #include "otbPersistentImageToOGRDataFilter.h" +#include "otbRelabelComponentImageFilter.h" +#include "itkMultiplyImageFilter.h" #include "otbMeanShiftImageFilter.h" #include "otbMeanShiftImageFilter2.h" @@ -115,6 +117,9 @@ public: typedef typename Superclass::OGRDataSourceType OGRDataSourceType; typedef typename Superclass::OGRDataSourcePointerType OGRDataSourcePointerType; typedef typename Superclass::OGRLayerType OGRLayerType; + + typedef RelabelComponentImageFilter<LabelImageType,LabelImageType> RelabelComponentImageFilterType; + typedef itk::MultiplyImageFilter<LabelImageType,LabelImageType,LabelImageType> MultiplyImageFilterType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -134,6 +139,12 @@ public: itkSetMacro(Use8Connected, bool); itkGetMacro(Use8Connected, bool); + itkSetMacro(FilterSmallObject, bool); + itkGetMacro(FilterSmallObject, bool); + + itkSetMacro(MinimumObjectSize, unsigned int); + itkGetMacro(MinimumObjectSize, unsigned int); + virtual void SetInputMask(const LabelImageType *mask); virtual const LabelImageType * GetInputMask(void); @@ -157,6 +168,8 @@ private: unsigned int m_TileNumber; bool m_Use8Connected; + bool m_FilterSmallObject; + unsigned int m_MinimumObjectSize; }; @@ -257,6 +270,26 @@ public: return this->GetFilter()->GetUse8Connected(); } + void SetFilterSmallObject(bool flag) + { + this->GetFilter()->SetFilterSmallObject(flag); + } + + const bool GetFilterSmallObject() + { + return this->GetFilter()->GetFilterSmallObject(); + } + + void SetMinimumObjectSize(const unsigned int & size) + { + this->GetFilter()->SetMinimumObjectSize(size); + } + + const unsigned int GetMinimumObjectSize() + { + return this->GetFilter()->GetMinimumObjectSize(); + } + protected: /** Constructor */ StreamingVectorizedSegmentationOGR() {} diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx index 2b118fff6f781961a36f751c4ccc1ed2486fd2d9..2de3d903e8f780242057d16c5d45b69b3c6eecfc 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx @@ -33,7 +33,8 @@ namespace otb template <class TImageType, class TSegmentationFilter> PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> -::PersistentStreamingLabelImageToOGRDataFilter() : m_TileMaxLabel(0), m_StartLabel(0), m_Use8Connected(false) +::PersistentStreamingLabelImageToOGRDataFilter() : m_TileMaxLabel(0), m_StartLabel(0), m_Use8Connected(false), + m_FilterSmallObject(false), m_MinimumObjectSize(1) { this->SetNumberOfInputs(3); this->SetNumberOfRequiredInputs(2); @@ -111,6 +112,16 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> chrono1.Stop(); std::cout<< "segmentation took " << chrono1.GetTotal() << " sec"<<std::endl; + //RelabelComponentImageFilter to suppress small area + typename RelabelComponentImageFilterType::Pointer relabelComponentFilter = RelabelComponentImageFilterType::New(); + if(m_FilterSmallObject) + { + relabelComponentFilter->SetInput(dynamic_cast<LabelImageType *>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer())); + relabelComponentFilter->SetMinimumObjectSize(m_MinimumObjectSize); + relabelComponentFilter->Update(); + + labelImageToOGRDataFilter->SetInputMask(relabelComponentFilter->GetOutput()); + } itk::TimeProbe chrono2; chrono2.Start(); @@ -128,7 +139,18 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> // WARNING: itk::ExtractImageFilter does not copy the MetadataDictionnary maskExtract->GetOutput()->SetMetaDataDictionary(this->GetInputMask()->GetMetaDataDictionary()); - labelImageToOGRDataFilter->SetInputMask(maskExtract->GetOutput()); + if(m_FilterSmallObject) + { + typename MultiplyImageFilterType::Pointer multiplyImageFilter = MultiplyImageFilterType::New(); + multiplyImageFilter->SetInput1(maskExtract->GetOutput()); + multiplyImageFilter->SetInput2(relabelComponentFilter->GetOutput()); + multiplyImageFilter->Update(); + labelImageToOGRDataFilter->SetInputMask(multiplyImageFilter->GetOutput()); + } + else + { + labelImageToOGRDataFilter->SetInputMask(maskExtract->GetOutput()); + } } labelImageToOGRDataFilter->SetInput(dynamic_cast<LabelImageType *>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer())); labelImageToOGRDataFilter->SetFieldName(this->GetFieldName()); diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt index 8507eb866796f03eb710faad062a18d0fccc2e3f..802c357d7e18998906c1c9e03ecc42af73f2010a 100644 --- a/Testing/Code/OBIA/CMakeLists.txt +++ b/Testing/Code/OBIA/CMakeLists.txt @@ -258,6 +258,8 @@ ADD_TEST(obTvStreamingVectorizedSegmentationOGR ${OBIA_TESTS1} 5 15. 100 + 0 #filter small object + 200 #minimum size of object ) # ------- otb::FusionOGRTileFilter ------------- diff --git a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx index 857f1d2cf9efdfe3fd337d8632b55fc21cd49161..bf0dd0344a2a83979b0799ac309b629a8936c929 100644 --- a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx +++ b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx @@ -49,10 +49,10 @@ int otbStreamingVectorizedSegmentationOGRNew(int argc, char * argv[]) int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) { - if (argc != 9) + if (argc != 11) { std::cerr << "Usage: " << argv[0]; - std::cerr << " inputImage maskImage outputVec layerName TileDimension spatialRadius rangeRadius minObjectSize" << std::endl; + std::cerr << " inputImage maskImage outputVec layerName TileDimension spatialRadius rangeRadius minObjectSize filterSmallObj minSize" << std::endl; return EXIT_FAILURE; } @@ -64,6 +64,8 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) const unsigned int spatialRadiusOldMS = atoi(argv[6]); const double rangeRadiusOldMS = atof(argv[7]); const unsigned int minimumObjectSizeOldMS = atoi(argv[8]); + const bool filterSmallObj = atoi(argv[9]); + const unsigned int minSize = atoi(argv[10]); typedef float InputPixelType; @@ -93,7 +95,7 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write); filter->SetInput(reader->GetOutput()); - filter->SetInputMask(maskReader->GetOutput()); + //filter->SetInputMask(maskReader->GetOutput()); filter->SetOGRDataSource(ogrDS); //filter->GetStreamer()->SetNumberOfLinesStrippedStreaming(atoi(argv[3])); filter->GetStreamer()->SetTileDimensionTiledStreaming(tileSize); @@ -101,6 +103,8 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) filter->SetFieldName(fieldName); filter->SetStartLabel(1); filter->SetUse8Connected(false); + filter->SetFilterSmallObject(filterSmallObj); + filter->SetMinimumObjectSize(minSize); filter->GetSegmentationFilter()->SetSpatialRadius(spatialRadiusOldMS); filter->GetSegmentationFilter()->SetRangeRadius(rangeRadiusOldMS); filter->GetSegmentationFilter()->SetMinimumRegionSize(minimumObjectSizeOldMS);