ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkConnectedComponentImageFilter_h 00019 #define __itkConnectedComponentImageFilter_h 00020 00021 #include "itkImageToImageFilter.h" 00022 #include "itkImage.h" 00023 #include <vector> 00024 #include <map> 00025 #include "itkProgressReporter.h" 00026 #include "itkBarrier.h" 00027 00028 namespace itk 00029 { 00054 template< class TInputImage, class TOutputImage, class TMaskImage = TInputImage > 00055 class ITK_EXPORT ConnectedComponentImageFilter: 00056 public ImageToImageFilter< TInputImage, TOutputImage > 00057 { 00058 public: 00062 typedef ConnectedComponentImageFilter Self; 00063 typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; 00064 00068 typedef typename Superclass::InputImagePointer InputImagePointer; 00069 00074 typedef typename TOutputImage::PixelType OutputPixelType; 00075 typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; 00076 typedef typename TInputImage::PixelType InputPixelType; 00077 typedef typename TInputImage::InternalPixelType InputInternalPixelType; 00078 typedef typename TMaskImage::PixelType MaskPixelType; 00079 itkStaticConstMacro(ImageDimension, unsigned int, 00080 TOutputImage::ImageDimension); 00081 itkStaticConstMacro(OutputImageDimension, unsigned int, 00082 TOutputImage::ImageDimension); 00083 itkStaticConstMacro(InputImageDimension, unsigned int, 00084 TInputImage::ImageDimension); 00086 00090 typedef TInputImage InputImageType; 00091 typedef TMaskImage MaskImageType; 00092 typedef typename TInputImage::IndexType IndexType; 00093 typedef typename TInputImage::SizeType SizeType; 00094 typedef typename TInputImage::OffsetType OffsetType; 00095 00096 typedef TOutputImage OutputImageType; 00097 typedef typename TOutputImage::RegionType RegionType; 00098 typedef typename TOutputImage::IndexType OutputIndexType; 00099 typedef typename TOutputImage::SizeType OutputSizeType; 00100 typedef typename TOutputImage::OffsetType OutputOffsetType; 00101 typedef typename TOutputImage::PixelType OutputImagePixelType; 00102 00103 typedef std::list< IndexType > ListType; 00104 typedef typename MaskImageType::Pointer MaskImagePointer; 00105 00109 typedef SmartPointer< Self > Pointer; 00110 typedef SmartPointer< const Self > ConstPointer; 00111 00115 itkTypeMacro(ConnectedComponentImageFilter, ImageToImageFilter); 00116 00120 itkNewMacro(Self); 00121 00128 itkSetMacro(FullyConnected, bool); 00129 itkGetConstReferenceMacro(FullyConnected, bool); 00130 itkBooleanMacro(FullyConnected); 00132 00134 typedef IdentifierType LabelType; 00135 00136 // only set after completion 00137 itkGetConstReferenceMacro(ObjectCount, LabelType); 00138 00139 // Concept checking -- input and output dimensions must be the same 00140 itkConceptMacro( SameDimension, 00141 ( Concept::SameDimension< itkGetStaticConstMacro(InputImageDimension), 00142 itkGetStaticConstMacro(OutputImageDimension) > ) ); 00143 itkConceptMacro( OutputImagePixelTypeIsInteger, ( Concept::IsInteger< OutputImagePixelType > ) ); 00144 00145 void SetMaskImage(TMaskImage *mask) 00146 { 00147 this->SetNthInput( 1, const_cast< TMaskImage * >( mask ) ); 00148 } 00149 00150 const TMaskImage * GetMaskImage() const 00151 { 00152 return ( static_cast< const TMaskImage * >( this->ProcessObject::GetInput(1) ) ); 00153 } 00154 00157 itkSetMacro(BackgroundValue, OutputImagePixelType); 00158 itkGetConstMacro(BackgroundValue, OutputImagePixelType); 00159 protected: 00160 ConnectedComponentImageFilter() 00161 { 00162 m_FullyConnected = false; 00163 m_ObjectCount = 0; 00164 m_BackgroundValue = NumericTraits< OutputImagePixelType >::Zero; 00165 } 00167 00168 virtual ~ConnectedComponentImageFilter() {} 00169 void PrintSelf(std::ostream & os, Indent indent) const; 00170 00174 void BeforeThreadedGenerateData(); 00175 00176 void AfterThreadedGenerateData(); 00177 00178 void ThreadedGenerateData(const RegionType & outputRegionForThread, ThreadIdType threadId); 00179 00183 void GenerateInputRequestedRegion(); 00184 00189 void EnlargeOutputRequestedRegion( DataObject * itkNotUsed(output) ); 00190 00191 bool m_FullyConnected; 00192 private: 00193 ConnectedComponentImageFilter(const Self &); //purposely not implemented 00194 void operator=(const Self &); //purposely not implemented 00195 00196 LabelType m_ObjectCount; 00197 OutputImagePixelType m_BackgroundValue; 00198 00199 // some additional types 00200 typedef typename TOutputImage::RegionType::SizeType OutSizeType; 00201 00202 // types to support the run length encoding of lines 00203 class runLength 00204 { 00205 public: 00206 // run length information - may be a more type safe way of doing this 00207 typename TInputImage::OffsetValueType length; 00208 typename TInputImage::IndexType where; // Index of the start of the run 00209 LabelType label; // the initial label of the run 00210 }; 00211 00212 typedef std::vector< runLength > lineEncoding; 00213 00214 // the map storing lines 00215 typedef std::vector< lineEncoding > LineMapType; 00216 00217 typedef std::vector< typename TInputImage::OffsetValueType > OffsetVec; 00218 00219 // the types to support union-find operations 00220 typedef std::vector< LabelType > UnionFindType; 00221 UnionFindType m_UnionFind; 00222 UnionFindType m_Consecutive; 00223 00224 // functions to support union-find operations 00225 void InitUnion( SizeValueType size ) 00226 { 00227 m_UnionFind = UnionFindType(size + 1); 00228 } 00229 00230 void InsertSet(const LabelType label); 00231 00232 SizeValueType LookupSet(const LabelType label); 00233 00234 void LinkLabels(const LabelType lab1, const LabelType lab2); 00235 00236 SizeValueType CreateConsecutive(); 00237 00239 bool CheckNeighbors(const OutputIndexType & A, 00240 const OutputIndexType & B); 00241 00242 void CompareLines(lineEncoding & current, const lineEncoding & Neighbour); 00243 00244 void FillOutput(const LineMapType & LineMap, 00245 ProgressReporter & progress); 00246 00247 void SetupLineOffsets(OffsetVec & LineOffsets); 00248 00249 void Wait() 00250 { 00251 // use m_NumberOfLabels.size() to get the number of thread used 00252 if ( m_NumberOfLabels.size() > 1 ) 00253 { 00254 m_Barrier->Wait(); 00255 } 00256 } 00257 00258 typename std::vector< IdentifierType > m_NumberOfLabels; 00259 typename std::vector< IdentifierType > m_FirstLineIdToJoin; 00260 00261 typename Barrier::Pointer m_Barrier; 00262 00263 typename TInputImage::ConstPointer m_Input; 00264 #if !defined( CABLE_CONFIGURATION ) 00265 LineMapType m_LineMap; 00266 #endif 00267 }; 00268 } // end namespace itk 00269 00270 #ifndef ITK_MANUAL_INSTANTIATION 00271 #if !defined( CABLE_CONFIGURATION ) 00272 #include "itkConnectedComponentImageFilter.hxx" 00273 #endif 00274 #endif 00275 00276 #endif 00277