--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkConditionalBinaryErodeImageFilter_h
+#define clitkConditionalBinaryErodeImageFilter_h
+
+/* =================================================
+ * @file clitkConditionalBinaryErodeImageFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+
+//itk include
+#include "itkImageToImageFilter.h"
+#include <vector>
+#include <queue>
+#include "itkBinaryMorphologyImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+#include "itkNeighborhoodIterator.h"
+#include "itkConstNeighborhoodIterator.h"
+#include "itkNeighborhood.h"
+#include "itkImageBoundaryCondition.h"
+#include "itkImageRegionIterator.h"
+#include "itkConceptChecking.h"
+
+namespace clitk
+{
+
+ template <class TInputImage, class TOutputImage, class TKernel>
+ class ITK_EXPORT ConditionalBinaryErodeImageFilter :
+ public itk::BinaryMorphologyImageFilter< TInputImage, TOutputImage, TKernel >
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef ConditionalBinaryErodeImageFilter Self;
+ typedef itk::BinaryMorphologyImageFilter<TInputImage, TOutputImage, TKernel> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ // Method for creation through the object factory
+ itkNewMacro(Self);
+
+ // Run-time type information (and related methods)
+ itkTypeMacro(BinaryErodeImageFilter, BinaryMorphologyImageFilterr );
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
+ /** Extract the dimension of the kernel */
+ itkStaticConstMacro(KernelDimension, unsigned int,
+ TKernel::NeighborhoodDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef TInputImage InputImageType;
+ typedef TOutputImage OutputImageType;
+ typedef TKernel KernelType;
+
+ /** Kernel (structuring element) iterator. */
+ typedef typename KernelType::ConstIterator KernelIteratorType;
+
+ /** Image typedef support. */
+ typedef typename InputImageType::PixelType InputPixelType;
+ typedef typename OutputImageType::PixelType OutputPixelType;
+ typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+ typedef typename InputImageType::OffsetType OffsetType;
+ typedef typename InputImageType::IndexType IndexType;
+
+ typedef typename InputImageType::RegionType InputImageRegionType;
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+ typedef typename InputImageType::SizeType InputSizeType;
+
+ /** Set the value in the image to consider as "foreground". Defaults to
+ * maximum value of PixelType. This is an alias to the
+ * ForegroundValue in the superclass. */
+ void SetErodeValue(const InputPixelType& value)
+ { this->SetForegroundValue( value ); }
+
+ /** Get the value in the image considered as "foreground". Defaults to
+ * maximum value of PixelType. This is an alias to the
+ * ForegroundValue in the superclass. */
+ InputPixelType GetErodeValue() const
+ { return this->GetForegroundValue(); }
+
+ protected:
+ ConditionalBinaryErodeImageFilter();
+ virtual ~ConditionalBinaryErodeImageFilter(){}
+ void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+ void GenerateData();
+
+ // type inherited from the superclass
+ typedef typename Superclass::NeighborIndexContainer NeighborIndexContainer;
+
+ private:
+ ConditionalBinaryErodeImageFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkConditionalBinaryErodeImageFilter.txx"
+#endif
+
+#endif // #define clitkConditionalBinaryErodeImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkConditionalBinaryErodeImageFilter_txx
+#define clitkConditionalBinaryErodeImageFilter_txx
+
+/* =================================================
+ * @file clitkConditionalBinaryErodeImageFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "itkConstNeighborhoodIterator.h"
+#include "itkNeighborhoodIterator.h"
+#include "itkImageRegionIteratorWithIndex.h"
+#include "itkNeighborhoodInnerProduct.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkNeighborhoodAlgorithm.h"
+#include "itkConstantBoundaryCondition.h"
+#include "itkOffset.h"
+#include "itkProgressReporter.h"
+#include "itkBinaryErodeImageFilter.h"
+
+namespace clitk
+{
+
+ template <class TInputImage, class TOutputImage, class TKernel>
+ ConditionalBinaryErodeImageFilter<TInputImage, TOutputImage, TKernel>
+ ::ConditionalBinaryErodeImageFilter()
+ {
+ this->m_BoundaryToForeground = true;
+ }
+
+
+ template< class TInputImage, class TOutputImage, class TKernel>
+ void
+ ConditionalBinaryErodeImageFilter< TInputImage, TOutputImage, TKernel>
+ ::GenerateData()
+ {
+ this->AllocateOutputs();
+
+ unsigned int i,j;
+
+ // Retrieve input and output pointers
+ typename OutputImageType::Pointer output = this->GetOutput();
+ typename InputImageType::ConstPointer input = this->GetInput();
+
+ // Get values from superclass
+ InputPixelType foregroundValue = this->GetForegroundValue();
+ InputPixelType backgroundValue = this->GetBackgroundValue();
+ KernelType kernel = this->GetKernel();
+ InputSizeType radius;
+ radius.Fill(1);
+ typename TInputImage::RegionType inputRegion = input->GetBufferedRegion();
+ typename TOutputImage::RegionType outputRegion = output->GetBufferedRegion();
+
+ // compute the size of the temp image. It is needed to create the progress
+ // reporter.
+ // The tmp image needs to be large enough to support:
+ // 1. The size of the structuring element
+ // 2. The size of the connectivity element (typically one)
+ typename TInputImage::RegionType tmpRequestedRegion = outputRegion;
+ typename TInputImage::RegionType paddedInputRegion
+ = input->GetBufferedRegion();
+ paddedInputRegion.PadByRadius( radius ); // to support boundary values
+ InputSizeType padBy = radius;
+ for (i=0; i < KernelDimension; ++i)
+ {
+ padBy[i] = (padBy[i]>kernel.GetRadius(i) ? padBy[i] : kernel.GetRadius(i));
+ }
+ tmpRequestedRegion.PadByRadius( padBy );
+ tmpRequestedRegion.Crop( paddedInputRegion );
+
+ typename TInputImage::RegionType requiredInputRegion
+ = input->GetBufferedRegion();
+ requiredInputRegion.Crop( tmpRequestedRegion );
+
+ // Support progress methods/callbacks
+ // Setup a progress reporter. We have 4 stages to the algorithm so
+ // pretend we have 4 times the number of pixels
+ itk::ProgressReporter progress(this, 0,
+ outputRegion.GetNumberOfPixels() * 3
+ + tmpRequestedRegion.GetNumberOfPixels()
+ + requiredInputRegion.GetNumberOfPixels() );
+
+ // Allocate and reset output. We copy the input to the output,
+ // except for pixels with DilateValue. These pixels are initially
+ // replaced with BackgroundValue and potentially replaced later with
+ // DilateValue as the Minkowski sums are performed.
+ itk::ImageRegionIterator<OutputImageType> outIt( output, outputRegion );
+ //ImageRegionConstIterator<InputImageType> inIt( input, outputRegion );
+
+ for( outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt )
+ {
+ outIt.Set( foregroundValue );
+ progress.CompletedPixel();
+ }
+
+
+ // Create the temp image for surface encoding
+ // The temp image size is equal to the output requested region for thread
+ // padded by max( connectivity neighborhood radius, SE kernel radius ).
+ typedef itk::Image<unsigned char, TInputImage::ImageDimension> TempImageType;
+ typename TempImageType::Pointer tmpImage = TempImageType::New();
+
+ // Define regions of temp image
+ tmpImage->SetRegions( tmpRequestedRegion );
+
+ // Allocation.
+ // Pay attention to the fact that here, the output is still not
+ // allocated (so no extra memory needed for tmp image, if you
+ // consider that you reserve som memory space for output)
+ tmpImage->Allocate();
+
+ // First Stage
+ // Copy the input image to the tmp image.
+ // Tag the tmp Image.
+ // zero means background
+ // one means pixel on but not treated
+ // two means border pixel
+ // three means inner pixel
+ static const unsigned char backgroundTag = 0;
+ static const unsigned char onTag = 1;
+ static const unsigned char borderTag = 2;
+ static const unsigned char innerTag = 3;
+
+ if( !this->m_BoundaryToForeground )
+ { tmpImage->FillBuffer( onTag ); }
+ else
+ { tmpImage->FillBuffer( backgroundTag ); }
+
+ // Iterators on input and tmp image
+ // iterator on input
+ itk::ImageRegionConstIterator<TInputImage> iRegIt( input, requiredInputRegion );
+ // iterator on tmp image
+ itk::ImageRegionIterator<TempImageType> tmpRegIt( tmpImage, requiredInputRegion );
+
+ for( iRegIt.GoToBegin(), tmpRegIt.GoToBegin();
+ !tmpRegIt.IsAtEnd();
+ ++iRegIt, ++tmpRegIt )
+ {
+ OutputPixelType pxl = iRegIt.Get();
+
+ //JV pxl != foregroundValue
+ if( pxl == backgroundValue )
+ { tmpRegIt.Set( onTag ); }
+ else
+ {
+ // by default if it is not foreground, consider
+ // it as background
+ tmpRegIt.Set( backgroundTag );
+ }
+ progress.CompletedPixel();
+ }
+
+ // Second stage
+ // Border tracking and encoding
+
+ // Need to record index, use an iterator with index
+ // Define iterators that will traverse the OUTPUT requested region
+ // for thread and not the padded one. The tmp image has been padded
+ // because in that way we will take care carefully at boundary
+ // pixels of output requested region. Take care means that we will
+ // check if a boundary pixel is or not a border pixel.
+ itk::ImageRegionIteratorWithIndex<TempImageType>
+ tmpRegIndexIt( tmpImage, tmpRequestedRegion );
+
+ itk::ConstNeighborhoodIterator<TempImageType>
+ oNeighbIt( radius, tmpImage, tmpRequestedRegion );
+
+ // Define boundaries conditions
+ itk::ConstantBoundaryCondition<TempImageType> cbc;
+ cbc.SetConstant( backgroundTag );
+ oNeighbIt.OverrideBoundaryCondition(&cbc);
+
+ unsigned int neighborhoodSize = oNeighbIt.Size();
+ unsigned int centerPixelCode = neighborhoodSize / 2;
+
+ std::queue<IndexType> propagQueue;
+
+ // Neighborhood iterators used to track the surface.
+ //
+ // Note the region specified for the first neighborhood iterator is
+ // the requested region for the tmp image not the output image. This
+ // is necessary because the NeighborhoodIterator relies on the
+ // specified region to determine if you will ever query a boundary
+ // condition pixel. Since we call SetLocation on the neighbor of a
+ // specified pixel, we have to set the region for the interator to
+ // include any pixel we may set our location to.
+ itk::NeighborhoodIterator<TempImageType>
+ nit( radius, tmpImage, tmpRequestedRegion );
+ nit.OverrideBoundaryCondition(&cbc);
+ nit.GoToBegin();
+
+ itk::ConstNeighborhoodIterator<TempImageType>
+ nnit( radius, tmpImage, tmpRequestedRegion );
+ nnit.OverrideBoundaryCondition(&cbc);
+ nnit.GoToBegin();
+
+ for( tmpRegIndexIt.GoToBegin(), oNeighbIt.GoToBegin();
+ !tmpRegIndexIt.IsAtEnd();
+ ++tmpRegIndexIt, ++oNeighbIt )
+ {
+
+ unsigned char tmpValue = tmpRegIndexIt.Get();
+
+ // Test current pixel: it is active ( on ) or not?
+ if( tmpValue == onTag )
+ {
+ // The current pixel has not been treated previously. That
+ // means that we do not know that it is an inner pixel of a
+ // border pixel.
+
+ // Test current pixel: it is a border pixel or an inner pixel?
+ bool bIsOnContour = false;
+
+ for (i = 0; i < neighborhoodSize; ++i)
+ {
+ // If at least one neighbour pixel is off the center pixel
+ // belongs to contour
+ if( oNeighbIt.GetPixel( i ) == backgroundTag )
+ {
+ bIsOnContour = true;
+ break;
+ }
+ }
+
+ if( bIsOnContour )
+ {
+ // center pixel is a border pixel and due to the parsing, it is also
+ // a pixel which belongs to a new border connected component
+ // Now we will parse this border thanks to a burn procedure
+
+ // mark pixel value as a border pixel
+ tmpRegIndexIt.Set( borderTag );
+
+ // add it to border container.
+ // its code is center pixel code because it is the first pixel
+ // of the connected component border
+
+ // paint the structuring element
+ typename NeighborIndexContainer::const_iterator itIdx;
+ NeighborIndexContainer& idxDifferenceSet
+ = this->GetDifferenceSet( centerPixelCode );
+ for( itIdx = idxDifferenceSet.begin();
+ itIdx != idxDifferenceSet.end();
+ ++itIdx )
+ {
+ IndexType idx = tmpRegIndexIt.GetIndex() + *itIdx;
+ if( outputRegion.IsInside( idx ) )
+ { output->SetPixel( idx, backgroundValue ); }
+ }
+
+ // add it to queue
+ propagQueue.push( tmpRegIndexIt.GetIndex() );
+
+ // now find all the border pixels
+ while ( !propagQueue.empty() )
+ {
+ // Extract pixel index from queue
+ IndexType currentIndex = propagQueue.front();
+ propagQueue.pop();
+
+ nit += currentIndex - nit.GetIndex();
+
+ for (i = 0; i < neighborhoodSize; ++i)
+ {
+ // If pixel has not been already treated and it is a pixel
+ // on, test if it is an inner pixel or a border pixel
+
+ // Remark: all the pixels outside the image are set to
+ // backgroundTag thanks to boundary conditions. That means that if
+ // we enter in the next if-statement we are sure that the
+ // current neighbour pixel is in the image
+ if( nit.GetPixel( i ) == onTag )
+ {
+ // Check if it is an inner or border neighbour pixel
+ // Get index of current neighbour pixel
+ IndexType neighbIndex = nit.GetIndex( i );
+
+ // Force location of neighbour iterator
+ nnit += neighbIndex - nnit.GetIndex();
+
+ bool bIsOnBorder = false;
+
+ for( j = 0; j < neighborhoodSize; ++j)
+ {
+ // If at least one neighbour pixel is off the center
+ // pixel belongs to border
+ if( nnit.GetPixel(j) == backgroundTag )
+ {
+ bIsOnBorder = true;
+ break;
+ }
+ }
+
+
+ if( bIsOnBorder )
+ {
+ // neighbour pixel is a border pixel
+ // mark it
+ bool status;
+ nit.SetPixel( i, borderTag, status );
+
+ // check whether we could set the pixel. can only set
+ // the pixel if it is within the tmpimage
+ if (status)
+ {
+ // add it to queue
+ propagQueue.push( neighbIndex );
+
+ // paint the structuring element
+ typename NeighborIndexContainer::const_iterator itIndex;
+ NeighborIndexContainer& indexDifferenceSet
+ = this->GetDifferenceSet( i );
+ for( itIndex = indexDifferenceSet.begin();
+ itIndex != indexDifferenceSet.end();
+ ++itIndex )
+ {
+ IndexType idx = neighbIndex + *itIndex;
+ if( outputRegion.IsInside( idx ) )
+ { output->SetPixel( idx, backgroundValue ); }
+ }
+ }
+ }
+ else
+ {
+ // neighbour pixel is an inner pixel
+ bool status;
+ nit.SetPixel( i, innerTag, status );
+ }
+
+ progress.CompletedPixel();
+ } // if( nit.GetPixel( i ) == onTag )
+
+ } // for (i = 0; i < neighborhoodSize; ++i)
+
+ } // while ( !propagQueue.empty() )
+
+ } // if( bIsOnCountour )
+ else
+ { tmpRegIndexIt.Set( innerTag ); }
+
+ progress.CompletedPixel();
+
+ } // if( tmpRegIndexIt.Get() == onTag )
+ else if( tmpValue == backgroundTag )
+ { progress.CompletedPixel(); }
+ // Here, the pixel is a background pixel ( value at 0 ) or an
+ // already treated pixel:
+ // 2 for border pixel, 3 for inner pixel
+ }
+
+
+ // Deallocate tmpImage
+ tmpImage->Initialize();
+
+ // Third Stage
+ // traverse structure of border and SE CCs, and paint output image
+
+ // Let's consider the the set of the ON elements of the input image as X.
+ //
+ // Let's consider the structuring element as B = {B0, B1, ..., Bn},
+ // where Bi denotes a connected component of B.
+ //
+ // Let's consider bi, i in [0,n], an arbitrary point of Bi.
+ //
+
+ // We use hence the next property in order to compute minkoswki
+ // addition ( which will be written (+) ):
+ //
+ // X (+) B = ( Xb0 UNION Xb1 UNION ... Xbn ) UNION ( BORDER(X) (+) B ),
+ //
+ // where Xbi is the set X translated with respect to vector bi :
+ //
+ // Xbi = { x + bi, x belongs to X } where BORDER(X) is the extracted
+ // border of X ( 8 connectivity in 2D, 26 in 3D )
+
+ // Define boundaries conditions
+ itk::ConstantBoundaryCondition<TOutputImage> obc;
+ obc.SetConstant( backgroundValue );
+
+ itk::NeighborhoodIterator<OutputImageType>
+ onit( kernel.GetRadius(), output, outputRegion );
+ onit.OverrideBoundaryCondition(&obc);
+ onit.GoToBegin();
+
+
+ // Paint input image translated with respect to the SE CCs vectors
+ // --> "( Xb0 UNION Xb1 UNION ... Xbn )"
+ typename Superclass::ComponentVectorConstIterator vecIt;
+ typename Superclass::ComponentVectorConstIterator vecBeginIt
+ = this->KernelCCVectorBegin();
+ typename Superclass::ComponentVectorConstIterator vecEndIt
+ = this->KernelCCVectorEnd();
+
+ // iterator on output image
+ itk::ImageRegionIteratorWithIndex<OutputImageType>
+ ouRegIndexIt(output, outputRegion );
+ ouRegIndexIt.GoToBegin();
+
+ // InputRegionForThread is the output region for thread padded by
+ // kerne lradius We must traverse this padded region because some
+ // border pixel in the added band ( the padded band is the region
+ // added after padding ) may be responsible to the painting of some
+ // pixel in the non padded region. This happens typically when a
+ // non centered SE is used, a kind of shift is done on the "on"
+ // pixels of image. Consequently some pixels in the added band can
+ // appear in the current region for thread due to shift effect.
+ typename InputImageType::RegionType inputRegionForThread = outputRegion;
+
+ // Pad the input region by the kernel
+ inputRegionForThread.PadByRadius( kernel.GetRadius() );
+ inputRegionForThread.Crop( input->GetBufferedRegion() );
+
+ if( !this->m_BoundaryToForeground )
+ {
+ while( !ouRegIndexIt.IsAtEnd() )
+ {
+ // Retrieve index of current output pixel
+ IndexType currentIndex = ouRegIndexIt.GetIndex();
+ for( vecIt = vecBeginIt; vecIt != vecEndIt; ++vecIt )
+ {
+ // Translate
+ IndexType translatedIndex = currentIndex - *vecIt;
+
+ // translated index now is an index in input image in the
+ // output requested region padded. Theoretically, this translated
+ // index must be inside the padded region.
+ // If the pixel in the input image at the translated index
+ // has a value equal to the dilate one, this means
+ // that the output pixel at currentIndex will be on in the output.
+ //JV != foregroundValue
+ if( !inputRegionForThread.IsInside( translatedIndex )
+ || input->GetPixel( translatedIndex ) == backgroundValue )
+ {
+ ouRegIndexIt.Set( backgroundValue );
+ break; // Do not need to examine other offsets because at least one
+ // input pixel has been translated on current output pixel.
+ }
+ }
+
+ ++ouRegIndexIt;
+ progress.CompletedPixel();
+ }
+ }
+ else
+ {
+ while( !ouRegIndexIt.IsAtEnd() )
+ {
+ IndexType currentIndex = ouRegIndexIt.GetIndex();
+ for( vecIt = vecBeginIt; vecIt != vecEndIt; ++vecIt )
+ {
+ IndexType translatedIndex = currentIndex - *vecIt;
+
+ if( inputRegionForThread.IsInside( translatedIndex )
+ //JV != foregroundValue
+ && input->GetPixel( translatedIndex ) == backgroundValue )
+ {
+ ouRegIndexIt.Set( backgroundValue );
+ break;
+ }
+ }
+
+ ++ouRegIndexIt;
+ progress.CompletedPixel();
+ }
+ }
+
+ // now, we must to restore the background values
+ itk::ImageRegionConstIterator<InputImageType> inIt( input, outputRegion );
+
+ for( inIt.GoToBegin(), outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt, ++inIt )
+ {
+ InputPixelType inValue = inIt.Get();
+ OutputPixelType outValue = outIt.Get();
+ // JV != foregroundValue
+ if ( outValue == backgroundValue && inValue == backgroundValue )
+ { outIt.Set( static_cast<OutputPixelType>( inValue ) ); }
+ progress.CompletedPixel();
+ }
+
+
+ }
+
+
+ /**
+ * Standard "PrintSelf" method
+ */
+ template <class TInputImage, class TOutput, class TKernel>
+ void
+ ConditionalBinaryErodeImageFilter<TInputImage, TOutput, TKernel>
+ ::PrintSelf( std::ostream& os, itk::Indent indent) const
+ {
+ Superclass::PrintSelf( os, indent );
+ os << indent << "Dilate Value: " << static_cast<typename itk::NumericTraits<InputPixelType>::PrintType>( this->GetForegroundValue() ) << std::endl;
+ }
+
+}//end clitk
+
+#endif //#define clitkConditionalBinaryErodeImageFilter_txx
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef __clitkLocallyAdaptiveBinaryThresholdImageFunction_h
+#define __clitkLocallyAdaptiveBinaryThresholdImageFunction_h
+#include "itkBinaryThresholdImageFunction.h"
+
+namespace clitk
+{
+
+template <class TInputImage, class TCoordRep = float >
+class ITK_EXPORT LocallyAdaptiveBinaryThresholdImageFunction :
+ public itk::BinaryThresholdImageFunction< TInputImage, TCoordRep >
+{
+public:
+ /** Standard class typedefs. */
+ typedef LocallyAdaptiveBinaryThresholdImageFunction Self;
+ typedef itk::BinaryThresholdImageFunction<TInputImage,TCoordRep> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ /** Run-time type information (and related methods). */
+ itkTypeMacro(LocallyAdaptiveBinaryThresholdImageFunction, BinaryThresholdImageFunction);
+
+ /** 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. */
+ typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
+
+ /** Point typedef support. */
+ typedef typename Superclass::PointType PointType;
+
+ /** PixelType typedef support. */
+ typedef typename Superclass::PixelType PixelType;
+
+ /** Dimension of the underlying image. */
+ itkStaticConstMacro(ImageDimension, unsigned int,
+ InputImageType::ImageDimension);
+
+ /** SizeType of the input image */
+ typedef typename InputImageType::SizeType InputSizeType;
+
+ /** Set the radius of the neighborhood used in computation. */
+ itkSetMacro(Radius, InputSizeType);
+
+ /** Get the radius of the neighborhood used in computation */
+ itkGetConstReferenceMacro(Radius, InputSizeType);
+
+ /** Evalulate the function at specified index */
+ virtual bool EvaluateAtIndex( const IndexType& index ) const;
+
+ /** Evaluate the function at non-integer positions */
+ virtual bool Evaluate( const PointType& point ) const
+ {
+ IndexType index;
+ this->ConvertPointToNearestIndex( point, index );
+ return this->EvaluateAtIndex( index );
+ }
+ virtual bool EvaluateAtContinuousIndex(
+ const ContinuousIndexType& cindex ) const
+ {
+ IndexType index;
+ this->ConvertContinuousIndexToNearestIndex( cindex, index );
+ return this->EvaluateAtIndex( index );
+ }
+
+ // JV
+ itkBooleanMacro(LowerBorderIsGiven);
+ itkSetMacro( LowerBorderIsGiven, bool);
+ itkGetConstReferenceMacro( LowerBorderIsGiven, bool);
+ itkBooleanMacro(UpperBorderIsGiven);
+ itkSetMacro( UpperBorderIsGiven, bool);
+ itkGetConstReferenceMacro( UpperBorderIsGiven, bool);
+ itkSetMacro( Multiplier, double);
+ itkGetConstMacro( Multiplier, double);
+ itkBooleanMacro(MaximumSDIsGiven);
+ itkSetMacro( MaximumSDIsGiven, bool);
+ itkGetConstReferenceMacro( MaximumSDIsGiven, bool);
+ itkSetMacro( MaximumSD, double);
+ itkGetConstMacro( MaximumSD, double);
+
+
+
+protected:
+ LocallyAdaptiveBinaryThresholdImageFunction();
+ ~LocallyAdaptiveBinaryThresholdImageFunction(){};
+ void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+ LocallyAdaptiveBinaryThresholdImageFunction( const Self& ); //purposely not implemented
+ void operator=( const Self& ); //purposely not implemented
+
+ InputSizeType m_Radius;
+
+ // JV
+ bool m_LowerBorderIsGiven;
+ bool m_UpperBorderIsGiven;
+ bool m_MaximumSDIsGiven;
+ double m_Multiplier;
+ double m_MaximumSD;
+
+};
+
+} // end namespace clitk
+
+// Define instantiation macro for this template.
+#define ITK_TEMPLATE_LocallyAdaptiveBinaryThresholdImageFunction(_, EXPORT, x, y) namespace itk { \
+ _(2(class EXPORT LocallyAdaptiveBinaryThresholdImageFunction< ITK_TEMPLATE_2 x >)) \
+ namespace Templates { typedef LocallyAdaptiveBinaryThresholdImageFunction< ITK_TEMPLATE_2 x > \
+ LocallyAdaptiveBinaryThresholdImageFunction##y; } \
+ }
+
+#if ITK_TEMPLATE_EXPLICIT
+# include "Templates/clitkLocallyAdaptiveBinaryThresholdImageFunction+-.h"
+#endif
+
+#if ITK_TEMPLATE_TXX
+# include "clitkLocallyAdaptiveBinaryThresholdImageFunction.txx"
+#endif
+
+/*
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkLocallyAdaptiveBinaryThresholdImageFunction.txx"
+#endif
+*/
+
+#endif
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef __clitkLocallyAdaptiveBinaryThresholdImageFunction_txx
+#define __clitkLocallyAdaptiveBinaryThresholdImageFunction_txx
+#include "clitkLocallyAdaptiveBinaryThresholdImageFunction.h"
+#include "itkNumericTraits.h"
+#include "itkConstNeighborhoodIterator.h"
+
+namespace clitk
+{
+
+ /**
+ * Constructor
+ */
+ template <class TInputImage, class TCoordRep>
+ LocallyAdaptiveBinaryThresholdImageFunction<TInputImage,TCoordRep>
+ ::LocallyAdaptiveBinaryThresholdImageFunction()
+ {
+ m_Radius.Fill(1);
+ m_LowerBorderIsGiven=true;
+ m_UpperBorderIsGiven=true;
+ m_MaximumSDIsGiven=true;
+ m_Multiplier=1.0;
+ m_MaximumSD=100.0;
+ }
+
+
+ /**
+ *
+ */
+ template <class TInputImage, class TCoordRep>
+ void
+ LocallyAdaptiveBinaryThresholdImageFunction<TInputImage,TCoordRep>
+ ::PrintSelf(std::ostream& os, itk::Indent indent) const
+ {
+ this->Superclass::PrintSelf(os,indent);
+
+ os << indent << "Radius: " << m_Radius << std::endl;
+ }
+
+
+ /**
+ *
+ */
+ template <class TInputImage, class TCoordRep>
+ bool
+ LocallyAdaptiveBinaryThresholdImageFunction<TInputImage,TCoordRep>
+ ::EvaluateAtIndex(const IndexType& index) const
+ {
+
+ if( !this->GetInputImage() )
+ {
+ return ( false );
+ }
+
+ if ( !this->IsInsideBuffer( index ) )
+ {
+ return ( false );
+ }
+
+ // Create an N-d neighborhood kernel, using a zeroflux boundary condition
+ itk::ConstNeighborhoodIterator<InputImageType>
+ it(m_Radius, this->GetInputImage(), this->GetInputImage()->GetBufferedRegion());
+
+ // Set the iterator at the desired location
+ it.SetLocation(index);
+ PixelType centerValue = it.GetPixel(0);
+ PixelType currentvalue;
+ bool isInside=true;
+
+ // Walk the neighborhood for the mean and SD
+ const unsigned int size = it.Size();
+ typename itk::NumericTraits<PixelType>::RealType mean=0;
+ typename itk::NumericTraits<PixelType>::RealType sd=0;
+ for (unsigned int i = 1; i < size; ++i)
+ {
+ currentvalue=it.GetPixel(i);
+ mean+=currentvalue;
+ sd+=currentvalue*currentvalue;
+ }
+ mean/=( typename itk::NumericTraits<PixelType>::RealType) size-1.;
+ sd= sqrt( (sd /(typename itk::NumericTraits<PixelType>::RealType)size-1.) - (mean*mean) );
+
+ // Verify fixed borders
+ if (this->GetLower() > centerValue || centerValue > this->GetUpper())
+ isInside = false;
+
+ // Verify lower adaptive borders
+ if( (m_LowerBorderIsGiven) && (centerValue < ( mean - (typename itk::NumericTraits<PixelType>::RealType) ( m_Multiplier*sd) ) ) )
+ isInside = false;
+
+ // Verify upper adaptive border
+ if ( (m_UpperBorderIsGiven) && (centerValue > ( mean + (typename itk::NumericTraits<PixelType>::RealType) ( m_Multiplier*sd) ) ) )
+ isInside = false;
+
+ // Verify SD
+ if ( (m_MaximumSDIsGiven) && ( sd> m_MaximumSD) )
+ isInside=false;
+
+// DD(centerValue);
+// DD(mean);
+// DD(sd);
+// DD(isInside);
+
+ return ( isInside );
+ }
+
+
+} // end namespace itk
+
+#endif
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef __clitkLocallyAdaptiveThresholdConnectedImageFilter_h
+#define __clitkLocallyAdaptiveThresholdConnectedImageFilter_h
+#include "itkImage.h"
+#include "itkImageToImageFilter.h"
+
+namespace clitk {
+
+/** \class LocallyAdaptiveThresholdConnectedImageFilter
+ * \brief Label pixels that are connected to a seed and lie within a neighborhood
+ *
+ * LocallyAdaptiveThresholdConnectedImageFilter labels pixels with ReplaceValue that
+ * are connected to an initial Seed AND whose neighbors all lie within a
+ * Lower and Upper threshold range.
+ *
+ * \ingroup RegionGrowingSegmentation
+ */
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT LocallyAdaptiveThresholdConnectedImageFilter:
+ public itk::ImageToImageFilter<TInputImage,TOutputImage>
+{
+public:
+ /** Standard class typedefs. */
+ typedef LocallyAdaptiveThresholdConnectedImageFilter Self;
+ typedef itk::ImageToImageFilter<TInputImage,TOutputImage> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ /** Method for creation through the object factory. */
+ itkNewMacro(Self);
+
+ /** Run-time type information (and related methods). */
+ itkTypeMacro(LocallyAdaptiveThresholdConnectedImageFilter,
+ ImageToImageFilter);
+
+ typedef TInputImage InputImageType;
+ typedef typename InputImageType::Pointer InputImagePointer;
+ typedef typename InputImageType::RegionType InputImageRegionType;
+ typedef typename InputImageType::PixelType InputImagePixelType;
+ typedef typename InputImageType::IndexType IndexType;
+ typedef typename InputImageType::SizeType InputImageSizeType;
+
+ typedef TOutputImage OutputImageType;
+ typedef typename OutputImageType::Pointer OutputImagePointer;
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+ typedef typename OutputImageType::PixelType OutputImagePixelType;
+
+ void PrintSelf ( std::ostream& os, itk::Indent indent ) const;
+
+ /** Clear the seeds */
+ void ClearSeeds();
+
+ /** Set seed point. */
+ void SetSeed(const IndexType & seed);
+
+ /** Add a seed point */
+ void AddSeed ( const IndexType & seed );
+
+ // Set/Get the lower threshold. The default is 0.
+ itkSetMacro(Lower, InputImagePixelType);
+ itkGetConstMacro(Lower, InputImagePixelType);
+
+ // Set/Get the upper threshold. The default is the largest possible value for the InputPixelType.
+ itkSetMacro(Upper, InputImagePixelType);
+ itkGetConstMacro(Upper, InputImagePixelType);
+
+ /** Set/Get value to replace thresholded pixels. Pixels that lie *
+ * within Lower and Upper (inclusive) will be replaced with this
+ * value. The default is 1. */
+ itkSetMacro(ReplaceValue, OutputImagePixelType);
+ itkGetConstMacro(ReplaceValue, OutputImagePixelType);
+
+ /** Set the radius of the neighborhood used for a mask. */
+ itkSetMacro(Radius, InputImageSizeType);
+
+ /** Get the radius of the neighborhood used to compute the median */
+ itkGetConstReferenceMacro(Radius, InputImageSizeType);
+
+ /** ImageDimension constants */
+ itkStaticConstMacro(InputImageDimension, unsigned int,
+ TInputImage::ImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int,
+ TOutputImage::ImageDimension);
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+ /** Begin concept checking */
+ itkConceptMacro(InputEqualityComparableCheck,
+ (itk::Concept::EqualityComparable<InputImagePixelType>));
+ itkConceptMacro(OutputEqualityComparableCheck,
+ (itk::Concept::EqualityComparable<OutputImagePixelType>));
+ itkConceptMacro(SameDimensionCheck,
+ (itk::Concept::SameDimension<InputImageDimension, OutputImageDimension>));
+ itkConceptMacro(InputOStreamWritableCheck,
+ (itk::Concept::OStreamWritable<InputImagePixelType>));
+ itkConceptMacro(OutputOStreamWritableCheck,
+ (itk::Concept::OStreamWritable<OutputImagePixelType>));
+ /** End concept checking */
+#endif
+
+ // JV
+ itkBooleanMacro(LowerBorderIsGiven);
+ itkSetMacro( LowerBorderIsGiven, bool);
+ itkGetConstReferenceMacro( LowerBorderIsGiven, bool);
+ itkBooleanMacro(UpperBorderIsGiven);
+ itkSetMacro( UpperBorderIsGiven, bool);
+ itkGetConstReferenceMacro( UpperBorderIsGiven, bool);
+ itkSetMacro( Multiplier, double);
+ itkGetConstMacro( Multiplier, double);
+ itkBooleanMacro(MaximumSDIsGiven);
+ itkSetMacro( MaximumSDIsGiven, bool);
+ itkGetConstReferenceMacro( MaximumSDIsGiven, bool);
+ itkSetMacro( MaximumSD, double);
+ itkGetConstMacro( MaximumSD, double);
+
+protected:
+ LocallyAdaptiveThresholdConnectedImageFilter();
+ ~LocallyAdaptiveThresholdConnectedImageFilter(){};
+ std::vector<IndexType> m_Seeds;
+ InputImagePixelType m_Lower;
+ InputImagePixelType m_Upper;
+ OutputImagePixelType m_ReplaceValue;
+ InputImageSizeType m_Radius;
+
+ // JV
+ bool m_LowerBorderIsGiven;
+ bool m_UpperBorderIsGiven;
+ bool m_MaximumSDIsGiven;
+ double m_Multiplier;
+ double m_MaximumSD;
+
+ // Override since the filter needs all the data for the algorithm
+ void GenerateInputRequestedRegion();
+
+ // Override since the filter produces the entire dataset
+ void EnlargeOutputRequestedRegion(itk::DataObject *output);
+ void GenerateData();
+
+private:
+ LocallyAdaptiveThresholdConnectedImageFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+};
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkLocallyAdaptiveThresholdConnectedImageFilter.txx"
+#endif
+
+#endif
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef __clitkLocallyAdaptiveThresholdConnectedImageFilter_txx
+#define __clitkLocallyAdaptiveThresholdConnectedImageFilter_txx
+#include "clitkLocallyAdaptiveThresholdConnectedImageFilter.h"
+#include "clitkLocallyAdaptiveBinaryThresholdImageFunction.h"
+#include "itkFloodFilledImageFunctionConditionalIterator.h"
+#include "itkProgressReporter.h"
+
+namespace clitk
+{
+
+/**
+ * Constructor
+ */
+template <class TInputImage, class TOutputImage>
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage, TOutputImage>
+::LocallyAdaptiveThresholdConnectedImageFilter()
+{
+ m_Lower = itk::NumericTraits<InputImagePixelType>::NonpositiveMin();
+ m_Upper = itk::NumericTraits<InputImagePixelType>::max();
+ m_LowerBorderIsGiven=true;
+ m_UpperBorderIsGiven=true;
+ m_MaximumSDIsGiven=true;
+ m_Multiplier=1.0;
+ m_ReplaceValue = itk::NumericTraits<OutputImagePixelType>::One;
+ m_Radius.Fill(1);
+ m_MaximumSD=100.0;
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage, TOutputImage>
+::ClearSeeds()
+{
+ if( this->m_Seeds.size() > 0 )
+ {
+ this->m_Seeds.clear();
+ this->Modified();
+ }
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage, TOutputImage>
+::SetSeed(const IndexType & seed)
+{
+ this->ClearSeeds();
+ this->AddSeed ( seed );
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage, TOutputImage>
+::AddSeed ( const IndexType & seed )
+{
+ this->m_Seeds.push_back ( seed );
+ this->Modified();
+}
+
+/**
+ * Standard PrintSelf method.
+ */
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage, TOutputImage>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+ this->Superclass::PrintSelf(os, indent);
+ os << indent << "Upper: "
+ << static_cast<typename itk::NumericTraits<InputImagePixelType>::PrintType>(m_UpperBorderIsGiven)
+ << std::endl;
+ os << indent << "Lower: "
+ << static_cast<typename itk::NumericTraits<InputImagePixelType>::PrintType>(m_LowerBorderIsGiven)
+ << std::endl;
+ os << indent << "ReplaceValue: "
+ << static_cast<double>(m_Multiplier)
+ << std::endl;
+ os << indent << "ReplaceValue: "
+ << static_cast<typename itk::NumericTraits<OutputImagePixelType>::PrintType>(m_ReplaceValue)
+ << std::endl;
+ os << indent << "Radius: " << m_Radius << std::endl;
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage,TOutputImage>
+::GenerateInputRequestedRegion()
+{
+ Superclass::GenerateInputRequestedRegion();
+ if ( this->GetInput() )
+ {
+ InputImagePointer image =
+ const_cast< InputImageType * >( this->GetInput() );
+ image->SetRequestedRegionToLargestPossibleRegion();
+ }
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage,TOutputImage>
+::EnlargeOutputRequestedRegion(itk::DataObject *output)
+{
+ Superclass::EnlargeOutputRequestedRegion(output);
+ output->SetRequestedRegionToLargestPossibleRegion();
+}
+
+template <class TInputImage, class TOutputImage>
+void
+LocallyAdaptiveThresholdConnectedImageFilter<TInputImage,TOutputImage>
+::GenerateData()
+{
+ typename Superclass::InputImageConstPointer inputImage = this->GetInput();
+ typename Superclass::OutputImagePointer outputImage = this->GetOutput();
+
+ // Zero the output
+ outputImage->SetBufferedRegion( outputImage->GetRequestedRegion() );
+ outputImage->Allocate();
+ outputImage->FillBuffer ( itk::NumericTraits<OutputImagePixelType>::Zero );
+
+ typedef LocallyAdaptiveBinaryThresholdImageFunction<InputImageType> FunctionType;
+ typedef itk::FloodFilledImageFunctionConditionalIterator<OutputImageType, FunctionType> IteratorType;
+
+ typename FunctionType::Pointer function = FunctionType::New();
+ function->SetInputImage ( inputImage );
+ function->SetLowerBorderIsGiven ( m_LowerBorderIsGiven );
+ function->SetUpperBorderIsGiven ( m_UpperBorderIsGiven );
+ function->SetMaximumSDIsGiven ( m_MaximumSDIsGiven );
+ function->ThresholdBetween ( m_Lower, m_Upper );
+ function->SetMultiplier ( m_Multiplier );
+ function->SetMaximumSD ( m_MaximumSD );
+ function->SetRadius (m_Radius);
+
+ IteratorType it = IteratorType ( outputImage, function, m_Seeds );
+ itk::ProgressReporter progress( this, 0, outputImage->GetRequestedRegion().GetNumberOfPixels());
+
+ while( !it.IsAtEnd())
+ {
+ it.Set(m_ReplaceValue);
+ ++it;
+ progress.CompletedPixel();
+ }
+}
+
+
+} // end namespace clitk
+
+#endif
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkVectorImageToImageFilter_h
+#define clitkVectorImageToImageFilter_h
+
+/* =================================================
+ * @file clitkVectorImageToImageFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+
+//itk include
+#include "itkImageToImageFilter.h"
+
+namespace clitk
+{
+
+ template <class InputImageType, class OutputImageType>
+ class ITK_EXPORT VectorImageToImageFilter :
+ public itk::ImageToImageFilter<InputImageType, OutputImageType>
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef VectorImageToImageFilter Self;
+ typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ // Method for creation through the object factory
+ itkNewMacro(Self);
+
+ // Run-time type information (and related methods)
+ itkTypeMacro( VectorImageToImageFilter, ImageToImageFilter );
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ itkBooleanMacro(Verbose);
+ itkSetMacro( Verbose, bool);
+ itkGetConstReferenceMacro( Verbose, bool);
+ itkSetMacro(ComponentIndex, unsigned int);
+ itkGetConstMacro(ComponentIndex, unsigned int);
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ VectorImageToImageFilter();
+ ~VectorImageToImageFilter() {};
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ unsigned int m_ComponentIndex;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkVectorImageToImageFilter.txx"
+#endif
+
+#endif // #define clitkVectorImageToImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkVectorImageToImageFilter_txx
+#define clitkVectorImageToImageFilter_txx
+
+/* =================================================
+ * @file clitkVectorImageToImageFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Constructor
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ VectorImageToImageFilter<InputImageType, OutputImageType>::VectorImageToImageFilter()
+ {
+ m_Verbose=false;
+ m_ComponentIndex=0;
+ }
+
+
+ //-------------------------------------------------------------------
+ // Generate Data
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ void
+ VectorImageToImageFilter<InputImageType, OutputImageType>::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId)
+ {
+ // Iterators
+ typename OutputImageType::Pointer output=this->GetOutput();
+ typename InputImageType::ConstPointer input=this->GetInput();
+
+ typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType;
+ InputIteratorType inputIt (input, outputRegionForThread);
+
+ typedef itk::ImageRegionIterator<OutputImageType> OutputIteratorType;
+ OutputIteratorType outputIt (output, outputRegionForThread);
+
+ while(! inputIt.IsAtEnd() )
+ {
+ outputIt.Set(inputIt.Get()[m_ComponentIndex]);
+ ++outputIt;
+ ++inputIt;
+ }
+ }
+
+
+}//end clitk
+
+#endif //#define clitkVectorImageToImageFilter_txx