contrib/mul/vil3d/algo/vil3d_grad_1x3.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Apply gradient filter to single plane 3D image
00004 // \author Tim Cootes
00005 
00006 #include "vil3d_grad_1x3.h"
00007 #include <vil3d/vil3d_slice.h>
00008 #include <vcl_cassert.h>
00009 
00010 //: Fill 1 pixel border in image with zeros
00011 void vil3d_zero_border_1plane(vil3d_image_view<float>& image)
00012 {
00013   unsigned ni = image.ni();
00014   unsigned nj = image.nj();
00015   unsigned nk = image.nk();
00016 
00017   vil3d_slice_ij(image,0).fill(0.0f);
00018   vil3d_slice_ij(image,nk-1).fill(0.0f);
00019   vil3d_slice_jk(image,0).fill(0.0f);
00020   vil3d_slice_jk(image,ni-1).fill(0.0f);
00021   vil3d_slice_ik(image,0).fill(0.0f);
00022   vil3d_slice_ik(image,nj-1).fill(0.0f);
00023 }
00024 
00025 
00026 
00027 //: Compute gradients of single plane of 2D data using 1x3 grad filters
00028 void vil3d_grad_1x3_1plane(const vil3d_image_view<vxl_byte>& src_im,
00029                            vil3d_image_view<float>& grad_i,
00030                            vil3d_image_view<float>& grad_j,
00031                            vil3d_image_view<float>& grad_k)
00032 {
00033   unsigned ni = src_im.ni();
00034   unsigned nj = src_im.nj();
00035   unsigned nk = src_im.nk();
00036 
00037   // Not exhaustive
00038   assert(grad_i.ni()==ni);
00039   assert(grad_j.nj()==nj);
00040   assert(grad_k.nk()==nk);
00041 
00042   if (ni<=2 || nj<=2 || nk<=2)
00043   {
00044     // Zero the elements in the column
00045     grad_i.fill(0.0f);
00046     grad_j.fill(0.0f);
00047     grad_k.fill(0.0f);
00048     return;
00049   }
00050 
00051   // Compute relative sampling positions
00052   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00053   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00054   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00055 
00056   const unsigned ni1 = ni-1;
00057   const unsigned nj1 = nj-1;
00058   const unsigned nk1 = nk-1;
00059 
00060   const vcl_ptrdiff_t src_istep = src_im.istep();
00061   const vcl_ptrdiff_t gri_istep = grad_i.istep();
00062   const vcl_ptrdiff_t grj_istep = grad_j.istep();
00063   const vcl_ptrdiff_t grk_istep = grad_j.istep();
00064   
00065   for (unsigned k=1;k<nk1;++k)
00066   {
00067     for (unsigned j=1;j<nj1;++j)
00068     {
00069       const unsigned char* s = &src_im(1,j,k);
00070       float* pgi = &grad_i(1,j,k);
00071       float* pgj = &grad_j(1,j,k);
00072       float* pgk = &grad_k(1,j,k);
00073 
00074       for (unsigned i=1;i<ni1;++i)
00075       {
00076         // Compute gradient in i
00077         // Note: Multiply each element individually
00078         //      to ensure conversion to float before subtraction
00079         *pgi = 0.5f*s[di1] - 0.5f*s[di2];
00080         // Compute gradient in j
00081         *pgj = 0.5f*s[dj1] - 0.5f*s[dj2];
00082         // Compute gradient in k
00083         *pgk = 0.5f*s[dk1] - 0.5f*s[dk2];
00084 
00085         s   += src_istep;
00086         pgi += gri_istep;
00087         pgj += grj_istep;
00088         pgk += grk_istep;
00089       }
00090     }
00091   }
00092 
00093   vil3d_zero_border_1plane(grad_i);
00094   vil3d_zero_border_1plane(grad_j);
00095   vil3d_zero_border_1plane(grad_k);
00096 }
00097 
00098 //: Compute gradients of single plane of 3D data using 1x3 grad filters
00099 void vil3d_grad_1x3_1plane(const vil3d_image_view<float>& src_im,
00100                            vil3d_image_view<float>& grad_i,
00101                            vil3d_image_view<float>& grad_j,
00102                            vil3d_image_view<float>& grad_k)
00103 {
00104   unsigned ni = src_im.ni();
00105   unsigned nj = src_im.nj();
00106   unsigned nk = src_im.nk();
00107 
00108   if (ni<=2 || nj<=2 || nk<=2)
00109   {
00110     // Zero the elements in the column
00111     grad_i.fill(0.0f);
00112     grad_j.fill(0.0f);
00113     grad_k.fill(0.0f);
00114     return;
00115   }
00116 
00117   // Compute relative sampling positions
00118   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00119   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00120   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00121 
00122   const unsigned ni1 = ni-1;
00123   const unsigned nj1 = nj-1;
00124   const unsigned nk1 = nk-1;
00125 
00126   for (unsigned k=1;k<nk1;++k)
00127   {
00128     for (unsigned j=1;j<nj1;++j)
00129     {
00130       const float* s = &src_im(1,j,k);
00131       float* pgi = &grad_i(1,j,k);
00132       float* pgj = &grad_j(1,j,k);
00133       float* pgk = &grad_k(1,j,k);
00134 
00135       for (unsigned i=1;i<ni1;++i)
00136       {
00137         // Compute gradient in i
00138         *pgi = 0.5f*(s[di1] - s[di2]);
00139         // Compute gradient in j
00140         *pgj = 0.5f*(s[dj1] - s[dj2]);
00141         // Compute gradient in k
00142         *pgk = 0.5f*(s[dk1] - s[dk2]);
00143 
00144         s   += src_im.istep();
00145         pgi += grad_i.istep();
00146         pgj += grad_j.istep();
00147         pgk += grad_k.istep();
00148       }
00149     }
00150   }
00151 
00152   vil3d_zero_border_1plane(grad_i);
00153   vil3d_zero_border_1plane(grad_j);
00154   vil3d_zero_border_1plane(grad_k);
00155 }
00156 
00157 
00158 //: Compute gradients of single plane of 3D data using 1x3 grad filters
00159 void vil3d_grad_1x3_1plane(const vil3d_image_view<vxl_int_32>& src_im,
00160                            vil3d_image_view<float>& grad_i,
00161                            vil3d_image_view<float>& grad_j,
00162                            vil3d_image_view<float>& grad_k)
00163 {
00164   unsigned ni = src_im.ni();
00165   unsigned nj = src_im.nj();
00166   unsigned nk = src_im.nk();
00167 
00168   if (ni<=2 || nj<=2 || nk<=2)
00169   {
00170     // Zero the elements in the column
00171     grad_i.fill(0.0f);
00172     grad_j.fill(0.0f);
00173     grad_k.fill(0.0f);
00174     return;
00175   }
00176 
00177   // Compute relative sampling positions
00178   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00179   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00180   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00181 
00182   const unsigned ni1 = ni-1;
00183   const unsigned nj1 = nj-1;
00184   const unsigned nk1 = nk-1;
00185 
00186   for (unsigned k=1;k<nk1;++k)
00187   {
00188     for (unsigned j=1;j<nj1;++j)
00189     {
00190       const vxl_int_32* s = &src_im(1,j,k);
00191       float* pgi = &grad_i(1,j,k);
00192       float* pgj = &grad_j(1,j,k);
00193       float* pgk = &grad_k(1,j,k);
00194 
00195       for (unsigned i=1;i<ni1;++i)
00196       {
00197         // Compute gradient in i
00198         *pgi = 0.5f*(s[di1] - s[di2]);
00199         // Compute gradient in j
00200         *pgj = 0.5f*(s[dj1] - s[dj2]);
00201         // Compute gradient in k
00202         *pgk = 0.5f*(s[dk1] - s[dk2]);
00203 
00204         s   += src_im.istep();
00205         pgi += grad_i.istep();
00206         pgj += grad_j.istep();
00207         pgk += grad_k.istep();
00208       }
00209     }
00210   }
00211 
00212   vil3d_zero_border_1plane(grad_i);
00213   vil3d_zero_border_1plane(grad_j);
00214   vil3d_zero_border_1plane(grad_k);
00215 }
00216 
00217 //: Compute square dgradient magnitude of single plane of 3D data
00218 //  Use (-0.5,0,+0.5) filters in i,j,k
00219 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<vxl_byte>& src_im,
00220                                   vil3d_image_view<float>& grad_mag2)
00221 {
00222   unsigned ni = src_im.ni();
00223   unsigned nj = src_im.nj();
00224   unsigned nk = src_im.nk();
00225 
00226   assert(grad_mag2.ni()==ni);
00227   assert(grad_mag2.nj()==nj);
00228   assert(grad_mag2.nk()==nk);
00229 
00230   if (ni<=2 || nj<=2 || nk<=2)
00231   {
00232     grad_mag2.fill(0.0f);
00233     return;
00234   }
00235 
00236   // Compute relative sampling positions
00237   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00238   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00239   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00240 
00241   const unsigned ni1 = ni-1;
00242   const unsigned nj1 = nj-1;
00243   const unsigned nk1 = nk-1;
00244 
00245   for (unsigned k=1;k<nk1;++k)
00246   {
00247     for (unsigned j=1;j<nj1;++j)
00248     {
00249       const unsigned char* s = &src_im(1,j,k);
00250       float* pg = &grad_mag2(1,j,k);
00251 
00252       for (unsigned i=1;i<ni1;++i)
00253       {
00254         // Compute gradient in i
00255         // Note: Multiply each element individually
00256         //      to ensure conversion to float before subtraction
00257         float dx = 0.5f*s[di1] - 0.5f*s[di2];
00258         // Compute gradient in j
00259         float dy = 0.5f*s[dj1] - 0.5f*s[dj2];
00260         // Compute gradient in k
00261         float dz = 0.5f*s[dk1] - 0.5f*s[dk2];
00262 
00263         *pg = dx*dx + dy*dy + dz*dz;
00264 
00265         s   += src_im.istep();
00266         pg += grad_mag2.istep();
00267       }
00268     }
00269   }
00270 
00271   vil3d_zero_border_1plane(grad_mag2);
00272 }
00273 
00274 //: Compute square gradient magnitude of single plane of 3D data
00275 //  Use (-0.5,0,+0.5) filters in i,j,k
00276 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<float>& src_im,
00277                                   vil3d_image_view<float>& grad_mag2)
00278 {
00279   unsigned ni = src_im.ni();
00280   unsigned nj = src_im.nj();
00281   unsigned nk = src_im.nk();
00282 
00283   assert(grad_mag2.ni()==ni);
00284   assert(grad_mag2.nj()==nj);
00285   assert(grad_mag2.nk()==nk);
00286 
00287   if (ni<=2 || nj<=2 || nk<=2)
00288   {
00289     grad_mag2.fill(0.0f);
00290     return;
00291   }
00292 
00293   // Compute relative sampling positions
00294   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00295   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00296   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00297 
00298   const unsigned ni1 = ni-1;
00299   const unsigned nj1 = nj-1;
00300   const unsigned nk1 = nk-1;
00301 
00302   for (unsigned k=1;k<nk1;++k)
00303   {
00304     for (unsigned j=1;j<nj1;++j)
00305     {
00306       const float* s = &src_im(1,j,k);
00307       float* pg = &grad_mag2(1,j,k);
00308 
00309       for (unsigned i=1;i<ni1;++i)
00310       {
00311         // Compute gradient in i
00312         float dx = s[di1] - s[di2];
00313         // Compute gradient in j
00314         float dy = s[dj1] - s[dj2];
00315         // Compute gradient in k
00316         float dz = s[dk1] - s[dk2];
00317 
00318         *pg = 0.25f*(dx*dx + dy*dy + dz*dz);
00319 
00320         s   += src_im.istep();
00321         pg += grad_mag2.istep();
00322       }
00323     }
00324   }
00325 
00326   vil3d_zero_border_1plane(grad_mag2);
00327 }
00328 
00329 
00330 //: Compute square gradient magnitude of single plane of 3D data
00331 //  Use (-0.5,0,+0.5) filters in i,j,k
00332 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<vxl_int_32>& src_im,
00333                                   vil3d_image_view<float>& grad_mag2)
00334 {
00335   unsigned ni = src_im.ni();
00336   unsigned nj = src_im.nj();
00337   unsigned nk = src_im.nk();
00338 
00339   assert(grad_mag2.ni()==ni);
00340   assert(grad_mag2.nj()==nj);
00341   assert(grad_mag2.nk()==nk);
00342 
00343   if (ni<=2 || nj<=2 || nk<=2)
00344   {
00345     grad_mag2.fill(0.0f);
00346     return;
00347   }
00348 
00349   // Compute relative sampling positions
00350   const vcl_ptrdiff_t di1 = src_im.istep(), di2= -src_im.istep();
00351   const vcl_ptrdiff_t dj1 = src_im.jstep(), dj2= -src_im.jstep();
00352   const vcl_ptrdiff_t dk1 = src_im.kstep(), dk2= -src_im.kstep();
00353 
00354   const unsigned ni1 = ni-1;
00355   const unsigned nj1 = nj-1;
00356   const unsigned nk1 = nk-1;
00357 
00358   for (unsigned k=1;k<nk1;++k)
00359   {
00360     for (unsigned j=1;j<nj1;++j)
00361     {
00362       const vxl_int_32* s = &src_im(1,j,k);
00363       float* pg = &grad_mag2(1,j,k);
00364 
00365       for (unsigned i=1;i<ni1;++i)
00366       {
00367         // Compute gradient in i
00368         float dx = static_cast<float>(s[di1]) - static_cast<float>(s[di2]);
00369         // Compute gradient in j
00370         float dy = static_cast<float>(s[dj1]) - static_cast<float>(s[dj2]);
00371         // Compute gradient in k
00372         float dz = static_cast<float>(s[dk1]) - static_cast<float>(s[dk2]);
00373 
00374         *pg = 0.25f*(dx*dx + dy*dy + dz*dz);
00375 
00376         s   += src_im.istep();
00377         pg += grad_mag2.istep();
00378       }
00379     }
00380   }
00381 
00382   vil3d_zero_border_1plane(grad_mag2);
00383 }
00384