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 __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