/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkLabelContourImageFilter.h,v $ Language: C++ Date: $Date: 2007/10/05 10:31:58 $ Version: $Revision: 1.17 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 __itkLabelContourImageFilter_h #define __itkLabelContourImageFilter_h #include "itkInPlaceImageFilter.h" #include "itkImage.h" #include "itkConceptChecking.h" #include #include #include "itkProgressReporter.h" #include "itkBarrier.h" namespace itk { /** * \class LabelContourImageFilter * \brief Give the pixels on the border of an object. * * LabelContourImageFilter labels the pixels on the borders * of the objects in a binary image. * * \sa ImageToImageFilter */ template class ITK_EXPORT LabelContourImageFilter : public InPlaceImageFilter< TInputImage, TOutputImage > { public: /** * Standard "Self" & Superclass typedef. */ typedef LabelContourImageFilter Self; typedef InPlaceImageFilter< TInputImage, TOutputImage > Superclass; /** * Types from the Superclass */ typedef typename Superclass::InputImagePointer InputImagePointer; /** * Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef typename TOutputImage::PixelType OutputPixelType; typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::InternalPixelType InputInternalPixelType; itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); /** * Image typedef support */ typedef TInputImage InputImageType; typedef typename TInputImage::IndexType IndexType; typedef typename TInputImage::SizeType SizeType; typedef typename TInputImage::OffsetType OffsetType; typedef typename TInputImage::PixelType InputImagePixelType; typedef TOutputImage OutputImageType; typedef typename TOutputImage::RegionType RegionType; typedef typename TOutputImage::IndexType OutputIndexType; typedef typename TOutputImage::SizeType OutputSizeType; typedef typename TOutputImage::OffsetType OutputOffsetType; typedef typename TOutputImage::PixelType OutputImagePixelType; typedef std::list ListType; /** * Smart pointer typedef support */ typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Run-time type information (and related methods) */ itkTypeMacro(LabelContourImageFilter, ImageToImageFilter); /** * Method for creation through the object factory. */ itkNewMacro(Self); /** * Set/Get whether the connected components are defined strictly by * face connectivity or by face+edge+vertex connectivity. Default is * FullyConnectedOff. For objects that are 1 pixel wide, use * FullyConnectedOn. */ itkSetMacro(FullyConnected, bool); itkGetConstReferenceMacro(FullyConnected, bool); itkBooleanMacro(FullyConnected); // Concept checking -- input and output dimensions must be the same itkConceptMacro(SameDimension, (Concept::SameDimension)); /** */ itkSetMacro(BackgroundValue, OutputImagePixelType); itkGetMacro(BackgroundValue, OutputImagePixelType); protected: LabelContourImageFilter() { m_FullyConnected = false; m_BackgroundValue = NumericTraits< OutputImagePixelType >::Zero; m_NumberOfThreads = 0; this->SetInPlace( false ); } virtual ~LabelContourImageFilter() {} LabelContourImageFilter(const Self&) {} void PrintSelf(std::ostream& os, Indent indent) const; /** * Standard pipeline methods. */ void BeforeThreadedGenerateData (); void AfterThreadedGenerateData (); void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId); /** LabelContourImageFilter needs the entire input. Therefore * it must provide an implementation GenerateInputRequestedRegion(). * \sa ProcessObject::GenerateInputRequestedRegion(). */ void GenerateInputRequestedRegion(); /** LabelContourImageFilter will produce all of the output. * Therefore it must provide an implementation of * EnlargeOutputRequestedRegion(). * \sa ProcessObject::EnlargeOutputRequestedRegion() */ void EnlargeOutputRequestedRegion(DataObject *itkNotUsed(output)); private: OutputImagePixelType m_BackgroundValue; bool m_FullyConnected; // some additional types typedef typename TOutputImage::RegionType::SizeType OutSizeType; // types to support the run length encoding of lines class runLength { public: // run length information - may be a more type safe way of doing this long int length; typename InputImageType::IndexType where; // Index of the start of the run InputImagePixelType label; }; typedef std::vector lineEncoding; // the map storing lines typedef std::vector LineMapType; typedef std::vector OffsetVec; // the types to support union-find operations typedef std::vector UnionFindType; bool CheckNeighbors(const OutputIndexType &A, const OutputIndexType &B); void CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour); void SetupLineOffsets(OffsetVec &LineOffsets); void Wait() { if( m_NumberOfThreads > 1 ) { m_Barrier->Wait(); } } typename Barrier::Pointer m_Barrier; LineMapType m_LineMap; long m_NumberOfThreads; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLabelContourImageFilter.txx" #endif #endif