DownsampleHeuristics.h

Go to the documentation of this file.
00001 #ifndef DownsampleHeuristics_h_
00002 #define DownsampleHeuristics_h_
00003 
00004 #include <itkArray2D.h>
00005 #include <vnl/vnl_vector.h>
00006 #include <itkSpatialObject.h>
00007 #include <itkImageRegionConstIteratorWithIndex.h>
00008 
00009 template<class PyramidFilterType>
00010 void
00011 scheduleImagePyramid(PyramidFilterType* pyramid)
00012 {
00013   typedef typename PyramidFilterType::InputImageType ImageType;
00014   typename ImageType::ConstPointer image = pyramid->GetInput();
00015 
00016   typedef typename ImageType::RegionType RegionType;
00017   
00018   RegionType region = image->GetLargestPossibleRegion();
00019   
00020   // concept check 3D image
00021   
00022   typedef typename RegionType::SizeType SizeType;
00023   typedef typename RegionType::SizeValueType SizeValueType;
00024   
00025   const SizeType size = region.GetSize();
00026   
00027   typedef typename ImageType::SpacingType SpacingType;
00028   SpacingType spacing = image->GetSpacing();
00029   spacing[0] = fabs(spacing[0]);
00030   spacing[1] = fabs(spacing[1]);
00031   spacing[2] = fabs(spacing[2]);
00032 
00033   unsigned int ninplanelevels = 0;
00034   unsigned int nalllevels = 0;
00035   
00036   typedef typename ImageType::SpacingValueType SpacingValueType;
00037 
00038   SpacingValueType max = spacing.GetVnlVector().max_value(); 
00039   unsigned int maxind = 0;
00040   if(spacing[1] == max)
00041     {
00042     maxind = 1;
00043     }
00044   else if(spacing[2] == max)
00045     {
00046     maxind = 2;
00047     }
00048 
00049   // Assuming the other two spacings are approximately equal by averaging them.
00050   SpacingValueType nonmax = (spacing[0] + spacing[1] + spacing[2] - max)/2.0;
00051 
00052   // downsample the other two dimensions until there average is as close to min
00053   // without going under min.  That is as long as we can multiply the larger
00054   // spacing by 2.
00055   while(nonmax * 2.0 <= max)
00056     {
00057     nonmax *= 2.0;
00058     ninplanelevels++;
00059     }
00060 
00061   SizeType afterinplanesize = size;
00062   for(unsigned int s = 0; s < 3; ++s)
00063     {
00064     if(s != maxind)
00065       {
00066       afterinplanesize[s] /= 2;
00067       }
00068     }  
00069   
00070   SpacingValueType minsize = size[0];
00071   if(size[1] < minsize)
00072     minsize = size[1];
00073   if(size[2] < minsize)
00074     minsize = size[2];
00075 
00076   // Hard-coded constant is bad
00077   while((minsize / 2.0) >= 25)
00078     {
00079     minsize /= 2.0;
00080     nalllevels++;
00081     }
00082 
00083   const unsigned int nlevels = ninplanelevels + nalllevels+1;
00084   
00085   pyramid->SetNumberOfLevels(nlevels);
00086   itk::Array2D<unsigned int> schedule = pyramid->GetSchedule();
00087   for(int i = ninplanelevels-1; i >= 0; --i)
00088     {
00089     for(unsigned int j = 0; j < 3; ++j)
00090       {
00091       if(j == maxind)
00092         {
00093         schedule(i,j) = schedule(i+1,j);
00094         }     
00095       }
00096     }
00097 
00098   pyramid->SetSchedule(schedule);
00099 }
00100 
00101 template<class ImageType>
00102 unsigned long countInsideVoxels(const ImageType* img, const itk::SpatialObject<3>* so)
00103 {
00104   unsigned long count = 0;
00105 
00106 
00107 
00108   typedef itk::ImageRegionConstIteratorWithIndex<ImageType> IteratorType;
00109   IteratorType it(img, img->GetBufferedRegion());
00110   for(it.GoToBegin(); !it.IsAtEnd(); ++it)
00111     {
00112     typedef typename ImageType::IndexType IndexType;
00113     IndexType ind = it.GetIndex();
00114     typedef typename ImageType::PointType PointType;
00115     PointType pt;
00116     img->TransformIndexToPhysicalPoint(ind, pt);
00117     
00118     if(!so || so->IsInside(pt))
00119       {
00120       ++count;
00121       }
00122     
00123     }
00124 
00125   return count;
00126 }
00127 
00128 #endif

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1