From 592b8a3e455b6670a4c39102baa5117f74f1ec15 Mon Sep 17 00:00:00 2001 From: Cyrille Valladeau <cyrille.valladeau@c-s.fr> Date: Tue, 10 Mar 2009 13:32:31 +0100 Subject: [PATCH] ENH : change in edge detection --- .../otbBinaryImageDensityFunction.h | 46 +++--- .../otbBinaryImageDensityFunction.txx | 9 +- .../otbBinaryImageToDensityImageFilter.h | 21 ++- .../otbBinaryImageToDensityImageFilter.txx | 133 ++++++++++++++---- Code/BasicFilters/otbEdgeDensityImageFilter.h | 14 +- .../otbEdgeDensityImageFilter.txx | 54 ++----- 6 files changed, 168 insertions(+), 109 deletions(-) diff --git a/Code/BasicFilters/otbBinaryImageDensityFunction.h b/Code/BasicFilters/otbBinaryImageDensityFunction.h index bff63bbaa8..9dd890d564 100644 --- a/Code/BasicFilters/otbBinaryImageDensityFunction.h +++ b/Code/BasicFilters/otbBinaryImageDensityFunction.h @@ -45,38 +45,29 @@ template <class TInputImage, class TCoordRep = float > class ITK_EXPORT BinaryImageDensityFunction : public itk::ImageFunction< TInputImage, typename itk::NumericTraits<typename TInputImage::PixelType>::RealType,TCoordRep > { -public: + public: /** Standard class typedefs. */ typedef BinaryImageDensityFunction Self; typedef itk::ImageFunction<TInputImage,typename itk::NumericTraits<typename TInputImage::PixelType>::RealType, - TCoordRep > Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; + TCoordRep > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(BinaryImageDensityFunction, itk::ImageFunction); - + /** Method for creation through the object factory. */ itkNewMacro(Self); - - /** InputImageType typedef support. */ - typedef TInputImage InputImageType; - - /** OutputType typdef support. */ - typedef typename Superclass::OutputType OutputType; - - /** Index typedef support. */ - typedef typename Superclass::IndexType IndexType; - /** ContinuousIndex typedef support. */ + /** InputImageType typedef support. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::SizeType RadiusType; + typedef typename Superclass::OutputType OutputType; + typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; - - /** Point typedef support. */ - typedef typename Superclass::PointType PointType; - - /** Dimension of the underlying image. */ -itkStaticConstMacro(ImageDimension, unsigned int, - InputImageType::ImageDimension); + typedef typename Superclass::PointType PointType; + + itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension); /** Datatype used for the density */ typedef typename itk::NumericTraits<typename InputImageType::PixelType>::RealType @@ -102,8 +93,13 @@ itkStaticConstMacro(ImageDimension, unsigned int, /** Get/Set the radius of the neighborhood over which the statistics are evaluated */ - itkSetMacro( NeighborhoodRadius, unsigned int ); - itkGetConstReferenceMacro( NeighborhoodRadius, unsigned int ); + itkSetMacro( NeighborhoodRadius, RadiusType ); + itkGetConstReferenceMacro( NeighborhoodRadius, RadiusType ); + void SetNeighborhoodRadius(unsigned int rad) + { + m_NeighborhoodRadius.Fill( rad ); + this->Modified(); + } protected: @@ -115,7 +111,7 @@ private: BinaryImageDensityFunction( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented - unsigned int m_NeighborhoodRadius; + RadiusType m_NeighborhoodRadius; }; diff --git a/Code/BasicFilters/otbBinaryImageDensityFunction.txx b/Code/BasicFilters/otbBinaryImageDensityFunction.txx index faabc4abc3..6a992cc5d3 100644 --- a/Code/BasicFilters/otbBinaryImageDensityFunction.txx +++ b/Code/BasicFilters/otbBinaryImageDensityFunction.txx @@ -35,7 +35,7 @@ template <class TInputImage, class TCoordRep> BinaryImageDensityFunction<TInputImage,TCoordRep> ::BinaryImageDensityFunction() { - m_NeighborhoodRadius = 1; + m_NeighborhoodRadius.Fill( 1 ); } @@ -77,11 +77,10 @@ BinaryImageDensityFunction<TInputImage,TCoordRep> } // Create an N-d neighborhood kernel, using a zeroflux boundary condition - typename InputImageType::SizeType kernelSize; - kernelSize.Fill( m_NeighborhoodRadius ); - + typename InputImageType::SizeType kernelSize = m_NeighborhoodRadius; + itk::ConstNeighborhoodIterator<InputImageType> - it(kernelSize, this->GetInputImage(), this->GetInputImage()->GetBufferedRegion()); + it(kernelSize, this->GetInputImage(), this->GetInputImage()->GetBufferedRegion()); // Set the iterator at the desired location it.SetLocation(index); diff --git a/Code/BasicFilters/otbBinaryImageToDensityImageFilter.h b/Code/BasicFilters/otbBinaryImageToDensityImageFilter.h index b8abde1511..6e9564f4ce 100644 --- a/Code/BasicFilters/otbBinaryImageToDensityImageFilter.h +++ b/Code/BasicFilters/otbBinaryImageToDensityImageFilter.h @@ -20,6 +20,8 @@ #include "itkImageToImageFilter.h" #include "itkDataObject.h" +#include "itkConstNeighborhoodIterator.h" + namespace otb { @@ -48,6 +50,7 @@ public: typedef TInputImage InputImageType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::Pointer InputImagePointerType; + typedef typename InputImageType::SizeType InputImageSizeType; typedef TOutputImage OutputImageType; typedef typename OutputImageType::Pointer OutputImagePointerType; @@ -55,16 +58,24 @@ public: typedef TCountFunction CountFunctionType; typedef typename CountFunctionType::Pointer CountFunctionPointerType; + typedef itk::ConstNeighborhoodIterator<TInputImage> NeighborhoodIteratorType; + typedef typename NeighborhoodIteratorType::RadiusType RadiusType; + /** Shrink factor accessor */ - itkSetMacro(NeighborhoodRadius,unsigned int); - itkGetMacro(NeighborhoodRadius, unsigned int); + itkSetMacro(NeighborhoodRadius, RadiusType); + itkGetMacro(NeighborhoodRadius, RadiusType); + void SetNeighborhoodRadius(unsigned int rad) + { + m_NeighborhoodRadius.Fill(rad); + this->Modified(); + } /** Main computation method */ - virtual void ThreadedGenerateData( const InputImageRegionType &outputRegionForThread, int threadId ) ; - + virtual void BeforeThreadedGenerateData(); + virtual void GenerateInputRequestedRegion(); protected: /** Constructor */ @@ -81,7 +92,7 @@ private: CountFunctionPointerType m_CountFunction; /** The shrink factor */ - unsigned int m_NeighborhoodRadius; + RadiusType m_NeighborhoodRadius; }; } // End namespace otb diff --git a/Code/BasicFilters/otbBinaryImageToDensityImageFilter.txx b/Code/BasicFilters/otbBinaryImageToDensityImageFilter.txx index 2a95dd2579..75691fe081 100644 --- a/Code/BasicFilters/otbBinaryImageToDensityImageFilter.txx +++ b/Code/BasicFilters/otbBinaryImageToDensityImageFilter.txx @@ -20,7 +20,12 @@ #include "otbBinaryImageToDensityImageFilter.h" #include "itkImageRegionIterator.h" -#include "itkImageRegionConstIterator.h" +//#include "itkImageRegionConstIterator.h" +#include "itkProgressReporter.h" +#include "otbMirrorBoundaryCondition.h" +#include "itkZeroFluxNeumannBoundaryCondition.h" +#include "itkNeighborhoodAlgorithm.h" + #include "otbMacro.h" namespace otb @@ -30,11 +35,10 @@ template <class TInputImage, class TOutputImage, class TCountFunction> BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> ::BinaryImageToDensityImageFilter() { - m_NeighborhoodRadius = 1; - + m_NeighborhoodRadius.Fill( 1 ); m_CountFunction = CountFunctionType::New(); - } + /** Destructor */ template <class TInputImage, class TOutputImage, class TCountFunction> BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> @@ -42,39 +46,119 @@ BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> {} +template <class TInputImage, class TOutputImage, class TCountFunction> +void +BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> +::GenerateInputRequestedRegion() +{ + // call the superclass' implementation of this method + Superclass::GenerateInputRequestedRegion(); + + // get pointers to the input and output + InputImagePointerType inputPtr = const_cast< TInputImage * >( this->GetInput()); + OutputImagePointerType outputPtr = this->GetOutput(); + + if ( !inputPtr || !outputPtr ) + { + return; + } + // get a copy of the input requested region (should equal the output + // requested region) + InputImageRegionType inputRequestedRegion = inputPtr->GetRequestedRegion(); + + // pad the input requested region by the operator radius + inputRequestedRegion.PadByRadius( m_NeighborhoodRadius ); + + // crop the input requested region at the input's largest possible region + if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) + { + inputPtr->SetRequestedRegion( inputRequestedRegion ); + return; + } + else + { + // Couldn't crop the region (requested region is outside the largest + // possible region). Throw an exception. + + // store what we tried to request (prior to trying to crop) + inputPtr->SetRequestedRegion( inputRequestedRegion ); + + // build an exception + itk::InvalidRequestedRegionError e(__FILE__, __LINE__); + itk::OStringStream msg; + msg << this->GetNameOfClass() + << "::GenerateInputRequestedRegion()"; + e.SetLocation(msg.str().c_str()); + e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + e.SetDataObject(inputPtr); + throw e; + } +} + +template <class TInputImage, class TOutputImage, class TCountFunction> +void +BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> +::BeforeThreadedGenerateData() +{ + Superclass::BeforeThreadedGenerateData(); + + m_CountFunction->SetInputImage(this->GetInput()); + m_CountFunction->SetNeighborhoodRadius(m_NeighborhoodRadius); +} + + /** Main computation method */ template <class TInputImage, class TOutputImage, class TCountFunction> void BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> ::ThreadedGenerateData( const InputImageRegionType &outputRegionForThread, int threadId ) { - - InputImagePointerType input = const_cast<InputImageType * > (this->GetInput()); - OutputImagePointerType output = this->GetOutput(); + InputImagePointerType inputPtr = const_cast<InputImageType * > (this->GetInput()); + OutputImagePointerType outputPtr = this->GetOutput(); - m_CountFunction->SetInputImage(input); + itk::ZeroFluxNeumannBoundaryCondition<TInputImage> nbc; + RadiusType r; + r[0]=m_NeighborhoodRadius[0]; + r[1]=m_NeighborhoodRadius[1]; - itk::ImageRegionConstIterator<InputImageType> it(input,outputRegionForThread ); - itk::ImageRegionIterator<OutputImageType> itOut(output,outputRegionForThread ); - - it.GoToBegin(); - itOut.GoToBegin(); - - while(!it.IsAtEnd()) - { - m_CountFunction->SetNeighborhoodRadius(m_NeighborhoodRadius); - typename InputImageType::IndexType index = it.GetIndex(); + NeighborhoodIteratorType it; + typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType faceList; + typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage> bC; + faceList = bC(inputPtr, outputRegionForThread, r); + typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType::iterator fit; + + itk::ImageRegionIterator<OutputImageType> itOut(outputPtr,outputRegionForThread ); + + itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + + typename InputImageType::IndexType index; + + for (fit=faceList.begin(); fit != faceList.end(); ++fit) + { + it = itk::ConstNeighborhoodIterator<TInputImage>(r, inputPtr, *fit); + + itOut = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit); + it.OverrideBoundaryCondition(&nbc); + it.GoToBegin(); - if(outputRegionForThread.IsInside(index)) + while(!itOut.IsAtEnd()) { - itOut.Set(m_CountFunction->EvaluateAtIndex(index)); + index = it.GetIndex(); + + if(outputRegionForThread.IsInside(index)) + { + itOut.Set(m_CountFunction->EvaluateAtIndex(index)); + } + + ++itOut; + ++it; + progress.CompletedPixel(); // potential exception thrown here } - - ++itOut; - ++it; } } + /** PrintSelf method */ template <class TInputImage, class TOutputImage, class TCountFunction> void @@ -82,8 +166,7 @@ BinaryImageToDensityImageFilter<TInputImage, TOutputImage, TCountFunction> ::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os,indent); - os << indent << "Neighborhood Radius : " << m_NeighborhoodRadius - << std::endl; + os << indent << "Neighborhood Radius : " << m_NeighborhoodRadius << std::endl; } } // End namespace otb #endif diff --git a/Code/BasicFilters/otbEdgeDensityImageFilter.h b/Code/BasicFilters/otbEdgeDensityImageFilter.h index d56fa7945a..0f8e34e9c0 100644 --- a/Code/BasicFilters/otbEdgeDensityImageFilter.h +++ b/Code/BasicFilters/otbEdgeDensityImageFilter.h @@ -85,10 +85,11 @@ public: itkSetMacro( NeighborhoodRadius, unsigned int ); itkGetConstReferenceMacro( NeighborhoodRadius, unsigned int ); + /**Set/Get detector */ + itkSetObjectMacro(Detector, DetectorType); + itkGetObjectMacro(Detector, DetectorType); + itkGetObjectMacro(DensityImageFilter, DensityImageType); - /**Set/Get Descriptor from the otbCountmageFunction*/ - virtual void SetDetector(DetectorType* detector); - virtual DetectorType* GetDetector(); protected: @@ -107,7 +108,6 @@ protected: /** * Main computation method. */ - //virtual void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); virtual void GenerateData( ); private: @@ -115,9 +115,9 @@ private: EdgeDensityImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented - DetectorPointerType m_Detector; - DensityImagePointerType m_DensityImageFilter; - unsigned int m_NeighborhoodRadius; + DetectorPointerType m_Detector; + DensityImagePointerType m_DensityImageFilter; + unsigned int m_NeighborhoodRadius; }; } #ifndef OTB_MANUAL_INSTANTIATION diff --git a/Code/BasicFilters/otbEdgeDensityImageFilter.txx b/Code/BasicFilters/otbEdgeDensityImageFilter.txx index bef73b4e34..e32dcb8526 100644 --- a/Code/BasicFilters/otbEdgeDensityImageFilter.txx +++ b/Code/BasicFilters/otbEdgeDensityImageFilter.txx @@ -29,7 +29,7 @@ namespace otb template <class TInputImage , class TOutputImage, class TEdgeDetector, class TDensityCount> EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> ::EdgeDensityImageFilter() -{ +{ this->SetNumberOfRequiredInputs( 1 ); m_NeighborhoodRadius = 1; @@ -46,65 +46,35 @@ EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> ::~EdgeDensityImageFilter() {} + /** * threaded Generate Data */ - -/** -* ThreadedGenerateData Performs the pixel-wise addition -*/ template <class TInputImage , class TOutputImage, class TEdgeDetector, class TDensityCount> void EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> ::GenerateData() - //::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId ) { - typename Superclass::OutputImagePointer outputImage = this->GetOutput(); - InputImagePointerType ptr = const_cast<InputImageType *>(this->GetInput()); - if (!ptr) - return ; + m_Detector->SetInput( this->GetInput() ); - /** Apply Canny Detector*/ - m_Detector->SetInput(ptr); - + std::cout<<"###"<<this->GetInput()->GetLargestPossibleRegion()<<std::endl; + m_Detector->Update(); + m_Detector->UpdateOutputInformation(); + //m_Detector->SetRequestedRegionToLargestPossibleRegion(); + std::cout<<"~~~"<<m_Detector->GetOutput()->GetLargestPossibleRegion()<<std::endl; - /** Compute density on the binaruzed Image */ - m_DensityImageFilter->SetInput(m_Detector->GetOutput()); m_DensityImageFilter->SetNeighborhoodRadius(m_NeighborhoodRadius); + m_DensityImageFilter->SetInput(m_Detector->GetOutput()); + + m_DensityImageFilter->UpdateOutputInformation(); + std::cout<<"***"<<m_DensityImageFilter->GetOutput()->GetLargestPossibleRegion()<<std::endl; - /** updating the output*/ m_DensityImageFilter->GraftOutput(this->GetOutput()); m_DensityImageFilter->Update(); this->GraftOutput(m_DensityImageFilter->GetOutput()); } -/** - * Set Detector - */ -template <class TInputImage , class TOutputImage, class TEdgeDetector, class TDensityCount> -void -EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> -::SetDetector(DetectorType* detector) -{ - m_Detector = detector; -} - - -/** - * Get Detector - */ -template <class TInputImage , class TOutputImage, class TEdgeDetector, class TDensityCount> -typename EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> -::DetectorType * -EdgeDensityImageFilter<TInputImage, TOutputImage, TEdgeDetector, TDensityCount> -::GetDetector() -{ - return m_Detector; -} - - - /*---------------------------------------------------------------- PrintSelf -----------------------------------------------------------------*/ -- GitLab