00001
00002 #ifndef vil3d_world_gradients_txx_
00003 #define vil3d_world_gradients_txx_
00004
00005
00006
00007
00008
00009 #include "vil3d_world_gradients.h"
00010 #include <vil3d/algo/vil3d_fill_border.h>
00011 #include <vil3d/vil3d_transform.h>
00012 #include <vil3d/vil3d_plane.h>
00013 #include <vcl_cmath.h>
00014 #include <vcl_cassert.h>
00015
00016
00017 class vil3d_math_scale_functor
00018 {
00019 private:
00020 double s_;
00021 public:
00022 vil3d_math_scale_functor(double s) : s_(s) {}
00023 float operator()(vxl_byte x) const { return float(s_*x); }
00024 float operator()(unsigned x) const { return float(s_*x); }
00025 float operator()(short x) const { return float(s_*x); }
00026 float operator()(int x) const { return float(s_*x); }
00027 float operator()(float x) const { return float(s_*x); }
00028 float operator()(double x) const { return float(s_*x); }
00029 };
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 template<class srcT, class destT>
00044 void vil3d_world_gradients(const vil3d_image_view<srcT>& grad_i,
00045 const vil3d_image_view<srcT>& grad_j,
00046 const vil3d_image_view<srcT>& grad_k,
00047 double voxel_width_i,
00048 double voxel_width_j,
00049 double voxel_width_k,
00050 vil3d_image_view<destT>& world_grad,
00051 vil3d_image_view<destT>& grad_mag)
00052 {
00053 assert(grad_i.nplanes()==grad_j.nplanes());
00054 assert(grad_i.nplanes()==grad_k.nplanes());
00055 assert(grad_i.nplanes()==1);
00056 unsigned ni = grad_i.ni(), nj = grad_i.nj(), nk = grad_i.nk();
00057 assert(ni>2 && nj>2 && nk>2);
00058 assert(grad_j.ni()==ni && grad_j.nj()==nj && grad_j.nk()==nk);
00059 assert(grad_k.ni()==ni && grad_k.nj()==nj && grad_k.nk()==nk);
00060 world_grad.set_size(ni,nj,nk,3);
00061 grad_mag.set_size(ni,nj,nk,1);
00062
00063 vil3d_image_view<destT> w_grad_i=vil3d_plane(world_grad,0);
00064 vil3d_image_view<destT> w_grad_j=vil3d_plane(world_grad,1);
00065 vil3d_image_view<destT> w_grad_k=vil3d_plane(world_grad,2);
00066
00067 vil3d_transform(grad_i,w_grad_i,vil3d_math_scale_functor(1.0/voxel_width_i));
00068 vil3d_transform(grad_j,w_grad_j,vil3d_math_scale_functor(1.0/voxel_width_j));
00069 vil3d_transform(grad_k,w_grad_k,vil3d_math_scale_functor(1.0/voxel_width_k));
00070
00071
00072 vil3d_fill_border(grad_mag,1,1,1,destT(0));
00073
00074 const vcl_ptrdiff_t gi_istep = w_grad_i.istep(), gi_jstep = w_grad_i.jstep(),
00075 gi_kstep = w_grad_i.kstep();
00076 const vcl_ptrdiff_t gj_istep = w_grad_j.istep(), gj_jstep = w_grad_j.jstep(),
00077 gj_kstep = w_grad_j.kstep();
00078 const vcl_ptrdiff_t gk_istep = w_grad_k.istep(), gk_jstep = w_grad_k.jstep(),
00079 gk_kstep = w_grad_k.kstep();
00080 const vcl_ptrdiff_t gm_istep = grad_mag.istep(), gm_jstep = grad_mag.jstep(),
00081 gm_kstep = grad_mag.kstep();
00082
00083 unsigned ihi=ni-2;
00084 unsigned jhi=nj-2;
00085 unsigned khi=nk-2;
00086
00087
00088 double c2i=1.0/(voxel_width_i*voxel_width_i);
00089 double c2j=1.0/(voxel_width_j*voxel_width_j);
00090 double c2k=1.0/(voxel_width_k*voxel_width_k);
00091
00092
00093 const srcT * gi_slice = &w_grad_i(1,1,1);
00094 const srcT * gj_slice = &w_grad_j(1,1,1);
00095 const srcT * gk_slice = &w_grad_k(1,1,1);
00096 destT * gm_slice = &grad_mag(1,1,1);
00097
00098 for (unsigned k=1; k<=khi; ++k, gi_slice+=gi_kstep, gj_slice+=gj_kstep,
00099 gk_slice+=gk_kstep, gm_slice+=gm_kstep)
00100 {
00101 const srcT* gi_row=gi_slice;
00102 const srcT* gj_row=gj_slice;
00103 const srcT* gk_row=gk_slice;
00104 destT *gm_row = gm_slice;
00105
00106 for (unsigned j=2; j<=jhi; ++j, gi_row+=gi_jstep, gj_row+=gj_jstep,
00107 gk_row+=gk_jstep, gm_row+=gm_jstep)
00108 {
00109 const srcT* pgi = gi_row;
00110 const srcT* pgj = gj_row;
00111 const srcT* pgk = gk_row;
00112 destT *pgm = gm_row;
00113 for (unsigned i=2; i<=ihi; ++i, pgi+=gi_istep, pgj+=gj_istep,
00114 pgk+=gk_istep, pgm+=gm_istep)
00115 {
00116 *pgm=destT(vcl_sqrt(double(c2i*pgi[0]*pgi[0] + c2j*pgj[0]*pgj[0] + c2k*pgk[0]*pgk[0])));
00117 }
00118 }
00119 }
00120 }
00121
00122 #undef VIL3D_WORLD_GRADIENTS_INSTANTIATE
00123 #define VIL3D_WORLD_GRADIENTS_INSTANTIATE(srcT, destT) \
00124 template void vil3d_world_gradients(const vil3d_image_view<srcT >& grad_i,\
00125 const vil3d_image_view<srcT >& grad_j,\
00126 const vil3d_image_view<srcT >& grad_k,\
00127 double voxel_width_i,\
00128 double voxel_width_j,\
00129 double voxel_width_k,\
00130 vil3d_image_view<destT >& world_grad,\
00131 vil3d_image_view<destT >& grad_mag)
00132
00133 #endif // vil3d_world_gradients_txx_