Skip to content
Snippets Groups Projects
Commit 9a1e1961 authored by Jonathan Guinet's avatar Jonathan Guinet
Browse files

ENH: new code to concatenate MeanShift filter and connected component

parent a03daf71
No related branches found
No related tags found
No related merge requests found
/*=========================================================================
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 __otbMeanShiftConnectedComponentSegmentationFilter_h
#define __otbMeanShiftConnectedComponentSegmentationFilter_h
#include "itkMacro.h"
#include "otbConnectedComponentMuParserFunctor.h"
#include "itkConnectedComponentFunctorImageFilter.h"
#include "otbMaskMuParserFilter.h"
#include "itkRelabelComponentImageFilter.h"
#include "otbMeanShiftImageFilter2.h"
namespace otb {
/** \class MeanShiftConnectedComponentSegmentationFilter
* \brief [internal] Helper class to perform connected component segmentation on an input image,
*
*
* The whole chain is described in :
* http://wiki.orfeo-toolbox.org/index.php/Connected_component_segmentation_module
*
* This class wraps a processing chain based on meanshift filtering followed by a connected component segmentation,
*
* An optional mask can be applied to segment only the pixels inside the mask.
*
* Parameters of the chain are :
* - MaskExpression : mathematical expression to apply on the input image to make a mask
* - ConnectedComponentExpression : mathematical expression which connects two pixels
* - MinimumObjectSize : minimum object size kept after segmentation
*
*/
template <class TVInputImage, class TMaskImage,class TLabelImage>
class MeanShiftConnectedComponentSegmentationFilter : public itk::ImageToImageFilter<TVInputImage, TLabelImage>
{
public:
/** Standard Self typedef */
typedef MeanShiftConnectedComponentSegmentationFilter Self;
typedef itk::ImageToImageFilter<TVInputImage, TLabelImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef unsigned int ObjectSizeType;
/** Some convenient typedefs. */
typedef TVInputImage VectorImageType;
typedef TMaskImage MaskImageType;
typedef TLabelImage LabelImageType;
typedef typename VectorImageType::Pointer VectorImagePointerType;
typedef typename VectorImageType::PixelType VectorImagePixelType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Runtime information support. */
itkTypeMacro(MeanShiftConnectedComponentSegmentationFilter, ImageToImageFilter);
/** ImageDimension constants */
itkStaticConstMacro(InputImageDimension, unsigned int,TVInputImage::ImageDimension);
// Mask generation
typedef Functor::ConnectedComponentMuParserFunctor<VectorImagePixelType> FunctorType;
typedef itk::ConnectedComponentFunctorImageFilter
<VectorImageType, LabelImageType, FunctorType, MaskImageType>
ConnectedComponentFilterType;
// mask typedef
typedef otb::MaskMuParserFilter<VectorImageType, MaskImageType> MaskMuParserFilterType;
// Labelization
typedef itk::RelabelComponentImageFilter<LabelImageType, LabelImageType>
RelabelComponentFilterType;
typedef double KernelType;
typedef otb::MeanShiftImageFilter2
<VectorImageType, VectorImageType, VectorImageType, KernelType>
MeanShiftFilterType;
typedef typename MeanShiftFilterType::Pointer MeanShiftFilterPointerType;
// ** // meanshift filter
/* Set/Get mean shift filter */
itkSetObjectMacro(MeanShiftFilter, MeanShiftFilterType);
itkGetObjectMacro(MeanShiftFilter, MeanShiftFilterType);
/* Set the mathematical expression used for the mask */
itkSetStringMacro(MaskExpression);
/* Get the mathematical expression used for the mask */
itkGetStringMacro(MaskExpression);
/* Set the mathematical expression used during connected component segmentation */
itkSetStringMacro(ConnectedComponentExpression);
/* Get the mathematical expression used during connected component segmentation */
itkGetStringMacro(ConnectedComponentExpression);
/* Set the minimum object size */
itkSetMacro(MinimumObjectSize, ObjectSizeType);
/* Get the minimum object size */
itkGetMacro(MinimumObjectSize, ObjectSizeType);
protected:
MeanShiftConnectedComponentSegmentationFilter();
virtual ~MeanShiftConnectedComponentSegmentationFilter();
void GenerateInputRequestedRegion();
virtual void GenerateData();
private:
MeanShiftFilterPointerType m_MeanShiftFilter;
/* CC parameters */
ObjectSizeType m_MinimumObjectSize;
std::string m_MaskExpression;
std::string m_ConnectedComponentExpression;
/* */
};
} // end namespace itk
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbMeanShiftConnectedComponentSegmentationFilter.txx"
#endif
#endif
/*=========================================================================
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 __otbMeanShiftConnectedComponentSegmentationFilter_txx
#define __otbMeanShiftConnectedComponentSegmentationFilter_txx
#include "otbMeanShiftConnectedComponentSegmentationFilter.h"
#include "itkExtractImageFilter.h"
namespace otb {
template<class TVImage,class TMaskImage, class TLabelImage>
MeanShiftConnectedComponentSegmentationFilter<TVImage,TMaskImage, TLabelImage>
::MeanShiftConnectedComponentSegmentationFilter()
{
m_MinimumObjectSize=2;
m_MeanShiftFilter= MeanShiftFilterType::New();
}
template<class TVImage,class TMaskImage, class TLabelImage>
MeanShiftConnectedComponentSegmentationFilter<TVImage,TMaskImage, TLabelImage>
::~MeanShiftConnectedComponentSegmentationFilter()
{
}
template<class TVImage,class TMaskImage, class TLabelImage>
void
MeanShiftConnectedComponentSegmentationFilter<TVImage,TMaskImage, TLabelImage>
::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
}
template<class TVImage,class TMaskImage, class TLabelImage>
void
MeanShiftConnectedComponentSegmentationFilter<TVImage,TMaskImage, TLabelImage>
::GenerateData()
{
// Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion
typedef itk::ExtractImageFilter<TVImage, TVImage> ExtractImageFilterType;
typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New();
extract->SetInput(this->GetInput());
extract->SetExtractionRegion(this->GetOutput()->GetRequestedRegion());
// WARNING: itk::ExtractImageFilter does not copy the MetadataDictionnary
// meanshift filtering
//not necessary
/* if (this->m_MeanShiftFilter.IsNotNull())
{
itkExceptionMacro("MeanShiftFilter is null");
}*/
this->m_MeanShiftFilter->SetInput(extract->GetOutput());
//this->m_MeanShiftFilter->SetInput(this->GetInput());
typename MaskImageType::Pointer mask;
if (!m_MaskExpression.empty())
{
// Compute the mask
typename MaskMuParserFilterType::Pointer maskFilter;
maskFilter = MaskMuParserFilterType::New();
maskFilter->SetInput(this->m_MeanShiftFilter->GetOutput());
maskFilter->SetExpression(m_MaskExpression);
maskFilter->Update();
mask = maskFilter->GetOutput();
}
// Perform connected components segmentation
typename ConnectedComponentFilterType::Pointer connected = ConnectedComponentFilterType::New();
connected->SetInput(this->m_MeanShiftFilter->GetOutput());
if (mask.IsNotNull()) connected->SetMaskImage(mask);
connected->GetFunctor().SetExpression(m_ConnectedComponentExpression);
connected->Update();
// Relabel connected component output
typename RelabelComponentFilterType::Pointer relabel = RelabelComponentFilterType::New();
relabel->SetInput(connected->GetOutput());
relabel->SetMinimumObjectSize(m_MinimumObjectSize);
relabel->Update();
this->GraftOutput(relabel->GetOutput());
}
} // end namespace otb
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment