00001
00002 #ifndef vil3d_suppress_non_max_edges_txx_
00003 #define vil3d_suppress_non_max_edges_txx_
00004
00005
00006
00007
00008
00009 #include "vil3d_suppress_non_max_edges.h"
00010 #include <vil3d/algo/vil3d_fill_border.h>
00011 #include <vil3d/vil3d_trilin_interp.h>
00012 #include <vcl_cmath.h>
00013 #include <vcl_cassert.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 template<class srcT>
00032 void vil3d_suppress_non_max_edges(const vil3d_image_view<srcT>& world_grad,
00033 const vil3d_image_view<srcT>& grad_mag,
00034 double voxel_width_i,
00035 double voxel_width_j,
00036 double voxel_width_k,
00037 srcT grad_mag_threshold,
00038 vil3d_image_view<srcT>& max_grad_mag)
00039 {
00040 assert(world_grad.nplanes()==3);
00041 assert(grad_mag.nplanes()==1);
00042 unsigned ni = world_grad.ni(), nj = world_grad.nj(), nk = world_grad.nk();
00043 assert(ni>2 && nj>2 && nk>2);
00044 assert(grad_mag.ni()==ni && grad_mag.nj()==nj && grad_mag.nk()==nk);
00045 max_grad_mag.set_size(ni,nj,nk,1);
00046
00047
00048 vil3d_fill_border(max_grad_mag,2,2,2,srcT(0));
00049
00050 const vcl_ptrdiff_t g_istep = world_grad.istep(), g_jstep = world_grad.jstep(),
00051 g_kstep = world_grad.kstep();
00052 const vcl_ptrdiff_t gm_istep = grad_mag.istep(), gm_jstep = grad_mag.jstep(),
00053 gm_kstep = grad_mag.kstep();
00054 const vcl_ptrdiff_t d_istep = max_grad_mag.istep(), d_jstep = max_grad_mag.jstep(),
00055 d_kstep = max_grad_mag.kstep();
00056 const vcl_ptrdiff_t pstep = world_grad.planestep();
00057 const vcl_ptrdiff_t pstep2 = 2*pstep;
00058
00059 unsigned ihi=ni-3;
00060 unsigned jhi=nj-3;
00061 unsigned khi=nk-3;
00062
00063 double step_size = vcl_sqrt((voxel_width_i*voxel_width_i +
00064 voxel_width_j*voxel_width_j +
00065 voxel_width_k*voxel_width_k )/3.0);
00066
00067 const srcT * gm_data = &grad_mag(0,0,0);
00068 const srcT * wg_slice = &world_grad(2,2,2);
00069 const srcT * gm_slice = &grad_mag(2,2,2);
00070 srcT * d_slice = &max_grad_mag(2,2,2);
00071
00072 for (unsigned k=2; k<=khi; ++k, wg_slice+=g_kstep, gm_slice+=gm_kstep,
00073 d_slice+=d_kstep)
00074 {
00075 const srcT* wg_row = wg_slice;
00076 const srcT* gm_row = gm_slice;
00077 srcT *d_row = d_slice;
00078
00079 for (unsigned j=2; j<=jhi; ++j, wg_row+=g_jstep, gm_row+=gm_jstep,
00080 d_row+=d_jstep)
00081 {
00082 const srcT* vg = wg_row;
00083 const srcT* vgm = gm_row;
00084 srcT *v_new_gm = d_row;
00085 for (unsigned i=2; i<=ihi; ++i, vg+=g_istep, vgm+=gm_istep,
00086 v_new_gm+=d_istep)
00087 {
00088 srcT gmag=*vgm;
00089 if (gmag<grad_mag_threshold)
00090 {
00091 *v_new_gm = 0; continue;
00092 }
00093
00094
00095
00096 double dx=step_size*vg[0]/(gmag*voxel_width_i);
00097 double dy=step_size*vg[pstep]/(gmag*voxel_width_j);
00098 double dz=step_size*vg[pstep2]/(gmag*voxel_width_k);
00099
00100
00101 double a= vcl_fabs(dx); if (a>=1.0) { dx/=a; dy/=a; dz/=a; }
00102 a= vcl_fabs(dy); if (a>=1.0) { dx/=a; dy/=a; dz/=a; }
00103 a= vcl_fabs(dz); if (a>=1.0) { dx/=a; dy/=a; dz/=a; }
00104
00105
00106 double gm1=vil3d_trilin_interp_raw(i+dx,j+dy,k+dz,gm_data,gm_istep,gm_jstep,gm_kstep);
00107 if (gm1>gmag) { *v_new_gm=0; continue; }
00108 double gm2=vil3d_trilin_interp_raw(i-dx,j-dy,k-dz,gm_data,gm_istep,gm_jstep,gm_kstep);
00109 if (gm2>gmag) *v_new_gm=0;
00110 else *v_new_gm=gmag;
00111 }
00112 }
00113 }
00114 }
00115
00116 #undef VIL3D_SUPPRESS_NON_MAX_EDGES_INSTANTIATE
00117 #define VIL3D_SUPPRESS_NON_MAX_EDGES_INSTANTIATE(srcT) \
00118 template void vil3d_suppress_non_max_edges(const vil3d_image_view<srcT >& world_grad,\
00119 const vil3d_image_view<srcT >& grad_mag,\
00120 double voxel_width_i,\
00121 double voxel_width_j,\
00122 double voxel_width_k,\
00123 srcT grad_mag_threshold,\
00124 vil3d_image_view<srcT >& max_grad_mag)
00125
00126 #endif // vil3d_suppress_non_max_edges_txx_