ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkAttributeMorphologyBaseImageFilter.h
Go to the documentation of this file.
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 __itkAttributeMorphologyBaseImageFilter_h
00019 #define __itkAttributeMorphologyBaseImageFilter_h
00020 
00021 #include "itkImageToImageFilter.h"
00022 #include <vector>
00023 
00024 #define PAMI
00025 
00026 namespace itk
00027 {
00062 template< class TInputImage, class TOutputImage, class TAttribute, class TFunction >
00063 class ITK_EXPORT AttributeMorphologyBaseImageFilter:
00064   public ImageToImageFilter< TInputImage, TOutputImage >
00065 {
00066 public:
00070   typedef AttributeMorphologyBaseImageFilter              Self;
00071   typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass;
00072 
00076   typedef typename Superclass::InputImagePointer InputImagePointer;
00077 
00082   typedef typename TOutputImage::PixelType         OutputPixelType;
00083   typedef typename TOutputImage::InternalPixelType OutputInternalPixelType;
00084   typedef typename TInputImage::PixelType          InputPixelType;
00085   typedef typename TInputImage::InternalPixelType  InputInternalPixelType;
00086   typedef typename TInputImage::IndexType          IndexType;
00087   typedef typename TInputImage::OffsetType         OffsetType;
00088   typedef typename TInputImage::SizeType           SizeType;
00089 
00090   itkStaticConstMacro(ImageDimension, unsigned int,
00091                       TOutputImage::ImageDimension);
00092 
00096   typedef TInputImage  InputImageType;
00097   typedef TOutputImage OutputImageType;
00098 //   typedef   typename TInputImage::IndexType       IndexType;
00099 //   typedef   typename TInputImage::SizeType        SizeType;
00100   typedef   typename TOutputImage::RegionType RegionType;
00101   typedef   std::list< IndexType >            ListType;
00102   typedef TAttribute                          AttributeType;
00103 
00107   typedef SmartPointer< Self >       Pointer;
00108   typedef SmartPointer< const Self > ConstPointer;
00109 
00113   itkTypeMacro(AttributeMorphologyBaseImageFilter, ImageToImageFilter);
00114 
00118   itkNewMacro(Self);
00119 
00126   itkSetMacro(FullyConnected, bool);
00127   itkGetConstReferenceMacro(FullyConnected, bool);
00128   itkBooleanMacro(FullyConnected);
00130 
00136   itkSetMacro(Lambda, AttributeType);
00137   itkGetConstMacro(Lambda, AttributeType);
00138 protected:
00139   AttributeMorphologyBaseImageFilter()
00140   {
00141     m_FullyConnected = false;
00142     m_AttributeValuePerPixel = 1;
00143     m_Lambda = 0;
00144   }
00146 
00147   virtual ~AttributeMorphologyBaseImageFilter() {}
00148   AttributeMorphologyBaseImageFilter(const Self &) {}
00149   void PrintSelf(std::ostream & os, Indent indent) const;
00150 
00154   void GenerateData();
00155 
00159   void GenerateInputRequestedRegion();
00160 
00165   void EnlargeOutputRequestedRegion( DataObject * itkNotUsed(output) );
00166 
00167   AttributeType m_AttributeValuePerPixel;
00168 private:
00169 
00170   bool          m_FullyConnected;
00171   AttributeType m_Lambda;
00172 
00173   // some constants used several times in the code
00174   itkStaticConstMacro(INACTIVE, OffsetValueType, -1);
00175   itkStaticConstMacro(ACTIVE, OffsetValueType, -2);
00176   itkStaticConstMacro(ROOT, OffsetValueType, -3);
00177 
00178   // Just used for area/volume openings at the moment
00179   AttributeType *m_AuxData;
00180 
00181   typedef std::vector< OffsetType > OffsetVecType;
00182   // offset in the linear array.
00183   typedef std::vector< OffsetValueType > OffsetDirectVecType;
00184 
00185   void SetupOffsetVec(OffsetDirectVecType & PosOffsets, OffsetVecType & Offsets);
00186 
00187   class GreyAndPos
00188   {
00189 public:
00190     InputPixelType  Val;
00191     OffsetValueType Pos;
00192   };
00193 
00194   GreyAndPos        * m_SortPixels;
00195   OffsetValueType   * m_Parent;
00196 #ifndef PAMI
00197   bool *m_Processed;
00198 #endif
00199   // This is a bit ugly, but I can't see an easy way around
00200   InputPixelType *m_Raw;
00201 
00202   class ComparePixStruct
00203   {
00204 public:
00205     TFunction m_TFunction;
00206     bool operator()(GreyAndPos const & l, GreyAndPos const & r) const
00207     {
00208       if ( m_TFunction(l.Val, r.Val) )
00209         {
00210         return true;
00211         }
00212       if ( l.Val == r.Val )
00213         {
00214         return ( l.Pos < r.Pos );
00215         }
00216       return false;
00217     }
00218   };
00219 
00220 #ifdef PAMI
00221   // version from PAMI. Note - using the AuxData array rather than the
00222   // parent array to store area
00223   void MakeSet(OffsetValueType x)
00224   {
00225     m_Parent[x] = ACTIVE;
00226     m_AuxData[x] = m_AttributeValuePerPixel;
00227   }
00228 
00229   OffsetValueType FindRoot(OffsetValueType x)
00230   {
00231     if ( m_Parent[x] >= 0 )
00232       {
00233       m_Parent[x] = FindRoot(m_Parent[x]);
00234       return ( m_Parent[x] );
00235       }
00236     else
00237       {
00238       return ( x );
00239       }
00240   }
00241 
00242   bool Criterion(OffsetValueType x, OffsetValueType y)
00243   {
00244     return ( ( m_Raw[x] == m_Raw[y] ) || ( m_AuxData[x] < m_Lambda ) );
00245   }
00246 
00247   void Union(OffsetValueType n, OffsetValueType p)
00248   {
00249     OffsetValueType r = FindRoot(n);
00250 
00251     if ( r != p )
00252       {
00253       if ( Criterion(r, p) )
00254         {
00255         m_AuxData[p] += m_AuxData[r];
00256         m_Parent[r] = p;
00257         }
00258       else
00259         {
00260         m_AuxData[p] = m_Lambda;
00261         }
00262       }
00263   }
00264 
00265 #else
00266   // version from ISMM paper
00267   void MakeSet(OffsetValueType x)
00268   {
00269     m_Parent[x] = ACTIVE;
00270     m_AuxData[x] = m_AttributeValuePerPixel;
00271   }
00272 
00273   void Link(OffsetValueType x, OffsetValueType y)
00274   {
00275     if ( ( m_Parent[y] == ACTIVE ) && ( m_Parent[x] == ACTIVE ) )
00276       {
00277       // should be a call to MergeAuxData
00278       m_AuxData[y] = m_AuxData[x] + m_AuxData[y];
00279       m_AuxData[x] = -m_AttributeValuePerPixel;
00280       }
00281     else if ( m_Parent[x] == ACTIVE )
00282       {
00283       m_AuxData[x] = -m_AttributeValuePerPixel;
00284       }
00285     else
00286       {
00287       m_AuxData[y] = -m_AttributeValuePerPixel;
00288       m_Parent[y] = INACTIVE;
00289       }
00290     m_Parent[x] = y;
00291   }
00292 
00293   OffsetValueType FindRoot(OffsetValueType x)
00294   {
00295     if ( m_Parent[x] >= 0 )
00296       {
00297       m_Parent[x] = FindRoot(m_Parent[x]);
00298       return ( m_Parent[x] );
00299       }
00300     else
00301       {
00302       return ( x );
00303       }
00304   }
00305 
00306   bool Equiv(OffsetValueType x, OffsetValueType y)
00307   {
00308     return ( ( m_Raw[x] == m_Raw[y] ) || ( m_Parent[x] == ACTIVE ) );
00309   }
00310 
00311   void Union(OffsetValueType n, OffsetValueType p)
00312   {
00313     OffsetValueType r = FindRoot(n);
00314 
00315     if ( r != p )
00316       {
00317       if ( Equiv(r, p) )
00318         {
00319         Link(r, p);
00320         }
00321       else if ( m_Parent[p] == ACTIVE )
00322         {
00323         m_Parent[p] = INACTIVE;
00324         m_AuxData[p] = -m_AttributeValuePerPixel;
00325         }
00326       }
00327   }
00328 
00329 #endif
00330 };
00331 } // end namespace itk
00332 
00333 #ifndef ITK_MANUAL_INSTANTIATION
00334 #include "itkAttributeMorphologyBaseImageFilter.hxx"
00335 #endif
00336 
00337 #endif
00338