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;
00110
00113 typedef ProcessObject Superclass;
00114 typedef SmartPointer<Self> Pointer;
00115 typedef SmartPointer<const Self> ConstPointer;
00116 itkNewMacro(Self);
00117 itkTypeMacro(Segmenter, ProcessObject);
00119
00121 typedef typename InputImageType::Pointer InputImageTypePointer;
00122 typedef typename OutputImageType::Pointer OutputImageTypePointer;
00123 typedef typename SegmentTableType::Pointer SegmentTableTypePointer;
00124 typedef typename BoundaryType::Pointer BoundaryTypePointer;
00125
00127 static unsigned long NULL_LABEL;
00128
00130 static short NULL_FLOW;
00131
00133 InputImageType * GetInputImage(void)
00134 { return static_cast<InputImageType *>
00135 (this->ProcessObject::GetInput(0)); }
00136 void SetInputImage(InputImageType *img)
00137 { this->ProcessObject::SetNthInput(0, img); }
00139
00142 OutputImageType * GetOutputImage(void)
00143 { return static_cast<OutputImageType *>
00144 (this->ProcessObject::GetOutput(0)); }
00145 void SetOutputImage(OutputImageType *img)
00146 { this->ProcessObject::SetNthOutput(0, img); }
00148
00151 SegmentTableType * GetSegmentTable(void)
00152 { return static_cast<SegmentTableType *>
00153 (this->ProcessObject::GetOutput(1)); }
00154 void SetSegmentTable(SegmentTableType *s)
00155 { this->ProcessObject::SetNthOutput(1, s); }
00157
00160 BoundaryType * GetBoundary(void)
00161 { return static_cast<BoundaryType *>
00162 (this->ProcessObject::GetOutput(2)); }
00163 void SetBoundary(BoundaryType *b)
00164 { this->ProcessObject::SetNthOutput(2,b); }
00166
00168 void GenerateData();
00169
00176 void SetLargestPossibleRegion(ImageRegionType reg)
00177 {
00178 if (reg == m_LargestPossibleRegion) return;
00179 m_LargestPossibleRegion = reg;
00180 this->Modified();
00181 }
00182 ImageRegionType GetLargestPossibleRegion() const
00183 { return m_LargestPossibleRegion; }
00185
00188 static void RelabelImage(OutputImageTypePointer,
00189 ImageRegionType,
00190 EquivalencyTable::Pointer);
00191
00193 virtual DataObjectPointer MakeOutput(unsigned int idx);
00194
00197 itkSetMacro(CurrentLabel, unsigned long);
00198 itkGetMacro(CurrentLabel, unsigned long);
00200
00210 itkSetClampMacro(Threshold, double, 0.0, 1.0);
00211 itkGetMacro(Threshold, double);
00213
00217 itkSetMacro(DoBoundaryAnalysis, bool);
00218 itkGetMacro(DoBoundaryAnalysis, bool);
00220
00225 itkGetMacro(SortEdgeLists, bool);
00226 itkSetMacro(SortEdgeLists, bool);
00228
00229 protected:
00232 struct flat_region_t
00233 {
00234 unsigned long *min_label_ptr;
00235 InputPixelType bounds_min;
00236
00237 InputPixelType value;
00238 bool is_on_boundary;
00239 flat_region_t() : is_on_boundary(false) {}
00240 };
00241
00243 typedef itk::hash_map<unsigned long, flat_region_t, itk::hash<unsigned long> >
00244 flat_region_table_t;
00245
00246 struct connectivity_t
00247 {
00248 unsigned int size;
00249 unsigned int *index;
00250 typename InputImageType::OffsetType *direction;
00251 };
00252
00257 typedef itk::hash_map<unsigned long, InputPixelType, itk::hash<unsigned long>
00258 > edge_table_t;
00259
00260 typedef itk::hash_map<unsigned long, edge_table_t, itk::hash<unsigned long>
00261 > edge_table_hash_t;
00262
00263 Segmenter();
00264 Segmenter(const Self&) {}
00265 virtual ~Segmenter();
00266 void PrintSelf(std::ostream& os, Indent indent) const;
00267 void operator=(const Self&) {}
00268
00271 virtual void GenerateConnectivity();
00272
00276 void GenerateInputRequestedRegion();
00277 void GenerateOutputRequestedRegion(DataObject *output);
00278 void UpdateOutputInformation();
00280
00283 void InitializeBoundary();
00284
00288 void AnalyzeBoundaryFlow(InputImageTypePointer,
00289 flat_region_table_t &,
00290 InputPixelType);
00291
00295 void BuildRetainingWall(InputImageTypePointer,
00296 ImageRegionType, InputPixelType);
00297
00300 void LabelMinima(InputImageTypePointer,
00301 ImageRegionType, flat_region_table_t &,
00302 InputPixelType);
00303
00307 void GradientDescent(InputImageTypePointer, ImageRegionType);
00308
00311 void DescendFlatRegions(flat_region_table_t &, ImageRegionType);
00312
00315 void UpdateSegmentTable(InputImageTypePointer, ImageRegionType);
00316
00320 void CollectBoundaryInformation(flat_region_table_t &);
00321
00327 static void Threshold(InputImageTypePointer destination,
00328 InputImageTypePointer source,
00329 const ImageRegionType source_region,
00330 const ImageRegionType destination_region,
00331 InputPixelType threshold);
00332
00334 static void MinMax(InputImageTypePointer img,
00335 ImageRegionType region,
00336 InputPixelType &min,
00337 InputPixelType &max);
00338
00340 static void MergeFlatRegions(flat_region_table_t &, EquivalencyTable::Pointer);
00341
00343 static void SetInputImageValues(InputImageTypePointer img,
00344 const ImageRegionType region,
00345 InputPixelType value);
00346
00347 static void SetOutputImageValues(OutputImageTypePointer img,
00348 const ImageRegionType region,
00349 unsigned long value);
00350
00352
00353
00356 connectivity_t m_Connectivity;
00357
00358 private:
00360
00361
00365 ImageRegionType m_LargestPossibleRegion;
00366
00367 bool m_SortEdgeLists;
00368 bool m_DoBoundaryAnalysis;
00369 double m_Threshold;
00370 double m_MaximumFloodLevel;
00371 unsigned long m_CurrentLabel;
00372 };
00373
00374 }
00375 }
00376
00377 #ifndef ITK_MANUAL_INSTANTIATION
00378 #include "itkWatershedSegmenter.txx"
00379 #endif
00380
00381 #endif
00382