00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkWatershedSegmenter_h
00018 #define __itkWatershedSegmenter_h
00019
00020 #if defined(_MSC_VER)
00021 #pragma warning ( disable : 4786 )
00022 #endif
00023
00024 #include "itk_hash_map.h"
00025 #include "itkWatershedBoundary.h"
00026 #include "itkWatershedSegmentTable.h"
00027 #include "itkEquivalencyTable.h"
00028 #include "itkImage.h"
00029
00030 namespace itk
00031 {
00032 namespace watershed
00033 {
00089 template <class TInputImage>
00090 class ITK_EXPORT Segmenter
00091 : public ProcessObject
00092 {
00093 public:
00095 typedef Segmenter Self;
00096
00098 typedef TInputImage InputImageType;
00099 itkStaticConstMacro(ImageDimension, unsigned int,
00100 TInputImage::ImageDimension);
00101 typedef Image<unsigned long, itkGetStaticConstMacro(ImageDimension)> OutputImageType;
00102 typedef typename InputImageType::RegionType ImageRegionType;
00103 typedef typename InputImageType::PixelType InputPixelType;
00104 typedef Boundary<InputPixelType, itkGetStaticConstMacro(ImageDimension)> BoundaryType;
00105 typedef typename BoundaryType::IndexType BoundaryIndexType;
00106 typedef typename BoundaryType::FlatHashValueType BoundaryFlatHashValueType;
00107 typedef SegmentTable<InputPixelType> SegmentTableType;
00108 typedef DataObject::Pointer DataObjectPointer;
00109
00112 typedef ProcessObject Superclass;
00113 typedef SmartPointer<Self> Pointer;
00114 typedef SmartPointer<const Self> ConstPointer;
00115 itkNewMacro(Self);
00116 itkTypeMacro(Segmenter, ProcessObject);
00117
00119 typedef typename InputImageType::Pointer InputImageTypePointer;
00120 typedef typename OutputImageType::Pointer OutputImageTypePointer;
00121 typedef typename SegmentTableType::Pointer SegmentTableTypePointer;
00122 typedef typename BoundaryType::Pointer BoundaryTypePointer;
00123
00125 static unsigned long NULL_LABEL;
00126
00128 static short NULL_FLOW;
00129
00131 InputImageType * GetInputImage(void)
00132 { return static_cast<InputImageType *>
00133 (this->ProcessObject::GetInput(0)); }
00134 void SetInputImage(InputImageType *img)
00135 { this->ProcessObject::SetNthInput(0, img); }
00136
00139 OutputImageType * GetOutputImage(void)
00140 { return static_cast<OutputImageType *>
00141 (this->ProcessObject::GetOutput(0)); }
00142 void SetOutputImage(OutputImageType *img)
00143 { this->ProcessObject::SetNthOutput(0, img); }
00144
00147 SegmentTableType * GetSegmentTable(void)
00148 { return static_cast<SegmentTableType *>
00149 (this->ProcessObject::GetOutput(1)); }
00150 void SetSegmentTable(SegmentTableType *s)
00151 { this->ProcessObject::SetNthOutput(1, s); }
00152
00155 BoundaryType * GetBoundary(void)
00156 { return static_cast<BoundaryType *>
00157 (this->ProcessObject::GetOutput(2)); }
00158 void SetBoundary(BoundaryType *b)
00159 { this->ProcessObject::SetNthOutput(2,b); }
00160
00162 void GenerateData();
00163
00170 void SetLargestPossibleRegion(ImageRegionType reg)
00171 {
00172 if (reg == m_LargestPossibleRegion) return;
00173 m_LargestPossibleRegion = reg;
00174 this->Modified();
00175 }
00176 ImageRegionType GetLargestPossibleRegion() const
00177 { return m_LargestPossibleRegion; }
00178
00181 static void RelabelImage(OutputImageTypePointer,
00182 ImageRegionType,
00183 EquivalencyTable::Pointer);
00184
00186 virtual DataObjectPointer MakeOutput(unsigned int idx);
00187
00190 itkSetMacro(CurrentLabel, unsigned long);
00191 itkGetMacro(CurrentLabel, unsigned long);
00192
00202 itkSetClampMacro(Threshold, double, 0.0, 1.0);
00203 itkGetMacro(Threshold, double);
00204
00208 itkSetMacro(DoBoundaryAnalysis, bool);
00209 itkGetMacro(DoBoundaryAnalysis, bool);
00210
00215 itkGetMacro(SortEdgeLists, bool);
00216 itkSetMacro(SortEdgeLists, bool);
00217
00218 protected:
00221 struct flat_region_t
00222 {
00223 unsigned long *min_label_ptr;
00224 InputPixelType bounds_min;
00225
00226 InputPixelType value;
00227 bool is_on_boundary;
00228 flat_region_t() : is_on_boundary(false) {}
00229 };
00230
00232 typedef itk::hash_map<unsigned long, flat_region_t, itk::hash<unsigned long> >
00233 flat_region_table_t;
00234
00235 struct connectivity_t
00236 {
00237 unsigned int size;
00238 unsigned int *index;
00239 typename InputImageType::OffsetType *direction;
00240 };
00241
00246 typedef itk::hash_map<unsigned long, InputPixelType, itk::hash<unsigned long>
00247 > edge_table_t;
00248
00249 typedef itk::hash_map<unsigned long, edge_table_t, itk::hash<unsigned long>
00250 > edge_table_hash_t;
00251
00252 Segmenter();
00253 Segmenter(const Self&) {}
00254 virtual ~Segmenter();
00255 void PrintSelf(std::ostream& os, Indent indent) const;
00256 void operator=(const Self&) {}
00257
00260 virtual void GenerateConnectivity();
00261
00265 void GenerateInputRequestedRegion();
00266 void GenerateOutputRequestedRegion(DataObject *output);
00267 void UpdateOutputInformation();
00268
00271 void InitializeBoundary();
00272
00276 void AnalyzeBoundaryFlow(InputImageTypePointer,
00277 flat_region_table_t &,
00278 InputPixelType);
00279
00283 void BuildRetainingWall(InputImageTypePointer,
00284 ImageRegionType, InputPixelType);
00285
00288 void LabelMinima(InputImageTypePointer,
00289 ImageRegionType, flat_region_table_t &,
00290 InputPixelType);
00291
00295 void GradientDescent(InputImageTypePointer, ImageRegionType);
00296
00299 void DescendFlatRegions(flat_region_table_t &, ImageRegionType);
00300
00303 void UpdateSegmentTable(InputImageTypePointer, ImageRegionType);
00304
00308 void CollectBoundaryInformation(flat_region_table_t &);
00309
00315 static void Threshold(InputImageTypePointer destination,
00316 InputImageTypePointer source,
00317 const ImageRegionType source_region,
00318 const ImageRegionType destination_region,
00319 InputPixelType threshold);
00320
00322 static void MinMax(InputImageTypePointer img,
00323 ImageRegionType region,
00324 InputPixelType &min,
00325 InputPixelType &max);
00326
00328 static void MergeFlatRegions(flat_region_table_t &, EquivalencyTable::Pointer);
00329
00331 static void SetInputImageValues(InputImageTypePointer img,
00332 const ImageRegionType region,
00333 InputPixelType value);
00334
00335 static void SetOutputImageValues(OutputImageTypePointer img,
00336 const ImageRegionType region,
00337 unsigned long value);
00338
00340
00341
00344 connectivity_t m_Connectivity;
00345
00346 private:
00348
00349
00353 ImageRegionType m_LargestPossibleRegion;
00354
00355 bool m_SortEdgeLists;
00356 bool m_DoBoundaryAnalysis;
00357 double m_Threshold;
00358 double m_MaximumFloodLevel;
00359 unsigned long m_CurrentLabel;
00360 };
00361
00362 }
00363 }
00364
00365 #ifndef ITK_MANUAL_INSTANTIATION
00366 #include "itkWatershedSegmenter.txx"
00367 #endif
00368
00369 #endif