diff --git a/Code/FeatureExtraction/otbLocalHistogramImageFunction.h b/Code/FeatureExtraction/otbLocalHistogramImageFunction.h index 747315729ef0fffbbf26d69ed52c8493615b5a5c..3989b474c32ed27906d96cea3922baa5ef82fccc 100644 --- a/Code/FeatureExtraction/otbLocalHistogramImageFunction.h +++ b/Code/FeatureExtraction/otbLocalHistogramImageFunction.h @@ -20,7 +20,7 @@ #include "itkImageFunction.h" #include "itkFixedArray.h" -#include "itkScalarImageToHistogramGenerator.h" +#include "itkHistogram.h" #include "itkNumericTraits.h" namespace otb @@ -40,14 +40,14 @@ namespace otb template <class TInputImage, class TCoordRep = double > class ITK_EXPORT LocalHistogramImageFunction : public itk::ImageFunction< TInputImage, - typename itk::Statistics::ScalarImageToHistogramGenerator<TInputImage>::HistogramConstPointer, + typename itk::Statistics::Histogram<typename TInputImage::PixelType>::Pointer, TCoordRep > { public: /** Standard class typedefs. */ typedef LocalHistogramImageFunction Self; typedef itk::ImageFunction< TInputImage, - typename itk::Statistics::ScalarImageToHistogramGenerator<TInputImage>::HistogramConstPointer, + typename itk::Statistics::Histogram<typename TInputImage::PixelType>::Pointer, TCoordRep > Superclass; typedef itk::SmartPointer<Self> Pointer; typedef itk::SmartPointer<const Self> ConstPointer; @@ -65,11 +65,8 @@ public: typedef typename Superclass::PointType PointType; typedef typename Superclass::OutputType OutputType; - typedef itk::Statistics::ScalarImageToHistogramGenerator<TInputImage> HistogramGeneratorType; - typedef typename HistogramGeneratorType::GeneratorType GeneratorType; - typedef typename GeneratorType::HistogramType HistogramType; - typedef typename HistogramType::Pointer HistogramPointer; - typedef typename GeneratorType::Pointer GeneratorPointer; + typedef itk::Statistics::Histogram<typename TInputImage::PixelType> HistogramType; + typedef typename HistogramType::Pointer HistogramPointer; /** Dimension of the underlying image. */ itkStaticConstMacro(ImageDimension, unsigned int, diff --git a/Code/FeatureExtraction/otbLocalHistogramImageFunction.txx b/Code/FeatureExtraction/otbLocalHistogramImageFunction.txx index 4d45866ffd87dfb970039959398632b76e362a9c..4af8fe109c0839e39e1d7dedfb8894fcc9f4034c 100644 --- a/Code/FeatureExtraction/otbLocalHistogramImageFunction.txx +++ b/Code/FeatureExtraction/otbLocalHistogramImageFunction.txx @@ -19,7 +19,6 @@ #define __otbLocalHistogramImageFunction_txx #include "otbLocalHistogramImageFunction.h" -#include "itkImageToHistogramGenerator.h" #include "itkConstNeighborhoodIterator.h" #include "itkNumericTraits.h" #include "itkMacro.h" @@ -55,27 +54,37 @@ typename LocalHistogramImageFunction<TInputImage,TCoordRep>::OutputType LocalHistogramImageFunction<TInputImage,TCoordRep> ::EvaluateAtIndex(const IndexType& index) const { - typename HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); - histogramGenerator->SetNumberOfBins( this->GetNumberOfHistogramBins() ); - histogramGenerator->SetHistogramMin( this->GetHistogramMin() ); - histogramGenerator->SetHistogramMax( this->GetHistogramMax() ); + + typename HistogramType::Pointer histogram = HistogramType::New(); + + typename HistogramType::SizeType size ; + size.Fill( this->GetNumberOfHistogramBins() ) ; + + typename HistogramType::MeasurementVectorType lowerBound; + typename HistogramType::MeasurementVectorType upperBound; + + lowerBound.Fill( static_cast<typename HistogramType::MeasurementType>(this->GetHistogramMin()) ) ; + upperBound.Fill( static_cast<typename HistogramType::MeasurementType>(this->GetHistogramMax()) ) ; + + histogram->Initialize(size, lowerBound, upperBound ) ; + histogram->SetToZero(); // Check for input image if( !this->GetInputImage() ) { - return histogramGenerator->GetOutput(); + return histogram; } // Check for out of buffer if ( !this->IsInsideBuffer( index ) ) { - return histogramGenerator->GetOutput(); + return histogram; } - typename InputImageType::Pointer currentImage; - currentImage = InputImageType::New(); + typename InputImageType::ConstPointer currentImage = this->GetInputImage(); - currentImage = const_cast<InputImageType *>(this->GetInputImage()); + typename itk::ConstNeighborhoodIterator<InputImageType>::RadiusType radius; + radius.Fill( this->GetNeighborhoodRadius() ); typename InputImageType::RegionType region; typename InputImageType::IndexType currentIndex; @@ -90,20 +99,25 @@ LocalHistogramImageFunction<TInputImage,TCoordRep> region.SetIndex(currentIndex); region.SetSize(currentSize); - if(region.Crop(currentImage->GetRequestedRegion()) ) - { - typedef itk::ExtractImageFilter<InputImageType,InputImageType> ExtractFilterType; - typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New(); + itk::ConstNeighborhoodIterator<InputImageType> it(radius, currentImage, region); - extractFilter->SetInput(this->GetInputImage()); - extractFilter->SetExtractionRegion(region); - extractFilter->Update(); + float numberOfPixelsCounted = 0.0; - histogramGenerator->SetInput( extractFilter->GetOutput() ); - histogramGenerator->Compute(); + it.GoToBegin(); + while (!it.IsAtEnd()) + { + typename HistogramType::MeasurementVectorType sample; + for (unsigned int j = 0; j < sample.Size(); ++j) + { + sample[j] = it.GetPixel(j); + } + if( histogram->IncreaseFrequency(sample, 1) ) + { + ++numberOfPixelsCounted; + } + ++it; } - - return histogramGenerator->GetOutput(); + return histogram; } } // namespace otb diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index 560bcf869530627cf44fba8f1214cefa96728ca2..25d5f4fe048322ffbe5bf21e4bef29847b0aa860 100644 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -1496,11 +1496,14 @@ ADD_TEST(feTuLocalHistogramImageFunctionNew ${FEATUREEXTRACTION_TESTS16} otbLocalHistogramImageFunctionNew ) -ADD_TEST(feTuLocalHistogramImageFunctionTest ${FEATUREEXTRACTION_TESTS16} - otbLocalHistogramImageFunctionTest - ${INPUTDATA}/poupees_1canal.hd - ${TEMP}/feLocalHistogramImage.txt - ) +ADD_TEST(feTvLocalHistogramImageFunctionTest ${FEATUREEXTRACTION_TESTS16} +--compare-ascii ${EPSILON_8} + ${BASELINE_FILES}/feLocalHistogramImage.txt + ${TEMP}/feLocalHistogramImage.txt + otbLocalHistogramImageFunctionTest + ${INPUTDATA}/prison_toulouse.tif + ${TEMP}/feLocalHistogramImage.txt +) # ------- otb::ImageFunctionAdapter ------------- diff --git a/Testing/Code/FeatureExtraction/otbLocalHistogramImageFunctionTest.cxx b/Testing/Code/FeatureExtraction/otbLocalHistogramImageFunctionTest.cxx index e6244b188395ad813ed20d84a2161d361eae5b3f..ac1145cb9c1c1aef37dbe96a1c7377a6c09e6a3d 100644 --- a/Testing/Code/FeatureExtraction/otbLocalHistogramImageFunctionTest.cxx +++ b/Testing/Code/FeatureExtraction/otbLocalHistogramImageFunctionTest.cxx @@ -30,7 +30,7 @@ int otbLocalHistogramImageFunctionTest(int argc, char * argv[]) const char * inputFilename = argv[1]; const char * outputFilename = argv[2]; - typedef unsigned char InputPixelType; + typedef float InputPixelType; const unsigned int Dimension = 2; typedef otb::Image<InputPixelType, Dimension> InputImageType; @@ -55,19 +55,43 @@ int otbLocalHistogramImageFunctionTest(int argc, char * argv[]) index[0] = 100; index[1] = 100; - function->SetNeighborhoodRadius(3); + function->SetNeighborhoodRadius(10); function->SetHistogramMin(filter->GetMinimum()); function->SetHistogramMax(filter->GetMaximum()); FunctionType::OutputType Result; Result = function->EvaluateAtIndex(index); + float numberOfPixelsCounted = 0.0; + std::ofstream outputStream(outputFilename); outputStream << std::setprecision(10) << std::endl; + outputStream << "Index: " << index << std::endl; + + for(unsigned int i = 0 ; i < function->GetNumberOfHistogramBins() ; ++i) + { + outputStream << "Pos[" <<i <<"] = " << Result->GetFrequency(i) << " -> " << Result->GetMeasurement(i,0) << std::endl; + numberOfPixelsCounted += Result->GetFrequency(i); + } + + outputStream << "Number Of Pixels counted: " << numberOfPixelsCounted << std::endl; + + index[0] = 0; + index[1] = 0; + + Result = function->EvaluateAtIndex(index); + + numberOfPixelsCounted = 0.0; + + outputStream << "Index: " << index << std::endl; + for(unsigned int i = 0 ; i < function->GetNumberOfHistogramBins() ; ++i) { outputStream << "Pos[" <<i <<"] = " << Result->GetFrequency(i) << " -> " << Result->GetMeasurement(i,0) << std::endl; + numberOfPixelsCounted += Result->GetFrequency(i); } + outputStream << "Number Of Pixels counted: " << numberOfPixelsCounted << std::endl; + outputStream.close(); return EXIT_SUCCESS;