00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: itkImageRandomNonRepeatingConstIteratorWithIndex.h,v $ 00005 Language: C++ 00006 Date: $Date: 2005/10/03 15:18:45 $ 00007 Version: $Revision: 1.6 $ 00008 00009 Copyright (c) Insight Software Consortium. All rights reserved. 00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 #ifndef __itkImageRandomNonRepeatingConstIteratorWithIndex_h 00018 #define __itkImageRandomNonRepeatingConstIteratorWithIndex_h 00019 00020 #include "itkImageConstIteratorWithIndex.h" 00021 #include "itkImage.h" 00022 #include <algorithm> 00023 #include <iostream> 00024 #include "itkMersenneTwisterRandomVariateGenerator.h" 00025 00026 00027 namespace itk 00028 { 00029 00030 00031 /* 00032 The itk::ImageRandomNonRepeatingIterator works by creating a random 00033 permutation of the image pixels and then using that to control the 00034 order in which it accesses them. The classes nodeOfPermutation and 00035 randomPermutation are used to support that. randomPermutation is 00036 basically container which holds nodeOfPermutation objects. The 00037 node class overloads the < operator, which allows the sort algorithm 00038 from the STL to be used on it. 00039 */ 00040 class nodeOfPermutation 00041 { 00042 public: 00043 unsigned long priority; 00044 unsigned long index; 00045 double value; 00046 nodeOfPermutation () 00047 { 00048 priority=0; 00049 index=0; 00050 value=0.0; 00051 } 00052 bool operator<( const nodeOfPermutation& b) const 00053 { 00054 if(priority==b.priority) 00055 { 00056 return value < b.value; 00057 } 00058 else 00059 { 00060 return priority<b.priority; 00061 } 00062 } 00063 }; 00064 class randomPermutation 00065 { 00066 public: 00067 nodeOfPermutation * permutation; 00068 Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_Generator; 00069 unsigned long size; 00070 randomPermutation(unsigned long sz) 00071 { 00072 size=sz; 00073 permutation=new nodeOfPermutation[size]; 00074 m_Generator = Statistics::MersenneTwisterRandomVariateGenerator::New(); 00075 this->Shuffle(); 00076 } 00077 void Dump() 00078 { 00079 for(unsigned int i=0;i<size;i++) 00080 { 00081 std::cout<<permutation[i].value<<" "<<permutation[i].priority 00082 <<" "<<permutation[i].index<<";"; 00083 std::cout<<std::endl; 00084 } 00085 } 00086 void SetPriority(unsigned long i,unsigned long priority) 00087 { 00088 if(i>size) 00089 { 00090 std::cerr<<"Error - i dont have "<<i<<" elements"<<std::endl; 00091 } 00092 else 00093 { 00094 permutation[i].priority=priority; 00095 } 00096 } 00097 void Shuffle() 00098 { 00099 for(unsigned int i=0;i<size;i++) 00100 { 00101 permutation[i].value= m_Generator->GetVariateWithClosedRange ( 1.0 ); 00102 permutation[i].index=i; 00103 } 00104 std::sort(permutation,permutation+size); 00105 } 00106 unsigned long operator[](unsigned long i) 00107 { 00108 return permutation[i].index; 00109 } 00110 ~randomPermutation() 00111 { 00112 delete [] permutation; 00113 } 00114 00116 void ReinitializeSeed() 00117 { 00118 m_Generator->Initialize(); 00119 } 00120 00121 void ReinitializeSeed(int seed) 00122 { 00123 m_Generator->Initialize ( seed ); 00124 } 00125 }; 00126 00127 00195 template<typename TImage> 00196 class ITK_EXPORT ImageRandomNonRepeatingConstIteratorWithIndex : public ImageConstIteratorWithIndex<TImage> 00197 { 00198 public: 00200 typedef ImageRandomNonRepeatingConstIteratorWithIndex Self; 00201 typedef ImageConstIteratorWithIndex<TImage> Superclass; 00202 00207 typedef typename TImage::IndexType IndexType; 00208 00213 typedef typename TImage::RegionType RegionType; 00214 00219 typedef TImage ImageType; 00220 00224 typedef typename TImage::PixelContainer PixelContainer; 00225 typedef typename PixelContainer::Pointer PixelContainerPointer; 00226 00228 ImageRandomNonRepeatingConstIteratorWithIndex(); 00229 ~ImageRandomNonRepeatingConstIteratorWithIndex() { if( m_Permutation ) delete m_Permutation; }; 00230 00233 ImageRandomNonRepeatingConstIteratorWithIndex(const ImageType *ptr, const RegionType& region); 00234 00241 ImageRandomNonRepeatingConstIteratorWithIndex( const ImageConstIteratorWithIndex<TImage> &it) 00242 { 00243 this->ImageConstIteratorWithIndex<TImage>::operator=(it); 00244 m_Permutation = NULL; 00245 } 00247 void GoToBegin(void) 00248 { 00249 m_NumberOfSamplesDone = 0L; 00250 this->UpdatePosition(); 00251 } 00252 00254 void GoToEnd(void) 00255 { 00256 m_NumberOfSamplesDone = m_NumberOfSamplesRequested; 00257 this->UpdatePosition(); 00258 } 00259 00261 bool IsAtBegin(void) const 00262 { 00263 return (m_NumberOfSamplesDone == 0L); 00264 } 00265 00267 bool IsAtEnd(void) const 00268 { 00269 return (m_NumberOfSamplesDone >= m_NumberOfSamplesRequested); 00270 } 00271 00272 00274 itkStaticConstMacro( ImageDimension, unsigned int, 00275 ::itk::GetImageDimension< TImage >::ImageDimension ); 00276 00277 00279 typedef itk::Image< unsigned long, 00280 itkGetStaticConstMacro(ImageDimension ) 00281 > PriorityImageType; 00282 00288 void SetPriorityImage(const PriorityImageType * priorityImage); 00289 00292 Self & operator++() 00293 { 00294 m_NumberOfSamplesDone++; 00295 this->UpdatePosition(); 00296 return *this; 00297 } 00298 00301 Self & operator--() 00302 { 00303 m_NumberOfSamplesDone--; 00304 this->UpdatePosition(); 00305 return *this; 00306 } 00307 00309 void SetNumberOfSamples( unsigned long number ); 00310 unsigned long GetNumberOfSamples( void ) const; 00311 00313 void ReinitializeSeed(); 00317 void ReinitializeSeed(int); 00318 00319 private: 00320 void UpdatePosition(); 00321 unsigned long m_NumberOfSamplesRequested; 00322 unsigned long m_NumberOfSamplesDone; 00323 unsigned long m_NumberOfPixelsInRegion; 00324 randomPermutation * m_Permutation; 00325 }; 00326 00327 } // end namespace itk 00328 00329 #ifndef ITK_MANUAL_INSTANTIATION 00330 #include "itkImageRandomNonRepeatingConstIteratorWithIndex.txx" 00331 #endif 00332 00333 #endif 00334 00335 00336