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; }; 00231 00234 ImageRandomNonRepeatingConstIteratorWithIndex(const ImageType *ptr, const RegionType& region); 00235 00242 ImageRandomNonRepeatingConstIteratorWithIndex( const ImageConstIteratorWithIndex<TImage> &it) 00243 { 00244 this->ImageConstIteratorWithIndex<TImage>::operator=(it); 00245 m_Permutation = NULL; 00246 } 00247 00249 void GoToBegin(void) 00250 { 00251 m_NumberOfSamplesDone = 0L; 00252 this->UpdatePosition(); 00253 } 00255 00257 void GoToEnd(void) 00258 { 00259 m_NumberOfSamplesDone = m_NumberOfSamplesRequested; 00260 this->UpdatePosition(); 00261 } 00263 00265 bool IsAtBegin(void) const 00266 { 00267 return (m_NumberOfSamplesDone == 0L); 00268 } 00269 00271 bool IsAtEnd(void) const 00272 { 00273 return (m_NumberOfSamplesDone >= m_NumberOfSamplesRequested); 00274 } 00275 00276 00278 itkStaticConstMacro( ImageDimension, unsigned int, 00279 ::itk::GetImageDimension< TImage >::ImageDimension ); 00280 00281 00283 typedef itk::Image< unsigned long, 00284 itkGetStaticConstMacro(ImageDimension ) 00285 > PriorityImageType; 00286 00292 void SetPriorityImage(const PriorityImageType * priorityImage); 00293 00296 Self & operator++() 00297 { 00298 m_NumberOfSamplesDone++; 00299 this->UpdatePosition(); 00300 return *this; 00301 } 00303 00306 Self & operator--() 00307 { 00308 m_NumberOfSamplesDone--; 00309 this->UpdatePosition(); 00310 return *this; 00311 } 00313 00315 void SetNumberOfSamples( unsigned long number ); 00316 unsigned long GetNumberOfSamples( void ) const; 00318 00320 void ReinitializeSeed(); 00321 00325 void ReinitializeSeed(int); 00326 00327 private: 00328 void UpdatePosition(); 00329 unsigned long m_NumberOfSamplesRequested; 00330 unsigned long m_NumberOfSamplesDone; 00331 unsigned long m_NumberOfPixelsInRegion; 00332 randomPermutation * m_Permutation; 00333 }; 00334 00335 } // end namespace itk 00336 00337 #ifndef ITK_MANUAL_INSTANTIATION 00338 #include "itkImageRandomNonRepeatingConstIteratorWithIndex.txx" 00339 #endif 00340 00341 #endif 00342 00343 00344 00345