1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkImageToListSampleAdaptor_h 19 #define itkImageToListSampleAdaptor_h 20 21 #include <typeinfo> 22 #include <utility> 23 24 #include "itkImage.h" 25 #include "itkPixelTraits.h" 26 #include "itkListSample.h" 27 #include "itkSmartPointer.h" 28 #include "itkImageRegionIterator.h" 29 #include "itkMeasurementVectorTraits.h" 30 31 namespace itk 32 { 33 namespace Statistics 34 { 35 /** \class ImageToListSampleAdaptor 36 * \brief This class provides ListSample interface to ITK Image 37 * 38 * After calling SetImage( const Image * ) method to plug in the image object, 39 * users can use Sample interfaces to access Image data. The resulting data 40 * are a list of measurement vectors. 41 * 42 * The measurment vector type is determined from the image pixel type. This class 43 * handles images with scalar, fixed array or variable length vector pixel types. 44 * 45 * \sa Sample, ListSample 46 * \ingroup ITKStatistics 47 * 48 * \wiki 49 * \wikiexample{Statistics/ImageToListSampleAdaptor,Create a list of samples from an image without duplicating the data} 50 * \endwiki 51 */ 52 53 template< typename TImage > 54 class ITK_TEMPLATE_EXPORT ImageToListSampleAdaptor: 55 public ListSample< typename MeasurementVectorPixelTraits< typename TImage::PixelType >::MeasurementVectorType > 56 { 57 public: 58 ITK_DISALLOW_COPY_AND_ASSIGN(ImageToListSampleAdaptor); 59 60 /** Standard class type aliases */ 61 using Self = ImageToListSampleAdaptor; 62 63 using Superclass = ListSample< typename MeasurementVectorPixelTraits< 64 typename TImage::PixelType >::MeasurementVectorType >; 65 66 using Pointer = SmartPointer< Self >; 67 using ConstPointer = SmartPointer< const Self >; 68 69 /** Run-time type information (and related methods). */ 70 itkTypeMacro(ImageToListSampleAdaptor, ListSample); 71 72 /** Method for creation through the object factory. */ 73 itkNewMacro(Self); 74 75 /** Image type alias */ 76 using ImageType = TImage; 77 using ImagePointer = typename ImageType::Pointer; 78 using ImageConstPointer = typename ImageType::ConstPointer; 79 using IndexType = typename ImageType::IndexType; 80 using PixelType = typename ImageType::PixelType; 81 using PixelContainerConstPointer = typename ImageType::PixelContainerConstPointer; 82 83 /** Image Iterator type alias support */ 84 using ImageIteratorType = ImageRegionIterator< ImageType >; 85 using ImageConstIteratorType = ImageRegionConstIterator< ImageType >; 86 using PixelTraitsType = PixelTraits< typename TImage::PixelType >; 87 88 89 /** Superclass type alias for Measurement vector, measurement, 90 * Instance Identifier, frequency, size, size element value */ 91 using MeasurementPixelTraitsType = MeasurementVectorPixelTraits< PixelType >; 92 using MeasurementVectorType = typename MeasurementPixelTraitsType::MeasurementVectorType; 93 94 using MeasurementVectorTraitsType = MeasurementVectorTraitsTypes< MeasurementVectorType >; 95 using MeasurementType = typename MeasurementVectorTraitsType::ValueType; 96 97 using AbsoluteFrequencyType = typename Superclass::AbsoluteFrequencyType; 98 using TotalAbsoluteFrequencyType = typename Superclass::TotalAbsoluteFrequencyType; 99 using MeasurementVectorSizeType = typename Superclass::MeasurementVectorSizeType; 100 using InstanceIdentifier = typename Superclass::InstanceIdentifier; 101 102 using ValueType = MeasurementVectorType; 103 104 /** Method to set the image */ 105 void SetImage(const TImage *image); 106 107 /** Method to get the image */ 108 const TImage * GetImage() const; 109 110 /** returns the number of measurement vectors in this container */ 111 InstanceIdentifier Size() const override; 112 113 /** method to return measurement vector for a specified id */ 114 const MeasurementVectorType & GetMeasurementVector(InstanceIdentifier id) const override; 115 GetMeasurementVectorSize()116 MeasurementVectorSizeType GetMeasurementVectorSize() const override 117 { 118 // some filter are expected that this method returns something even if the 119 // input is not set. This won't be the right value for a variable length vector 120 // but it's better than an exception. 121 if( m_Image.IsNull() ) 122 { 123 return Superclass::GetMeasurementVectorSize(); 124 } 125 else 126 { 127 return m_Image->GetNumberOfComponentsPerPixel(); 128 } 129 } 130 131 /** method to return frequency for a specified id */ 132 AbsoluteFrequencyType GetFrequency(InstanceIdentifier id) const override; 133 134 /** method to return the total frequency */ 135 TotalAbsoluteFrequencyType GetTotalFrequency() const override; 136 137 /** \class ConstIterator 138 * \brief Const Iterator 139 * \ingroup ITKStatistics 140 */ 141 class ConstIterator 142 { 143 friend class ImageToListSampleAdaptor; 144 145 public: 146 ConstIterator(const ImageToListSampleAdaptor * adaptor)147 ConstIterator(const ImageToListSampleAdaptor *adaptor) 148 { 149 *this = adaptor->Begin(); 150 } 151 ConstIterator(const ConstIterator & iter)152 ConstIterator(const ConstIterator & iter) : 153 m_Iter(iter.m_Iter), 154 m_InstanceIdentifier(iter.m_InstanceIdentifier) 155 {} 156 157 ConstIterator & operator=(const ConstIterator & iter) 158 { 159 m_Iter = iter.m_Iter; 160 m_InstanceIdentifier = iter.m_InstanceIdentifier; 161 return *this; 162 } 163 GetFrequency()164 AbsoluteFrequencyType GetFrequency() const 165 { 166 return 1; 167 } 168 GetMeasurementVector()169 const MeasurementVectorType & GetMeasurementVector() const 170 { 171 MeasurementVectorTraits::Assign( this->m_MeasurementVectorCache, m_Iter.Get() ); 172 return this->m_MeasurementVectorCache; 173 } 174 GetInstanceIdentifier()175 InstanceIdentifier GetInstanceIdentifier() const 176 { 177 return m_InstanceIdentifier; 178 } 179 180 ConstIterator & operator++() 181 { 182 ++m_Iter; 183 ++m_InstanceIdentifier; 184 return *this; 185 } 186 187 bool operator!=(const ConstIterator & it) 188 { 189 return ( m_Iter != it.m_Iter ); 190 } 191 192 bool operator==(const ConstIterator & it) 193 { 194 return ( m_Iter == it.m_Iter ); 195 } 196 197 protected: 198 // This method should only be available to the ListSample class ConstIterator(ImageConstIteratorType iter,InstanceIdentifier iid)199 ConstIterator(ImageConstIteratorType iter, InstanceIdentifier iid) : 200 m_Iter(std::move(iter)), 201 m_InstanceIdentifier(iid) 202 {} 203 204 private: 205 ConstIterator() = delete; 206 ImageConstIteratorType m_Iter; 207 mutable MeasurementVectorType m_MeasurementVectorCache; 208 InstanceIdentifier m_InstanceIdentifier; 209 }; 210 211 /** \class Iterator 212 * \brief Iterator 213 * \ingroup ITKStatistics 214 */ 215 class Iterator: 216 public ConstIterator 217 { 218 friend class ImageToListSampleAdaptor; 219 220 public: 221 Iterator(Self * adaptor)222 Iterator(Self *adaptor) : 223 ConstIterator(adaptor) 224 {} 225 Iterator(const Iterator & iter)226 Iterator(const Iterator & iter): 227 ConstIterator(iter) 228 {} 229 230 Iterator & operator=(const Iterator & iter) 231 { 232 this->ConstIterator::operator=(iter); 233 return *this; 234 } 235 236 protected: Iterator(const ImageIteratorType & iter,InstanceIdentifier iid)237 Iterator(const ImageIteratorType & iter, InstanceIdentifier iid) : 238 ConstIterator(iter, iid) 239 {} 240 241 private: 242 // To ensure const-correctness these method must not be in the public API. 243 // The are purposly not implemented, since they should never be called. 244 Iterator() = delete; 245 Iterator(const Self *adaptor) = delete; 246 Iterator(const ImageConstIteratorType & iter, InstanceIdentifier iid) = delete; 247 Iterator(const ConstIterator & it) = delete; 248 ConstIterator & operator=(const ConstIterator & it) = delete; 249 }; 250 251 /** returns an iterator that points to the beginning of the container */ Begin()252 Iterator Begin() 253 { 254 ImagePointer nonConstImage = const_cast< ImageType * >( m_Image.GetPointer() ); 255 ImageIteratorType imageIterator( nonConstImage, nonConstImage->GetLargestPossibleRegion() ); 256 imageIterator.GoToBegin(); 257 Iterator iter(imageIterator, 0); 258 return iter; 259 } 260 261 /** returns an iterator that points to the end of the container */ End()262 Iterator End() 263 { 264 ImagePointer nonConstImage = const_cast< ImageType * >( m_Image.GetPointer() ); 265 const typename ImageType::RegionType & largestRegion = nonConstImage->GetLargestPossibleRegion(); 266 ImageIteratorType imageIterator( nonConstImage, largestRegion ); 267 imageIterator.GoToEnd(); 268 Iterator iter( imageIterator, largestRegion.GetNumberOfPixels() ); 269 270 return iter; 271 } 272 273 /** returns an iterator that points to the beginning of the container */ Begin()274 ConstIterator Begin() const 275 { 276 ImageConstIteratorType imageConstIterator( m_Image, m_Image->GetLargestPossibleRegion() ); 277 imageConstIterator.GoToBegin(); 278 ConstIterator iter(imageConstIterator, 0); 279 280 return iter; 281 } 282 283 /** returns an iterator that points to the end of the container */ End()284 ConstIterator End() const 285 { 286 const typename ImageType::RegionType & largestRegion = m_Image->GetLargestPossibleRegion(); 287 ImageConstIteratorType imageConstIterator( m_Image, largestRegion ); 288 imageConstIterator.GoToEnd(); 289 ConstIterator iter( imageConstIterator, largestRegion.GetNumberOfPixels() ); 290 291 return iter; 292 } 293 294 protected: 295 ImageToListSampleAdaptor(); 296 ~ImageToListSampleAdaptor() override = default; 297 void PrintSelf(std::ostream & os, Indent indent) const override; 298 299 private: 300 ImageConstPointer m_Image; 301 mutable MeasurementVectorType m_MeasurementVectorInternal; 302 303 }; // end of class ImageToListSampleAdaptor 304 } // end of namespace Statistics 305 } // end of namespace itk 306 307 #ifndef ITK_MANUAL_INSTANTIATION 308 #include "itkImageToListSampleAdaptor.hxx" 309 #endif 310 311 #endif 312