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 __itkMaskImageFilter_h 00019 #define __itkMaskImageFilter_h 00020 00021 #include "itkBinaryFunctorImageFilter.h" 00022 #include "itkNumericTraits.h" 00023 #include "itkVariableLengthVector.h" 00024 00025 namespace itk 00026 { 00027 namespace Functor 00028 { 00034 template< class TInput, class TMask, class TOutput = TInput > 00035 class MaskInput 00036 { 00037 public: 00038 typedef typename NumericTraits< TInput >::AccumulateType AccumulatorType; 00039 00040 MaskInput() 00041 { 00042 InitializeOutsideValue( static_cast<TOutput*>( NULL ) ); 00043 } 00044 ~MaskInput() {} 00045 bool operator!=(const MaskInput &) const 00046 { 00047 return false; 00048 } 00049 00050 bool operator==(const MaskInput & other) const 00051 { 00052 return !( *this != other ); 00053 } 00054 00055 inline TOutput operator()(const TInput & A, const TMask & B) const 00056 { 00057 if ( B != NumericTraits< TMask >::ZeroValue() ) 00058 { 00059 return static_cast< TOutput >( A ); 00060 } 00061 else 00062 { 00063 return m_OutsideValue; 00064 } 00065 } 00066 00068 void SetOutsideValue(const TOutput & outsideValue) 00069 { 00070 m_OutsideValue = outsideValue; 00071 } 00072 00074 const TOutput & GetOutsideValue() const 00075 { 00076 return m_OutsideValue; 00077 } 00078 00079 private: 00080 00081 template < class TPixelType > 00082 void InitializeOutsideValue( TPixelType * ) 00083 { 00084 this->m_OutsideValue = NumericTraits< TPixelType >::Zero; 00085 } 00086 00087 template < class TValueType > 00088 void InitializeOutsideValue( VariableLengthVector<TValueType> * ) 00089 { 00090 // set the outside value to be of zero length 00091 this->m_OutsideValue = VariableLengthVector< TValueType >(0); 00092 } 00093 00094 TOutput m_OutsideValue; 00095 }; 00096 } 00131 template< class TInputImage, class TMaskImage, class TOutputImage = TInputImage > 00132 class ITK_EXPORT MaskImageFilter: 00133 public 00134 BinaryFunctorImageFilter< TInputImage, TMaskImage, TOutputImage, 00135 Functor::MaskInput< 00136 typename TInputImage::PixelType, 00137 typename TMaskImage::PixelType, 00138 typename TOutputImage::PixelType > > 00139 00140 { 00141 public: 00143 typedef MaskImageFilter Self; 00144 typedef BinaryFunctorImageFilter< TInputImage, TMaskImage, TOutputImage, 00145 Functor::MaskInput< 00146 typename TInputImage::PixelType, 00147 typename TMaskImage::PixelType, 00148 typename TOutputImage::PixelType > 00149 > Superclass; 00150 00151 typedef SmartPointer< Self > Pointer; 00152 typedef SmartPointer< const Self > ConstPointer; 00153 00155 itkNewMacro(Self); 00156 00158 itkTypeMacro(MaskImageFilter, 00159 BinaryFunctorImageFilter); 00160 00162 typedef TMaskImage MaskImageType; 00163 00168 void SetMaskImage(const MaskImageType *maskImage) 00169 { 00170 // Process object is not const-correct so the const casting is required. 00171 this->SetNthInput( 1, const_cast< MaskImageType * >( maskImage ) ); 00172 } 00173 const MaskImageType * GetMaskImage() 00174 { 00175 return static_cast<const MaskImageType*>(this->ProcessObject::GetInput(1)); 00176 } 00178 00180 void SetOutsideValue(const typename TOutputImage::PixelType & outsideValue) 00181 { 00182 if ( this->GetOutsideValue() != outsideValue ) 00183 { 00184 this->Modified(); 00185 this->GetFunctor().SetOutsideValue(outsideValue); 00186 } 00187 } 00189 00190 const typename TOutputImage::PixelType & GetOutsideValue() const 00191 { 00192 return this->GetFunctor().GetOutsideValue(); 00193 } 00194 00195 void BeforeThreadedGenerateData() 00196 { 00197 typedef typename TOutputImage::PixelType PixelType; 00198 this->CheckOutsideValue( static_cast<PixelType*>(NULL) ); 00199 } 00200 00201 #ifdef ITK_USE_CONCEPT_CHECKING 00202 00203 itkConceptMacro( MaskEqualityComparableCheck, 00204 ( Concept::EqualityComparable< typename TMaskImage::PixelType > ) ); 00205 itkConceptMacro( InputConvertibleToOutputCheck, 00206 ( Concept::Convertible< typename TInputImage::PixelType, 00207 typename TOutputImage::PixelType > ) ); 00208 00210 #endif 00211 protected: 00212 MaskImageFilter() {} 00213 virtual ~MaskImageFilter() {} 00215 00216 void PrintSelf(std::ostream & os, Indent indent) const 00217 { 00218 Superclass::PrintSelf(os, indent); 00219 os << indent << "OutsideValue: " << this->GetOutsideValue() << std::endl; 00220 } 00221 00222 private: 00223 MaskImageFilter(const Self &); //purposely not implemented 00224 void operator=(const Self &); //purposely not implemented 00225 00226 template < class TPixelType > 00227 void CheckOutsideValue( const TPixelType * ) {} 00228 00229 template < class TValue > 00230 void CheckOutsideValue( const VariableLengthVector< TValue > * ) 00231 { 00232 // Check to see if the outside value contains only zeros. If so, 00233 // resize it to have the same number of zeros as the output 00234 // image. Otherwise, check that the number of components in the 00235 // outside value is the same as the number of components in the 00236 // output image. If not, throw an exception. 00237 VariableLengthVector< TValue > currentValue = 00238 this->GetFunctor().GetOutsideValue(); 00239 VariableLengthVector< TValue > zeroVector( currentValue.GetSize() ); 00240 zeroVector.Fill( NumericTraits< TValue >::Zero ); 00241 00242 if ( currentValue == zeroVector ) 00243 { 00244 zeroVector.SetSize( this->GetOutput()->GetVectorLength() ); 00245 zeroVector.Fill( NumericTraits< TValue >::Zero ); 00246 this->GetFunctor().SetOutsideValue( zeroVector ); 00247 } 00248 else if ( this->GetFunctor().GetOutsideValue().GetSize() != 00249 this->GetOutput()->GetVectorLength() ) 00250 { 00251 itkExceptionMacro( 00252 << "Number of components in OutsideValue: " 00253 << this->GetFunctor().GetOutsideValue().GetSize() 00254 << " is not the same as the " 00255 << "number of components in the image: " 00256 << this->GetOutput()->GetVectorLength()); 00257 } 00258 } 00259 00260 }; 00261 } // end namespace itk 00262 00263 #endif 00264