00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __itkConnectedComponentImageFilter_h
00019 #define __itkConnectedComponentImageFilter_h
00020
00021 #include "itkImageToImageFilter.h"
00022 #include "itkImage.h"
00023 #include "itkConceptChecking.h"
00024 #include <vector>
00025 #include <map>
00026 #include "itkProgressReporter.h"
00027 #include "itkBarrier.h"
00028
00029 namespace itk
00030 {
00031
00052 template <class TInputImage, class TOutputImage, class TMaskImage=TInputImage>
00053 class ITK_EXPORT ConnectedComponentImageFilter :
00054 public ImageToImageFilter< TInputImage, TOutputImage >
00055 {
00056 public:
00060 typedef ConnectedComponentImageFilter Self;
00061 typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass;
00062
00066 typedef typename Superclass::InputImagePointer InputImagePointer;
00067
00072 typedef typename TOutputImage::PixelType OutputPixelType;
00073 typedef typename TOutputImage::InternalPixelType OutputInternalPixelType;
00074 typedef typename TInputImage::PixelType InputPixelType;
00075 typedef typename TInputImage::InternalPixelType InputInternalPixelType;
00076 typedef typename TMaskImage::PixelType MaskPixelType;
00077 itkStaticConstMacro(ImageDimension, unsigned int,
00078 TOutputImage::ImageDimension);
00079 itkStaticConstMacro(OutputImageDimension, unsigned int,
00080 TOutputImage::ImageDimension);
00081 itkStaticConstMacro(InputImageDimension, unsigned int,
00082 TInputImage::ImageDimension);
00084
00088 typedef TInputImage InputImageType;
00089 typedef TMaskImage MaskImageType;
00090 typedef typename TInputImage::IndexType IndexType;
00091 typedef typename TInputImage::SizeType SizeType;
00092 typedef typename TInputImage::OffsetType OffsetType;
00093
00094 typedef TOutputImage OutputImageType;
00095 typedef typename TOutputImage::RegionType RegionType;
00096 typedef typename TOutputImage::IndexType OutputIndexType;
00097 typedef typename TOutputImage::SizeType OutputSizeType;
00098 typedef typename TOutputImage::OffsetType OutputOffsetType;
00099 typedef typename TOutputImage::PixelType OutputImagePixelType;
00100
00101 typedef std::list<IndexType> ListType;
00102 typedef typename MaskImageType::Pointer MaskImagePointer;
00103
00107 typedef SmartPointer<Self> Pointer;
00108 typedef SmartPointer<const Self> ConstPointer;
00109
00113 itkTypeMacro(ConnectedComponentImageFilter, ImageToImageFilter);
00114
00118 itkNewMacro(Self);
00119
00126 itkSetMacro(FullyConnected, bool);
00127 itkGetConstReferenceMacro(FullyConnected, bool);
00128 itkBooleanMacro(FullyConnected);
00130
00131
00132 itkGetConstReferenceMacro(ObjectCount, unsigned long);
00133
00134
00135 itkConceptMacro(SameDimension,
00136 (Concept::SameDimension<itkGetStaticConstMacro(InputImageDimension),
00137 itkGetStaticConstMacro(OutputImageDimension)>));
00138
00139
00140 void SetMaskImage(TMaskImage* mask)
00141 {
00142 this->SetNthInput(1, const_cast<TMaskImage *>( mask ));
00143 }
00144
00145 const TMaskImage* GetMaskImage() const
00146 {
00147 return (static_cast<const TMaskImage*>(this->ProcessObject::GetInput(1)));
00148 }
00149
00152 itkSetMacro(BackgroundValue, OutputImagePixelType);
00153 itkGetMacro(BackgroundValue, OutputImagePixelType);
00155
00156 protected:
00157 ConnectedComponentImageFilter()
00158 {
00159 m_FullyConnected = false;
00160 m_ObjectCount = 0;
00161 m_BackgroundValue = NumericTraits< OutputImagePixelType >::Zero;
00162 }
00163 virtual ~ConnectedComponentImageFilter() {}
00164 ConnectedComponentImageFilter(const Self&) {}
00165 void PrintSelf(std::ostream& os, Indent indent) const;
00166
00170 void BeforeThreadedGenerateData ();
00171 void AfterThreadedGenerateData ();
00172 void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId);
00174
00178 void GenerateInputRequestedRegion();
00179
00184 void EnlargeOutputRequestedRegion(DataObject *itkNotUsed(output));
00185
00186 bool m_FullyConnected;
00187
00188 private:
00189 unsigned long m_ObjectCount;
00190 OutputImagePixelType m_BackgroundValue;
00191
00192
00193 typedef typename TOutputImage::RegionType::SizeType OutSizeType;
00194
00195
00196 class runLength
00197 {
00198 public:
00199
00200 long int length;
00201 typename InputImageType::IndexType where;
00202 unsigned long int label;
00203 };
00204
00205 typedef std::vector<runLength> lineEncoding;
00206
00207
00208 typedef std::vector<lineEncoding> LineMapType;
00209
00210 typedef std::vector<long> OffsetVec;
00211
00212
00213 typedef std::vector<unsigned long int> UnionFindType;
00214 UnionFindType m_UnionFind;
00215 UnionFindType m_Consecutive;
00216
00217 void InitUnion(const unsigned long int size)
00218 {
00219 m_UnionFind = UnionFindType(size + 1);
00220 }
00221 void InsertSet(const unsigned long int label);
00222 unsigned long int LookupSet(const unsigned long int label);
00223 void LinkLabels(const unsigned long int lab1, const unsigned long int lab2);
00224 unsigned long int CreateConsecutive();
00226 bool CheckNeighbors(const OutputIndexType &A,
00227 const OutputIndexType &B);
00228
00229 void CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour);
00230
00231 void FillOutput(const LineMapType &LineMap,
00232 ProgressReporter &progress);
00233
00234 void SetupLineOffsets(OffsetVec &LineOffsets);
00235
00236 void Wait()
00237 {
00238
00239 if( m_NumberOfLabels.size() > 1 )
00240 {
00241 m_Barrier->Wait();
00242 }
00243 }
00244
00245 typename std::vector< long > m_NumberOfLabels;
00246 typename std::vector< long > m_FirstLineIdToJoin;
00247 typename Barrier::Pointer m_Barrier;
00248 typename TInputImage::ConstPointer m_Input;
00249 #if !defined(CABLE_CONFIGURATION)
00250 LineMapType m_LineMap;
00251 #endif
00252 };
00253
00254 }
00255
00256 #ifndef ITK_MANUAL_INSTANTIATION
00257 #if !defined(CABLE_CONFIGURATION)
00258 #include "itkConnectedComponentImageFilter.txx"
00259 #endif
00260 #endif
00261
00262 #endif
00263