aimstil  5.0.5
recursiveFilters.h
Go to the documentation of this file.
1 #ifndef TIL_RECURSIVE_FILTERS_H
2 #define TIL_RECURSIVE_FILTERS_H
3 
4 // includes from STL
5 #include <math.h>
6 
7 // includes from TIL library
8 #include "til/til_common.h"
9 #include "til/convert.h"
10 #include "til/imageArith.h"
11 #include "til/miscTools.h"
12 #include "til/RF4Gaussian.h"
13 #include "til/rf4Tools.h"
14 
15 
16 // Namespace
17 namespace til {
18 
19 
20 // Assumption: the sigma entered is the largest sigma possible
21 // i.e. it corresponds to the axis with the smallest voxel size.
22 // The motivation is that, e.g. for CT images of different
23 // voxel size in the Z dimension, at least the smoothing
24 // on X-Y planes remains the same.
25 /*
26 template < typename T >
27 T modifySigmaAccordingToVoxelSize
28 (T sigma,
29  float vx, float vy, float vz,
30  ImageAxis axis)
31 {
32 
33  float vMin = min(vx, min(vy, vz));
34 
35  if (axis==X_AXIS) return T(sigma * vMin/vx);
36  if (axis==Y_AXIS) return T(sigma * vMin/vy);
37  if (axis==Z_AXIS) return T(sigma * vMin/vz);
38 
39  throw std::invalid_argument("Invalid axis");
40 }
41 */
42 template < typename T >
44 (T sigma, const numeric_array<float,3> & vdim, ImageAxis axis)
45 {
46 
47  float vMin = min(vdim);
48 
49  if (axis==X_AXIS) return T(sigma * vMin/vdim[0]);
50  if (axis==Y_AXIS) return T(sigma * vMin/vdim[1]);
51  if (axis==Z_AXIS) return T(sigma * vMin/vdim[2]);
52 
53  throw std::invalid_argument("Invalid axis");
54 }
55 
56 // Recursive Gaussian filtering of size sigma
57 // Warning: pointer im is changed
58 
59 template < class TImage >
60 void recursiveGaussianSmoothing(TImage &im, typename TImage::value_type sigma)
61 {
62  typedef typename TImage::value_type T;
63  typedef RecursiveFilterSum < RecursiveFilter<double, +1, 4>, RecursiveFilter<double, -1, 4> > RecGaussian;
64 
65  T sigmaOriginal = sigma;
66 
67  for (ImageAxis axis = X_AXIS; axis <= Z_AXIS; ++axis)
68  {
69  // Apply filter only if image is not flat in that direction
70  if (im.dim()[axis] > 1)
71  {
72  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), axis);
73  RecGaussian rf4 = RF4Gaussian(sigma);
74  filterAlongAxis(im, im, axis, rf4);
75  }
76  }
77 }
78 
79 
80 
81 
82 // Recursive Gaussian filtering of size sigma
83 
84 template < typename TImage >
85 void recursiveGaussianDerivative(TImage &im, typename TImage::value_type sigma,
86  ImageAxis axis)
87 {
88  typedef typename TImage::value_type T;
89  typedef RecursiveFilterSum < RecursiveFilter<double, +1, 4>, RecursiveFilter<double, -1, 4> > RecGaussian;
90 
91  T sigmaOriginal = sigma;
92 
93  for (ImageAxis i=X_AXIS; i<=Z_AXIS; ++i)
94  {
95  if (i == axis)
96  {
97  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
98  RecGaussian rf4 = RF4GaussianDerivative<T>(sigma, im.vdim()[i]);
99  filterAlongAxis(im, im, i, rf4);
100  }
101  else
102  {
103  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
104  RecGaussian rf4 = RF4Gaussian(sigma);
105  filterAlongAxis(im, im, i, rf4);
106  }
107  }
108 }
109 
110 
111 
112 template < typename TImage >
113 void recursiveGaussianSecondDerivative(TImage &im, typename TImage::value_type sigma, ImageAxis axis1, ImageAxis axis2)
114 {
115  typedef typename TImage::value_type T;
116  typedef RecursiveFilterSum < RecursiveFilter<double, +1, 4>, RecursiveFilter<double, -1, 4> > RecGaussian;
117 
118  T sigmaOriginal = sigma;
119 
120  if (axis1 == axis2)
121  {
122  for (ImageAxis i=X_AXIS; i<=Z_AXIS; ++i)
123  {
124  if (i == axis1)
125  {
126  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
127  RecGaussian rf4 = RF4GaussianSecondDerivative(sigma);
128  filterAlongAxis(im, im, i, rf4);
129  }
130  else
131  {
132  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
133  RecGaussian rf4 = RF4Gaussian(sigma);
134  filterAlongAxis(im, im, i, rf4);
135  }
136  }
137  }
138  else
139  {
140  for (ImageAxis i=X_AXIS; i<=Z_AXIS; ++i)
141  {
142  if (i == axis1 || i == axis2)
143  {
144  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
145  RecGaussian rf4 = RF4GaussianDerivative(sigma);
146  filterAlongAxis(im, im, i, rf4);
147  }
148  else
149  {
150  sigma = modifySigmaAccordingToVoxelSize(sigmaOriginal, im.vdim(), i);
151  RecGaussian rf4 = RF4Gaussian(sigma);
152  filterAlongAxis(im, im, i, rf4);
153  }
154  }
155  }
156 }
157 
158 
159 
160 // Compute image gradient using recursive Gaussian derivative filtering
161 
162 template <class TImage1, class TImage2>
163 void recursiveGaussianGradient(const TImage1 &im,
164  TImage2 &dx,
165  TImage2 &dy,
166  TImage2 &dz,
167  typename TImage2::value_type sigma)
168 {
169 
170  convert_im(im, dx);
171  copy(dx, dy);
172  copy(dx, dz);
173 
177 
178 }
179 
180 template < class TImage1, class TImage2 >
181 void recursiveGaussianHessian(const TImage1 &im,
182  TImage2 &dxx,
183  TImage2 &dxy,
184  TImage2 &dxz,
185  TImage2 &dyy,
186  TImage2 &dyz,
187  TImage2 &dzz,
188  typename TImage2::value_type sigma)
189 {
190 
191  convert_im(im, dxx);
192  copy(dxx, dxy);
193  copy(dxx, dxz);
194  copy(dxx, dyy);
195  copy(dxx, dyz);
196  copy(dxx, dzz);
197 
201 
204 
206 }
207 
208 
209 } // namespace
210 
211 #endif
212 
boost::enable_if< is_Image< TImage >, typename TImage::value_type >::type min(const TImage &im)
Sum of two recursive filters, a forward and a backward one.
void recursiveGaussianGradient(const TImage1 &im, TImage2 &dx, TImage2 &dy, TImage2 &dz, typename TImage2::value_type sigma)
void recursiveGaussianSmoothing(TImage &im, typename TImage::value_type sigma)
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4Gaussian(T sigma)
Definition: RF4Gaussian.h:177
General macros, definitions and functions.
void recursiveGaussianSecondDerivative(TImage &im, typename TImage::value_type sigma, ImageAxis axis1, ImageAxis axis2)
ImageAxis
Definition: miscTools.h:123
void copy(const TImage &in, TImage &out)
Copy one image to another.
Definition: imageTools.h:133
void filterAlongAxis(const TImage &im, TImage &out, ImageAxis axis, const TLineFilter &filter)
Definition: rf4Tools.h:25
T modifySigmaAccordingToVoxelSize(T sigma, const numeric_array< float, 3 > &vdim, ImageAxis axis)
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4GaussianDerivative(T sigma, T stepSize=1)
Definition: RF4Gaussian.h:217
void recursiveGaussianHessian(const TImage1 &im, TImage2 &dxx, TImage2 &dxy, TImage2 &dxz, TImage2 &dyy, TImage2 &dyz, TImage2 &dzz, typename TImage2::value_type sigma)
void convert_im(TImageIn const &in, TImageOut &out)
Convert an image into the type of the other image.
Definition: convert.h:79
void recursiveGaussianDerivative(TImage &im, typename TImage::value_type sigma, ImageAxis axis)
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4GaussianSecondDerivative(T sigma)
Definition: RF4Gaussian.h:256