Skip to content
Snippets Groups Projects
Commit 46d0c52c authored by Cyrille Valladeau's avatar Cyrille Valladeau
Browse files

ENH : improve Mean Shift : add cluster (work in progress)

parent 0a191d4d
No related branches found
No related tags found
No related merge requests found
Showing
with 319 additions and 52 deletions
......@@ -33,15 +33,15 @@ namespace otb
* \ingroup Streamed
* \ingroup Threaded
*/
template <class TInputImage, class TOutputImage, class TPrecision = double>
template <class TInputImage, class TOutputImage, class TClusterImage = Image<unsigned short, 2>, class TPrecision = double>
class ITK_EXPORT MeanShiftImageFilter
: public MeanShiftImageFilterBase<TInputImage,TOutputImage,TPrecision>
: public MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage,TPrecision>
{
public:
/** Standard class typedef */
typedef MeanShiftImageFilter Self;
typedef MeanShiftImageFilterBase<TInputImage,
TOutputImage,TPrecision> Superclass;
TOutputImage,TClusterImage,TPrecision> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......
......@@ -23,51 +23,51 @@ PURPOSE. See the above copyright notices for more information.
namespace otb
{
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
unsigned int
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::GetNumberOfComponentsPerPixel()
{
return 1;
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
void
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::InitValue(PrecisionPixelType & value, const unsigned int& nbComponents)
{
value = 0;
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
double
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::SquaredNorm(const PrecisionPixelType & value)
{
return value * value;
}
template <class TInputImage,class TOutputImage,class TPrecision>
const typename MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
const typename MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::PrecisionPixelType
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::CastInputPixelToPrecisionPixel(const InputPixelType & pixel)
{
return static_cast<PrecisionPixelType>(pixel);
}
template <class TInputImage,class TOutputImage,class TPrecision>
const typename MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
const typename MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::OutputPixelType
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::CastPrecisionPixelToOutputPixel(const PrecisionPixelType & pixel)
{
return static_cast<OutputPixelType>(pixel);
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
void
MeanShiftImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
......
......@@ -20,9 +20,58 @@ PURPOSE. See the above copyright notices for more information.
#include "itkImageToImageFilter.h"
#include "itkVariableLengthVector.h"
#include "otbImage.h"
namespace otb
{
template <class TPixel, class TPoint>
class ITK_EXPORT MeanShiftCluster
{
public:
typedef TPixel PixelType;
typedef TPoint PointType;
PixelType m_SpectralCenter;
PointType m_SpatialCenter;
PixelType m_SpectralAccumulation;
PointType m_SpatialAccumulation;
unsigned int m_NumberOfPixels;
MeanShiftCluster()
{}
MeanShiftCluster(const PointType& spatialCenter, const PixelType& spectralCenter)
{
m_NumberOfPixels = 1;
m_SpectralCenter = spectralCenter;
m_SpatialCenter = spatialCenter;
m_SpectralAccumulation = spectralCenter;
m_SpatialAccumulation = spatialCenter;
}
void UpdateCenter()
{
m_SpectralCenter = m_SpectralAccumulation/m_NumberOfPixels;
m_SpatialCenter = m_SpatialAccumulation/m_NumberOfPixels;
}
void AddPixel(const PointType& point, const PixelType& pixel)
{
m_SpectralAccumulation += pixel;
m_SpatialAccumulation[0]+= point[0];
m_SpatialAccumulation[1]+= point[1];
m_NumberOfPixels++;
}
void RemovePixel(const PointType& point, const PixelType& pixel)
{
m_SpectralAccumulation -= pixel;
m_SpatialAccumulation[0]-= point[0];
m_SpatialAccumulation[1]-= point[1];
m_NumberOfPixels--;
}
};
/** \class MeanShiftImageFilterBase
*
......@@ -57,7 +106,7 @@ namespace otb
* \ingroup Threaded
*/
template <class TInputImage, class TOutputImage, class TPrecision = double>
template <class TInputImage, class TOutputImage, class TClusterImage = Image<unsigned short, 2>, class TPrecision = double>
class ITK_EXPORT MeanShiftImageFilterBase
: public itk::ImageToImageFilter<TInputImage,TOutputImage>
{
......@@ -79,12 +128,18 @@ namespace otb
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::Pointer OutputImagePointerType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef TClusterImage ClusterImageType;
typedef typename ClusterImageType::Pointer ClusterImagePointerType;
typedef typename ClusterImageType::PixelType ClusterPixelType;
typedef typename OutputImageType::RegionType RegionType;
typedef typename RegionType::SizeType SizeType;
typedef typename RegionType::IndexType IndexType;
typedef typename InputImageType::SpacingType SpacingType;
typedef TPrecision PrecisionPixelType;
typedef std::vector<ClusterPixelType> LabelPerThreadType;
typedef std::vector<LabelPerThreadType> LabelVectorType;
/** Setters / Getters */
itkSetMacro(SpatialRadius,double);
itkGetMacro(SpatialRadius,double);
......@@ -98,6 +153,11 @@ namespace otb
itkGetMacro(UseImageSpacing,bool);
itkBooleanMacro(UseImageSpacing);
/** Return the const output image direction */
const ClusterImageType * GetClusterImage() const;
/** Return the output image direction */
ClusterImageType * GetClusterImage();
protected:
/** This filters use a neighborhood around the pixel, so it needs to redfine the
* input requested region */
......@@ -106,9 +166,14 @@ namespace otb
/** Threaded generate data */
virtual void ThreadedGenerateData(const RegionType & outputRegionForThread,int threadId);
/** output allocation. ITK don't support to have two output with different type (Image and VectorImage) */
virtual void AllocateOutputs();
/** Before Threaded generate data */
virtual void BeforeThreadedGenerateData();
/** Constructor */
MeanShiftImageFilterBase();
/** destructor */
~MeanShiftImageFilterBase(){};
......@@ -174,6 +239,9 @@ namespace otb
/** Distance threshold for convergence in the spatial domain */
double m_ConvergenceDistanceThreshold;
/** Label vector*/
LabelVectorType m_Label;
};
}// end namespace otb
......
......@@ -29,10 +29,16 @@ PURPOSE. See the above copyright notices for more information.
namespace otb
{
template <class TInputImage,class TOutputImage,class TPrecision>
MeanShiftImageFilterBase<TInputImage,TOutputImage,TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::MeanShiftImageFilterBase()
{
this->SetNumberOfOutputs(2);
this->SetNumberOfRequiredOutputs(1);
//this->SetNthOutput(1,OutputImageType::New());
this->SetNthOutput(1,ClusterImageType::New());
m_MaxNumberOfIterations = 20;
m_ConvergenceDistanceThreshold = 0.5;
m_SpatialRadius = 3;
......@@ -40,14 +46,69 @@ namespace otb
m_UseImageSpacing = false;
m_InternalRadius.Fill(0);
m_InternalSpacing.Fill(1.);
m_Label.clear();
// For debug purposes we set the number of threads to 1.
// this->SetNumberOfThreads(1);
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
const typename MeanShiftImageFilterBase<TInputImage, TOutputImage, TClusterImage, TPrecision>::ClusterImageType *
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::GetClusterImage()const
{
if (this->GetNumberOfOutputs() < 2)
{
return 0;
}
return static_cast<const ClusterImageType * >(this->itk::ProcessObject::GetOutput(1) );
}
/** Return the output image direction */
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
typename MeanShiftImageFilterBase<TInputImage, TOutputImage, TClusterImage, TPrecision>::ClusterImageType *
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::GetClusterImage()
{
if (this->GetNumberOfOutputs() < 2)
{
return 0;
}
return static_cast<ClusterImageType * >
(this->itk::ProcessObject::GetOutput(1) );
}
template <class TInputImage,class TOutputImage,class TClusterImage, class TPrecision>
void
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::AllocateOutputs()
{
// Filter Output
OutputImagePointerType outputPtr = this->GetOutput(0);
outputPtr->SetBufferedRegion( outputPtr->GetRequestedRegion() );
outputPtr->Allocate();
// Cluster Output
ClusterImagePointerType clusterPtr = this->GetClusterImage();
clusterPtr->SetBufferedRegion( clusterPtr->GetRequestedRegion() );
clusterPtr->Allocate();
}
template <class TInputImage,class TOutputImage,class TClusterImage, class TPrecision>
void
MeanShiftImageFilterBase<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::BeforeThreadedGenerateData()
{
LabelPerThreadType labelThread(1, 0);
LabelVectorType m_label(this->GetNumberOfThreads(), labelThread);
}
template <class TInputImage,class TOutputImage,class TClusterImage, class TPrecision>
void
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::GenerateInputRequestedRegion()
{
// call the superclass' implementation of this method
......@@ -113,21 +174,24 @@ namespace otb
}
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage,class TClusterImage, class TPrecision>
void
MeanShiftImageFilterBase<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage,TPrecision>
::ThreadedGenerateData(const RegionType & outputRegionForThread,int threadId)
{
// Set up the progress reporter
itk::ProgressReporter progress(this,threadId,outputRegionForThread.GetNumberOfPixels());
// Input and output pointers
typename OutputImageType::Pointer outputPtr = this->GetOutput();
typename InputImageType::ConstPointer inputPtr = this->GetInput();
typename OutputImageType::Pointer outputPtr = this->GetOutput();
typename ClusterImageType::Pointer clusterPtr = this->GetClusterImage();
// Iterators
itk::ImageRegionConstIteratorWithIndex<InputImageType> inputIt(inputPtr,outputRegionForThread);
itk::ImageRegionIterator<OutputImageType> outputIt(outputPtr,outputRegionForThread);
itk::ImageRegionIterator<ClusterImageType> clusterIt(clusterPtr,outputRegionForThread);
// local declarations
unsigned int nbIterations;
......@@ -137,21 +201,27 @@ namespace otb
unsigned int nbPixelsIntoAccount;
bool goesOn = true;
long startx,stopx,starty,stopy,i,j;
double squaredSpatialDistance, squaredUpdateDistance;
double squaredSpatialDistance, squaredSpectralDistance, squaredUpdateDistance;
// Const values computed here to reduce complexity
const unsigned int nbComponentsPerPixel = this->GetNumberOfComponentsPerPixel();
const double spatialThreshold = vcl_pow(m_SpatialRadius,2);
const double spectralThreshold = vcl_pow(m_RangeRadius,2);
const double spatialAndRangeThreshold = nbComponentsPerPixel * vcl_pow(m_RangeRadius,2) + spatialThreshold;
const double spatialConvergenceThreshold = vcl_pow(m_ConvergenceDistanceThreshold,2);
typedef MeanShiftCluster<PrecisionPixelType,PointType> ClusterType;
typedef std::vector<ClusterType> ClusterVectorType;
ClusterVectorType clusterVector;
// intialize iterators
inputIt.GoToBegin();
outputIt.GoToBegin();
clusterIt.GoToBegin();
// Walk the images
while(!inputIt.IsAtEnd() && !outputIt.IsAtEnd())
while(!inputIt.IsAtEnd() && !outputIt.IsAtEnd() && !clusterIt.IsAtEnd())
{
nbIterations = 0;
goesOn = true;
......@@ -210,7 +280,7 @@ namespace otb
maxDensityPoint[1]/=nbPixelsIntoAccount;
maxDensityValue/=nbPixelsIntoAccount;
}
convergenceValue = maxDensityValue;
convergenceValue = maxDensityValue;
// Check if we are still significantly moving
squaredUpdateDistance = vcl_pow(static_cast<double>(maxDensityPoint[0]-convergencePoint[0]),2)
+vcl_pow(static_cast<double>(maxDensityPoint[1]-convergencePoint[1]),2);
......@@ -223,22 +293,58 @@ namespace otb
{
// Update the convergence point and loop again
convergencePoint = maxDensityPoint;
}
++nbIterations;
}
// Set the output value
outputIt.Set(this->CastPrecisionPixelToOutputPixel(convergenceValue));
bool clusterFound = false;
// Look for an already existing cluster
ClusterPixelType label = 0;
while(label<clusterVector.size() && !clusterFound)
{
squaredSpatialDistance = vcl_pow(clusterVector[label].m_SpatialCenter[0]-convergencePoint[0],2)
+vcl_pow(clusterVector[label].m_SpatialCenter[1]-convergencePoint[1],2);
squaredSpectralDistance = this->SquaredNorm(clusterVector[label].m_SpectralCenter-convergenceValue);
if(squaredSpatialDistance<spatialThreshold
&& squaredSpectralDistance<spectralThreshold)
{
clusterFound = true;
clusterVector[label].AddPixel(convergencePoint,convergenceValue);
}
else
{
++label;
}
}
// if we found a good cluster, labelize pixel
if(clusterFound)
{
clusterIt.Set(label+1);
}
// else create a new cluster for that pixel and labelize it
else
{
clusterVector.push_back(ClusterType(convergencePoint,convergenceValue));
clusterIt.Set(static_cast<ClusterPixelType>(clusterVector.size()));
}
// Update progress
progress.CompletedPixel();
// Increment iterators
++inputIt;
++outputIt;
++clusterIt;
}
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage,class TClusterImage, class TPrecision>
void
MeanShiftImageFilterBase<TInputImage,TOutputImage,TPrecision>
MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage, TPrecision>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
......
......@@ -34,14 +34,14 @@ namespace otb
* \ingroup Streamed
* \ingroup Threaded
*/
template <class TInputImage, class TOutputImage, class TPrecision = double>
template <class TInputImage, class TOutputImage, class TClusterImage = Image<unsigned short, 2>, class TPrecision = double>
class ITK_EXPORT MeanShiftVectorImageFilter
: public MeanShiftImageFilterBase<TInputImage,TOutputImage,itk::VariableLengthVector<TPrecision> >
: public MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage,itk::VariableLengthVector<TPrecision> >
{
public:
/** Standard class typedef */
typedef MeanShiftVectorImageFilter Self;
typedef MeanShiftImageFilterBase<TInputImage,TOutputImage,
typedef MeanShiftImageFilterBase<TInputImage,TOutputImage,TClusterImage,
itk::VariableLengthVector<TPrecision> > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......
......@@ -29,54 +29,54 @@ PURPOSE. See the above copyright notices for more information.
namespace otb
{
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
unsigned int
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::GetNumberOfComponentsPerPixel()
{
return this->GetInput()->GetNumberOfComponentsPerPixel();
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
void
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::InitValue(PrecisionPixelType & value, const unsigned int& nbComponents)
{
value.SetSize(nbComponents);
value.Fill(0);
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
double
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::SquaredNorm(const PrecisionPixelType & value)
{
return value.GetSquaredNorm();
}
template <class TInputImage,class TOutputImage,class TPrecision>
const typename MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
const typename MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::PrecisionPixelType
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::CastInputPixelToPrecisionPixel(const InputPixelType & pixel)
{
// Inplicit cast in construction by copy, nothing to do here
return pixel;
}
template <class TInputImage,class TOutputImage,class TPrecision>
const typename MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
const typename MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::OutputPixelType
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::CastPrecisionPixelToOutputPixel(const PrecisionPixelType & pixel)
{
// Inplicit cast in construction by copy, nothing to do here
return pixel;
}
template <class TInputImage,class TOutputImage,class TPrecision>
template <class TInputImage,class TOutputImage, class TClusterImage,class TPrecision>
void
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TPrecision>
MeanShiftVectorImageFilter<TInputImage,TOutputImage,TClusterImage,TPrecision>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
......
......@@ -913,6 +913,16 @@ ADD_TEST(bfTvMeanShiftVectorImageFilterUsingImageSpacing ${BASICFILTERS_TESTS9}
3 15 20 1 0.0001
)
ADD_TEST(bfTvMeanShiftVectorImageCluster ${BASICFILTERS_TESTS9}
#--compare-image ${EPSILON}
# ${BASELINE}/bfMeanShiftVectorImageFilterOutputUsingImageSpacing.tif
# ${TEMP}/bfMeanShiftImageCluster.tif
otbMeanShiftVectorImageCluster
${INPUTDATA}/qb_RoadExtract2sub200x200.tif
${TEMP}/bfMeanShiftImageCluster.tif
3 15 20 1 0.0001
)
ADD_TEST(bfTvFunctionToImageFilterNew ${BASICFILTERS_TESTS9}
otbFunctionToImageFilterNew
)
......@@ -1143,6 +1153,7 @@ otbMeanShiftImageFilterNew.cxx
otbMeanShiftImageFilter.cxx
otbMeanShiftVectorImageFilterNew.cxx
otbMeanShiftVectorImageFilter.cxx
otbMeanShiftVectorImageCluster.cxx
otbFunctionToImageFilterNew.cxx
otbFunctionToImageFilter.cxx
)
......
......@@ -35,6 +35,7 @@ REGISTER_TEST(otbMeanShiftImageFilterNew);
REGISTER_TEST(otbMeanShiftImageFilter);
REGISTER_TEST(otbMeanShiftVectorImageFilterNew);
REGISTER_TEST(otbMeanShiftVectorImageFilter);
REGISTER_TEST(otbMeanShiftVectorImageCluster);
REGISTER_TEST(otbFunctionToImageFilterNew);
REGISTER_TEST(otbFunctionToImageFilter);
}
......@@ -17,7 +17,6 @@
=========================================================================*/
#include "itkExceptionObject.h"
#include "otbImage.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMeanShiftImageFilter.h"
......
/*=========================================================================
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 "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMeanShiftVectorImageFilter.h"
int otbMeanShiftVectorImageCluster(int argc, char * argv[])
{
if(argc != 8)
{
std::cerr<<"Usage: "<<argv[0]<<" infname clusterfname spatialRadius rangeRadius maxNbIterations useImageSpacing convergenceDistanceThreshold"<<std::endl;
return EXIT_FAILURE;
}
const char * infname = argv[1];
const char * outfname = argv[2];
const double spatialRadius = atof(argv[3]);
const double rangeRadius = atof(argv[4]);
const unsigned int maxNbIterations = atoi(argv[5]);
const bool useImageSpacing = atoi(argv[6]);
const double convergenceTol = atof(argv[7]);
const unsigned int Dimension = 2;
typedef short PixelType;
typedef otb::VectorImage<PixelType,Dimension> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::MeanShiftVectorImageFilter<ImageType,ImageType> FilterType;
typedef FilterType::ClusterImageType ClusterImageType;
typedef otb::ImageFileWriter<ClusterImageType> WriterType;
// Instantiating object
FilterType::Pointer filter = FilterType::New();
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(infname);
writer->SetFileName(outfname);
filter->SetSpatialRadius(spatialRadius);
filter->SetRangeRadius(rangeRadius);
filter->SetMaxNumberOfIterations(maxNbIterations);
filter->SetUseImageSpacing(useImageSpacing);
filter->SetConvergenceDistanceThreshold(convergenceTol);
// FOR DEBUG
filter->SetNumberOfThreads(1);
filter->SetInput(reader->GetOutput());
writer->SetInput(filter->GetClusterImage());
writer->Update();
return EXIT_SUCCESS;
}
......@@ -43,7 +43,7 @@ int otbMeanShiftVectorImageFilter(int argc, char * argv[])
typedef otb::VectorImage<PixelType,Dimension> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<ImageType> WriterType;
typedef otb::MeanShiftVectorImageFilter<ImageType,ImageType> FilterType;
typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType> FilterType;
// Instantiating object
FilterType::Pointer filter = FilterType::New();
......@@ -55,6 +55,7 @@ int otbMeanShiftVectorImageFilter(int argc, char * argv[])
filter->SetSpatialRadius(spatialRadius);
filter->SetRangeRadius(rangeRadius);
std::cout<<maxNbIterations<<std::endl;
filter->SetMaxNumberOfIterations(maxNbIterations);
filter->SetUseImageSpacing(useImageSpacing);
filter->SetConvergenceDistanceThreshold(convergenceTol);
......@@ -63,5 +64,15 @@ int otbMeanShiftVectorImageFilter(int argc, char * argv[])
writer->SetInput(filter->GetOutput());
writer->Update();
/*
typedef FilterType::ClusterImageType ClusterType;
typedef otb::ImageFileWriter<ClusterType> Writer2Type;
Writer2Type::Pointer w2 = Writer2Type::New();
w2->SetFileName("cluster.tif");
w2->SetInput(filter->GetClusterImage());
w2->Update();
*/
return EXIT_SUCCESS;
}
......@@ -17,6 +17,7 @@
=========================================================================*/
#include "itkExceptionObject.h"
#include "otbVectorImage.h"
#include "otbImage.h"
#include "otbMeanShiftVectorImageFilter.h"
int otbMeanShiftVectorImageFilterNew(int argc, char * argv[])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment