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 itkImageRandomConstIteratorWithOnlyIndex_h 19 #define itkImageRandomConstIteratorWithOnlyIndex_h 20 21 #include "itkImageConstIteratorWithOnlyIndex.h" 22 #include "itkMersenneTwisterRandomVariateGenerator.h" 23 24 namespace itk 25 { 26 /** \class ImageRandomConstIteratorWithOnlyIndex 27 * \brief A multi-dimensional image iterator that visits a random set of locations 28 * within an image region, providing index information. 29 * 30 * ImageRandomConstIteratorWithOnlyIndex is a multi-dimensional iterator class that 31 * is templated over image type. ImageRandomConstIteratorWithOnlyIndex is 32 * constrained to walk only within the specified region. It samples random 33 * region positions at each increment or decrement. 34 * 35 * No access to image data is possible, and thus the class can be used with 36 * images of type ImageBase. 37 * 38 * ImageRandomConstIteratorWithOnlyIndex assumes a particular layout of the image data. The 39 * is arranged in a 1D array as if it were [][][][slice][row][col] with 40 * Index[0] = col, Index[1] = row, Index[2] = slice, etc. 41 * 42 * The operator++ method provides a simple syntax for walking around a region 43 * of a multidimensional image. operator++ performs a jump to a random position 44 * within the specified image region. This is designed to facilitate the 45 * extraction of random indecies from the image. 46 * 47 * This is the typical use of this iterator in a loop: 48 * 49 \code 50 51 ImageRandomConstIteratorWithOnlyIndex<ImageType> it( image, image->GetRequestedRegion() ); 52 53 it.SetNumberOfSamples(200); 54 it.GoToBegin(); 55 while( !it.IsAtEnd() ) 56 { 57 std::cout << it.GetIndex() << std::endl; 58 ++it; // here it jumps to another random position inside the region 59 } 60 61 \endcode 62 * 63 * or 64 * 65 \code 66 67 ImageRandomConstIteratorWithOnlyIndex<ImageType> it( image, image->GetRequestedRegion() ); 68 69 it.SetNumberOfSamples(200); 70 it.GoToEnd(); 71 while( !it.IsAtBegin() ) 72 { 73 std::cout << it.GetIndex() << std::endl; 74 --it; // here it jumps to another random position inside the region 75 } 76 77 \endcode 78 * 79 * \warning Incrementing the iterator (++it) followed by a decrement (--it) 80 * or vice versa does not in general return the iterator to the same position. 81 * 82 * \par MORE INFORMATION 83 * For a complete description of the ITK Image Iterators and their API, please 84 * see the Iterators chapter in the ITK Software Guide. The ITK Software Guide 85 * is available in print and as a free .pdf download from https://www.itk.org. 86 * 87 * \ingroup ImageIterators 88 * 89 * Index-only iterators: 90 * 91 * \sa ImageConstIteratorWithOnlyIndex 92 * \sa ConstNeighborhoodIteratorWithOnlyIndex 93 * 94 * Pixel data-access iterators: 95 * 96 * \sa ImageConstIterator \sa ConditionalConstIterator 97 * \sa ConstNeighborhoodIterator \sa ConstShapedNeighborhoodIterator 98 * \sa ConstSliceIterator \sa CorrespondenceDataStructureIterator 99 * \sa FloodFilledFunctionConditionalConstIterator 100 * \sa FloodFilledImageFunctionConditionalConstIterator 101 * \sa FloodFilledImageFunctionConditionalIterator 102 * \sa FloodFilledSpatialFunctionConditionalConstIterator 103 * \sa FloodFilledSpatialFunctionConditionalIterator 104 * \sa ImageConstIterator \sa ImageConstIteratorWithIndex 105 * \sa ImageIterator \sa ImageIteratorWithIndex 106 * \sa ImageLinearConstIteratorWithIndex \sa ImageLinearIteratorWithIndex 107 * \sa ImageRandomConstIteratorWithIndex \sa ImageRandomIteratorWithIndex 108 * \sa ImageRegionConstIterator \sa ImageRegionConstIteratorWithIndex 109 * \sa ImageRegionExclusionConstIteratorWithIndex 110 * \sa ImageRegionExclusionIteratorWithIndex 111 * \sa ImageRegionIterator \sa ImageRegionIteratorWithIndex 112 * \sa ImageRegionReverseConstIterator \sa ImageRegionReverseIterator 113 * \sa ImageReverseConstIterator \sa ImageReverseIterator 114 * \sa ImageSliceConstIteratorWithIndex \sa ImageSliceIteratorWithIndex 115 * \sa NeighborhoodIterator \sa PathConstIterator \sa PathIterator 116 * \sa ShapedNeighborhoodIterator \sa SliceIterator 117 * \sa ImageConstIteratorWithIndex 118 * 119 * \ingroup ITKCommon 120 * 121 */ 122 template< typename TImage > 123 class ITK_TEMPLATE_EXPORT ImageRandomConstIteratorWithOnlyIndex:public ImageConstIteratorWithOnlyIndex< TImage > 124 { 125 public: 126 /** Standard class type aliases. */ 127 using Self = ImageRandomConstIteratorWithOnlyIndex; 128 using Superclass = ImageConstIteratorWithOnlyIndex< TImage >; 129 130 /** Inherit types from the superclass */ 131 using IndexType = typename Superclass::IndexType; 132 using SizeType = typename Superclass::SizeType; 133 using OffsetType = typename Superclass::OffsetType; 134 using RegionType = typename Superclass::RegionType; 135 using ImageType = typename Superclass::ImageType; 136 using IndexValueType = typename Superclass::IndexValueType; 137 using OffsetValueType = typename Superclass::OffsetValueType; 138 using SizeValueType = typename Superclass::SizeValueType; 139 140 /** Default constructor. Needed since we provide a cast constructor. */ 141 ImageRandomConstIteratorWithOnlyIndex(); 142 ~ImageRandomConstIteratorWithOnlyIndex() override = default; 143 144 /** Constructor establishes an iterator to walk a particular image and a 145 * particular region of that image. */ 146 ImageRandomConstIteratorWithOnlyIndex(const ImageType *ptr, const RegionType & region); 147 148 /** Constructor that can be used to cast from an ImageIterator to an 149 * ImageRandomConstIteratorWithOnlyIndex. Many routines return an ImageIterator, but for a 150 * particular task, you may want an ImageRandomConstIteratorWithOnlyIndex. Rather than 151 * provide overloaded APIs that return different types of Iterators, itk 152 * returns ImageIterators and uses constructors to cast from an 153 * ImageIterator to a ImageRandomConstIteratorWithOnlyIndex. */ ImageRandomConstIteratorWithOnlyIndex(const ImageConstIteratorWithOnlyIndex<TImage> & it)154 ImageRandomConstIteratorWithOnlyIndex(const ImageConstIteratorWithOnlyIndex< TImage > & it) 155 { 156 this->ImageConstIteratorWithOnlyIndex< TImage >::operator=(it); 157 } 158 159 /** Move an iterator to the beginning of the region. */ GoToBegin()160 void GoToBegin() 161 { 162 this->RandomJump(); 163 m_NumberOfSamplesDone = 0L; 164 } 165 166 /** Move an iterator to one position past the End of the region. */ GoToEnd()167 void GoToEnd() 168 { 169 this->RandomJump(); 170 m_NumberOfSamplesDone = m_NumberOfSamplesRequested; 171 } 172 173 /** Is the iterator at the beginning of the region? */ IsAtBegin()174 bool IsAtBegin() const 175 { 176 return ( m_NumberOfSamplesDone == 0L ); 177 } 178 179 /** Is the iterator at the end of the region? */ IsAtEnd()180 bool IsAtEnd() const 181 { 182 return ( m_NumberOfSamplesDone >= m_NumberOfSamplesRequested ); 183 } 184 185 /** Increment (prefix) the selected dimension. 186 * No bounds checking is performed. \sa GetIndex \sa operator-- */ 187 Self & operator++() 188 { 189 this->RandomJump(); 190 m_NumberOfSamplesDone++; 191 return *this; 192 } 193 194 /** Decrement (prefix) the selected dimension. 195 * No bounds checking is performed. \sa GetIndex \sa operator++ */ 196 Self & operator--() 197 { 198 this->RandomJump(); 199 m_NumberOfSamplesDone--; 200 return *this; 201 } 202 203 /** Set/Get number of random samples to get from the image region */ 204 void SetNumberOfSamples(SizeValueType number); 205 206 SizeValueType GetNumberOfSamples() const; 207 208 /** Reinitialize the seed of the random number generator */ 209 void ReinitializeSeed(); 210 211 void ReinitializeSeed(int); 212 213 private: 214 void RandomJump(); 215 216 using GeneratorPointer = typename Statistics::MersenneTwisterRandomVariateGenerator::Pointer; 217 GeneratorPointer m_Generator; 218 SizeValueType m_NumberOfSamplesRequested; 219 SizeValueType m_NumberOfSamplesDone; 220 SizeValueType m_NumberOfPixelsInRegion; 221 }; 222 } // end namespace itk 223 224 #ifndef ITK_MANUAL_INSTANTIATION 225 #include "itkImageRandomConstIteratorWithOnlyIndex.hxx" 226 #endif 227 228 #endif 229