00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkJointDomainImageToListAdaptor_h
00018 #define __itkJointDomainImageToListAdaptor_h
00019
00020 #include "itkMacro.h"
00021 #include "itkFixedArray.h"
00022 #include "itkPoint.h"
00023 #include "itkPixelTraits.h"
00024 #include "itkImageToListAdaptor.h"
00025 #include "itkImageRegionConstIteratorWithIndex.h"
00026 #include "itkEuclideanDistance.h"
00027 #include "itkListSample.h"
00028
00029 namespace itk{
00030 namespace Statistics{
00031
00039 template< class TImage >
00040 struct ImageJointDomainTraits
00041 {
00042 typedef ImageJointDomainTraits Self ;
00043 typedef PixelTraits< typename TImage::PixelType > PixelTraitsType ;
00044 typedef typename PixelTraitsType::ValueType RangeDomainMeasurementType ;
00045 typedef typename TImage::IndexType::IndexValueType IndexValueType ;
00046 itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension) ;
00047 itkStaticConstMacro(Dimension,
00048 unsigned int,
00049 TImage::ImageDimension +
00050 PixelTraitsType::Dimension ) ;
00051 typedef float CoordinateRepType ;
00052 typedef Point< CoordinateRepType, itkGetStaticConstMacro(ImageDimension) > PointType ;
00053 typedef JoinTraits< RangeDomainMeasurementType, CoordinateRepType >
00054 JoinTraitsType ;
00055 typedef typename JoinTraitsType::ValueType MeasurementType ;
00056 typedef FixedArray< MeasurementType, itkGetStaticConstMacro(Dimension) >
00057 MeasurementVectorType ;
00058 } ;
00059
00089 template < class TImage >
00090 class ITK_EXPORT JointDomainImageToListAdaptor
00091 : public ImageToListAdaptor<
00092 TImage,
00093 typename ImageJointDomainTraits< TImage >::MeasurementVectorType >
00094 {
00095 public:
00096 typedef ImageJointDomainTraits< TImage > ImageJointDomainTraitsType ;
00097 typedef typename ImageJointDomainTraitsType::MeasurementVectorType
00098 MeasurementVectorType ;
00099 typedef typename ImageJointDomainTraitsType::MeasurementType
00100 MeasurementType ;
00101 typedef typename ImageJointDomainTraitsType::RangeDomainMeasurementType
00102 RangeDomainMeasurementType ;
00103 typedef typename ImageJointDomainTraitsType::PointType PointType ;
00104 typedef typename ImageJointDomainTraitsType::CoordinateRepType
00105 CoordinateRepType ;
00107 typedef JointDomainImageToListAdaptor Self;
00108 typedef ImageToListAdaptor< TImage, MeasurementVectorType >
00109 Superclass;
00110 typedef SmartPointer< Self > Pointer;
00111 typedef SmartPointer<const Self> ConstPointer;
00112
00114 itkTypeMacro(JointDomainImageToListAdaptor, ImageToListAdaptor) ;
00115
00117 itkNewMacro(Self) ;
00118
00120 itkStaticConstMacro(MeasurementVectorSize,
00121 unsigned int,
00122 ImageJointDomainTraitsType::Dimension) ;
00123
00124 typedef typename Superclass::MeasurementVectorSizeType MeasurementVectorSizeType;
00125
00126 virtual void SetMeasurementVectorSize( const MeasurementVectorSizeType s )
00127 {
00128
00129
00130 if( s != MeasurementVectorSize )
00131 {
00132 itkExceptionMacro( << "Cannot set measurement vector size of "
00133 << " JointDomainImageToListAdaptor to " << s );
00134 }
00135 }
00136
00137 MeasurementVectorSizeType GetMeasurementVectorSize() const
00138 {
00139 return MeasurementVectorSize;
00140 }
00141
00144 typedef typename Superclass::FrequencyType FrequencyType ;
00145 typedef typename Superclass::InstanceIdentifier InstanceIdentifier ;
00146
00147 typedef typename TImage::IndexType ImageIndexType ;
00148 typedef typename TImage::IndexType::IndexValueType ImageIndexValueType ;
00149 typedef typename TImage::SizeType ImageSizeType ;
00150 typedef typename TImage::RegionType ImageRegionType ;
00151 typedef ImageRegionConstIteratorWithIndex< TImage > ImageIteratorType ;
00152
00153 typedef MeasurementVectorType ValueType ;
00154
00155 itkStaticConstMacro(RangeDomainDimension,
00156 unsigned int,
00157 itk::PixelTraits<
00158 typename TImage::PixelType >::Dimension) ;
00159
00160 typedef FixedArray< RangeDomainMeasurementType,
00161 itkGetStaticConstMacro( RangeDomainDimension ) >
00162 RangeDomainMeasurementVectorType ;
00163
00164 typedef std::vector< InstanceIdentifier > InstanceIdentifierVectorType ;
00165
00166 typedef FixedArray< float, itkGetStaticConstMacro(MeasurementVectorSize) >
00167 NormalizationFactorsType ;
00168
00170 void SetNormalizationFactors(NormalizationFactorsType& factors) ;
00171
00174 inline const MeasurementVectorType & GetMeasurementVector(const InstanceIdentifier &id) const;
00175
00178 inline void ComputeRegion(const MeasurementVectorType& mv,
00179 const double radius,
00180 ImageRegionType& region) const;
00181
00185 inline void Search(const MeasurementVectorType& mv,
00186 const double radius,
00187 InstanceIdentifierVectorType& result) const;
00188
00189 protected:
00190 JointDomainImageToListAdaptor() ;
00191 virtual ~JointDomainImageToListAdaptor() {}
00192 void PrintSelf(std::ostream& os, Indent indent) const;
00193
00194 private:
00195 JointDomainImageToListAdaptor(const Self&) ;
00196 void operator=(const Self&) ;
00197
00198 NormalizationFactorsType m_NormalizationFactors ;
00199
00200 mutable MeasurementVectorType m_TempVector ;
00201 mutable PointType m_TempPoint ;
00202 mutable ImageIndexType m_TempIndex ;
00203 mutable RangeDomainMeasurementVectorType m_TempRangeVector ;
00204 } ;
00205
00206 template < class TImage >
00207 inline const typename JointDomainImageToListAdaptor< TImage >::MeasurementVectorType &
00208 JointDomainImageToListAdaptor< TImage >
00209 ::GetMeasurementVector(const InstanceIdentifier &id) const
00210 {
00211 m_TempIndex = this->GetImage()->ComputeIndex( id ) ;
00212
00213 this->GetImage()->TransformIndexToPhysicalPoint( m_TempIndex, m_TempPoint ) ;
00214
00215 for ( unsigned int i = 0 ; i < TImage::ImageDimension ; ++i )
00216 {
00217 m_TempVector[i] = m_TempPoint[i] / m_NormalizationFactors[i] ;
00218 }
00219
00220 if( this->GetUseBuffer() )
00221 {
00222 m_TempRangeVector =
00223 *(reinterpret_cast<const RangeDomainMeasurementVectorType* >
00224 (&(*this->GetPixelContainer())[id])) ;
00225 }
00226 else
00227 {
00228 m_TempRangeVector =
00229 *(reinterpret_cast< const RangeDomainMeasurementVectorType* >
00230 (&(this->GetImage()->GetPixel( m_TempIndex ) ) ) ) ;
00231 }
00232
00233 for ( unsigned int i = TImage::ImageDimension ; i < MeasurementVectorType::Length ; ++i )
00234 {
00235 m_TempVector[i] = m_TempRangeVector[i - TImage::ImageDimension]
00236 / m_NormalizationFactors[i] ;
00237 }
00238
00239 return m_TempVector ;
00240 }
00241
00242 template < class TImage >
00243 inline void
00244 JointDomainImageToListAdaptor< TImage >
00245 ::ComputeRegion(const MeasurementVectorType& mv,
00246 const double radius,
00247 ImageRegionType& region) const
00248 {
00249 ImageIndexType beginIndex ;
00250 ImageSizeType size ;
00251
00252 for ( unsigned int i = 0 ; i < TImage::ImageDimension ; ++i )
00253 {
00254 m_TempPoint[i] = m_NormalizationFactors[i] * (mv[i] - radius) ;
00255 size[i] = (unsigned long)(2.0 * m_NormalizationFactors[i] * radius
00256 / this->GetImage()->GetSpacing()[i]) ;
00257 }
00258
00259 this->GetImage()->TransformPhysicalPointToIndex(m_TempPoint , beginIndex ) ;
00260
00261 for ( unsigned int i = 0 ; i < TImage::ImageDimension ; ++i )
00262 {
00263 if ( beginIndex[i] < this->GetImageBeginIndex()[i] )
00264 {
00265 beginIndex[i] = this->GetImageBeginIndex()[i] ;
00266 size[i] -= (this->GetImageBeginIndex()[i] - beginIndex[i]) ;
00267 }
00268
00269 if ( static_cast<typename ImageIndexType::IndexValueType>(beginIndex[i] + size[i] - 1) > this->GetImageEndIndex()[i] )
00270 {
00271 size[i] = this->GetImageEndIndex()[i] - beginIndex[i] + 1 ;
00272 }
00273 }
00274
00275 region.SetIndex( beginIndex ) ;
00276 region.SetSize( size ) ;
00277 }
00278
00279 template < class TImage >
00280 inline void
00281 JointDomainImageToListAdaptor< TImage >
00282 ::Search(const MeasurementVectorType& mv,
00283 const double radius,
00284 InstanceIdentifierVectorType& result) const
00285 {
00286 ImageRegionType region ;
00287 this->ComputeRegion( mv, radius, region ) ;
00288
00289 result.clear() ;
00290 ImageIteratorType iter( this->GetImage(), region ) ;
00291 iter.GoToBegin() ;
00292 double squaredRadius = radius * radius ;
00293 InstanceIdentifier instanceID;
00294 while ( !iter.IsAtEnd() )
00295 {
00296 instanceID = this->GetImage()->ComputeOffset(iter.GetIndex()) ;
00297 m_TempVector = this->GetMeasurementVector( instanceID ) ;
00298 bool isWithinRange = true ;
00299 double sum = 0.0 ;
00300 for ( unsigned int i = 0 ; i < MeasurementVectorSize ; ++i )
00301 {
00302 const double temp = (m_TempVector[i] - mv[i]) ;
00303 sum += temp * temp ;
00304 if ( sum > squaredRadius )
00305 {
00306 isWithinRange = false ;
00307 break ;
00308 }
00309 }
00310
00311 if ( isWithinRange )
00312 {
00313 result.push_back(instanceID) ;
00314 }
00315 ++iter ;
00316 }
00317 }
00318
00319 }
00320 }
00321
00322 #ifndef ITK_MANUAL_INSTANTIATION
00323 #include "itkJointDomainImageToListAdaptor.txx"
00324 #endif
00325
00326 #endif
00327