core/vil/algo/vil_sobel_1x3.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Apply gradient operator to 2D planes of data
00004 // \author Tim Cootes
00005 
00006 #include "vil_sobel_1x3.h"
00007 
00008 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
00009 //  Computes both i and j gradients of an ni x nj plane of data
00010 VCL_DEFINE_SPECIALIZATION
00011 void vil_sobel_1x3_1plane(const unsigned char* src,
00012                           vcl_ptrdiff_t s_istep, vcl_ptrdiff_t s_jstep,
00013                           float* gi, vcl_ptrdiff_t gi_istep, vcl_ptrdiff_t gi_jstep,
00014                           float* gj, vcl_ptrdiff_t gj_istep, vcl_ptrdiff_t gj_jstep,
00015                           unsigned ni, unsigned nj)
00016 {
00017   const unsigned char* s_data = src;
00018   float *gi_data = gi;
00019   float *gj_data = gj;
00020 
00021   if (ni==0 || nj==0) return;
00022   if (ni==1)
00023   {
00024       // Zero the elements in the column
00025     for (unsigned j=0;j<nj;++j)
00026     {
00027       *gi_data = 0;
00028       *gj_data = 0;
00029       gi_data += gi_jstep;
00030       gj_data += gj_jstep;
00031     }
00032     return;
00033   }
00034   if (nj==1)
00035   {
00036       // Zero the elements in the column
00037     for (unsigned i=0;i<ni;++i)
00038     {
00039       *gi_data = 0;
00040       *gj_data = 0;
00041       gi_data += gi_istep;
00042       gj_data += gj_istep;
00043     }
00044     return;
00045   }
00046 
00047   // Compute relative grid positions
00048   //     o2
00049   //  o4    o5
00050   //     o7
00051   const vcl_ptrdiff_t o2 = s_jstep;
00052   const vcl_ptrdiff_t o4 = -s_istep;
00053   const vcl_ptrdiff_t o5 = s_istep;
00054   const vcl_ptrdiff_t o7 = -s_jstep;
00055 
00056   const unsigned ni1 = ni-1;
00057   const unsigned nj1 = nj-1;
00058 
00059   s_data += s_istep + s_jstep;
00060   gi_data += gi_jstep;
00061   gj_data += gj_jstep;
00062 
00063   for (unsigned j=1;j<nj1;++j)
00064   {
00065     const unsigned char* s = s_data;
00066     float* pgi = gi_data;
00067     float* pgj = gj_data;
00068 
00069     // Zero the first elements in the rows
00070     *pgi = 0; pgi+=gi_istep;
00071     *pgj = 0; pgj+=gj_istep;
00072 
00073     for (unsigned i=1;i<ni1;++i)
00074     {
00075       // Compute gradient in i
00076       // Note: Multiply each element individually
00077       //      to ensure conversion to float before addition
00078       *pgi = 0.5f*s[o5] - 0.5f*s[o4];
00079       // Compute gradient in j
00080       *pgj = 0.5f*s[o2] - 0.5f*s[o7];
00081 
00082       s+=s_istep;
00083       pgi += gi_istep;
00084       pgj += gj_istep;
00085     }
00086 
00087     // Zero the last elements in the rows
00088     *pgi = 0;
00089     *pgj = 0;
00090 
00091     // Move to next row
00092     s_data  += s_jstep;
00093     gi_data += gi_jstep;
00094     gj_data += gj_jstep;
00095   }
00096 
00097   // Zero the first and last rows
00098   for (unsigned i=0;i<ni;++i)
00099   {
00100     *gi=0; gi+=gi_istep;
00101     *gj=0; gj+=gj_istep;
00102     *gi_data = 0; gi_data+=gi_istep;
00103     *gj_data = 0; gj_data+=gj_istep;
00104   }
00105 }
00106 
00107 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
00108 //  Computes both i and j gradients of an ni x nj plane of data
00109 VCL_DEFINE_SPECIALIZATION
00110 void vil_sobel_1x3_1plane(const unsigned char* src,
00111                           vcl_ptrdiff_t s_istep, vcl_ptrdiff_t s_jstep,
00112                           double* gi, vcl_ptrdiff_t gi_istep, vcl_ptrdiff_t gi_jstep,
00113                           double* gj, vcl_ptrdiff_t gj_istep, vcl_ptrdiff_t gj_jstep,
00114                           unsigned ni, unsigned nj)
00115 {
00116   const unsigned char* s_data = src;
00117   double *gi_data = gi;
00118   double *gj_data = gj;
00119 
00120   if (ni==0 || nj==0) return;
00121   if (ni==1)
00122   {
00123       // Zero the elements in the column
00124     for (unsigned j=0;j<nj;++j)
00125     {
00126       *gi_data = 0;
00127       *gj_data = 0;
00128       gi_data += gi_jstep;
00129       gj_data += gj_jstep;
00130     }
00131     return;
00132   }
00133   if (nj==1)
00134   {
00135       // Zero the elements in the column
00136     for (unsigned i=0;i<ni;++i)
00137     {
00138       *gi_data = 0;
00139       *gj_data = 0;
00140       gi_data += gi_istep;
00141       gj_data += gj_istep;
00142     }
00143     return;
00144   }
00145 
00146   // Compute relative grid positions
00147   //     o2
00148   //  o4    o5
00149   //     o7
00150   const vcl_ptrdiff_t o2 = s_jstep;
00151   const vcl_ptrdiff_t o4 = -s_istep;
00152   const vcl_ptrdiff_t o5 = s_istep;
00153   const vcl_ptrdiff_t o7 = -s_jstep;
00154 
00155   const unsigned ni1 = ni-1;
00156   const unsigned nj1 = nj-1;
00157 
00158   s_data += s_istep + s_jstep;
00159   gi_data += gi_jstep;
00160   gj_data += gj_jstep;
00161 
00162   for (unsigned j=1;j<nj1;++j)
00163   {
00164     const unsigned char* s = s_data;
00165     double* pgi = gi_data;
00166     double* pgj = gj_data;
00167 
00168     // Zero the first elements in the rows
00169     *pgi = 0; pgi+=gi_istep;
00170     *pgj = 0; pgj+=gj_istep;
00171 
00172     for (unsigned i=1;i<ni1;++i)
00173     {
00174       // Compute gradient in i
00175       // Note: Multiply each element individually
00176       //      to ensure conversion to double before addition
00177       *pgi = 0.5*s[o5] - 0.5*s[o4];
00178       // Compute gradient in j
00179       *pgj = 0.5*s[o2] - 0.5*s[o7];
00180 
00181       s+=s_istep;
00182       pgi += gi_istep;
00183       pgj += gj_istep;
00184     }
00185 
00186     // Zero the last elements in the rows
00187     *pgi = 0;
00188     *pgj = 0;
00189 
00190     // Move to next row
00191     s_data  += s_jstep;
00192     gi_data += gi_jstep;
00193     gj_data += gj_jstep;
00194   }
00195 
00196   // Zero the first and last rows
00197   for (unsigned i=0;i<ni;++i)
00198   {
00199     *gi=0; gi+=gi_istep;
00200     *gj=0; gj+=gj_istep;
00201     *gi_data = 0; gi_data+=gi_istep;
00202     *gj_data = 0; gj_data+=gj_istep;
00203   }
00204 }
00205 
00206 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
00207 //  Computes both x and j gradients of an nx x nj plane of data
00208 VCL_DEFINE_SPECIALIZATION
00209 void vil_sobel_1x3_1plane(const float* src,
00210                           vcl_ptrdiff_t s_istep, vcl_ptrdiff_t s_jstep,
00211                           float* gi, vcl_ptrdiff_t gi_istep, vcl_ptrdiff_t gi_jstep,
00212                           float* gj, vcl_ptrdiff_t gj_istep, vcl_ptrdiff_t gj_jstep,
00213                           unsigned ni, unsigned nj)
00214 {
00215   const float* s_data = src;
00216   float *gi_data = gi;
00217   float *gj_data = gj;
00218 
00219   if (ni==0 || nj==0) return;
00220   if (ni==1)
00221   {
00222       // Zero the elements in the column
00223     for (unsigned j=0;j<nj;++j)
00224     {
00225       *gi_data = 0;
00226       *gj_data = 0;
00227       gi_data += gi_jstep;
00228       gj_data += gj_jstep;
00229     }
00230     return;
00231   }
00232   if (nj==1)
00233   {
00234       // Zero the elements in the column
00235     for (unsigned i=0;i<ni;++i)
00236     {
00237       *gi_data = 0;
00238       *gj_data = 0;
00239       gi_data += gi_istep;
00240       gj_data += gj_istep;
00241     }
00242     return;
00243   }
00244 
00245   // Compute relative grid positions
00246   //     o2
00247   //  o4    o5
00248   //     o7
00249   const vcl_ptrdiff_t o2 = s_jstep;
00250   const vcl_ptrdiff_t o4 = -s_istep;
00251   const vcl_ptrdiff_t o5 = s_istep;
00252   const vcl_ptrdiff_t o7 = -s_jstep;
00253 
00254   const unsigned ni1 = ni-1;
00255   const unsigned nj1 = nj-1;
00256 
00257   s_data += s_istep + s_jstep;
00258   gi_data += gi_jstep;
00259   gj_data += gj_jstep;
00260 
00261   for (unsigned j=1;j<nj1;++j)
00262   {
00263     const float* s = s_data;
00264     float* pgi = gi_data;
00265     float* pgj = gj_data;
00266 
00267     // Zero the first elements in the rows
00268     *pgi = 0; pgi+=gi_istep;
00269     *pgj = 0; pgj+=gj_istep;
00270 
00271     for (unsigned i=1;i<ni1;++i)
00272     {
00273     // Compute gradient in i
00274       *pgi = 0.5f*(s[o5]-s[o4]);
00275     // Compute gradient in j
00276       *pgj = 0.5f*(s[o2]-s[o7]);
00277 
00278       s+=s_istep;
00279       pgi += gi_istep;
00280       pgj += gj_istep;
00281     }
00282 
00283     // Zero the last elements in the rows
00284     *pgi = 0;
00285     *pgj = 0;
00286 
00287     // Move to next row
00288     s_data  += s_jstep;
00289     gi_data += gi_jstep;
00290     gj_data += gj_jstep;
00291   }
00292 
00293   // Zero the first and last rows
00294   for (unsigned i=0;i<ni;++i)
00295   {
00296     *gi=0; gi+=gi_istep;
00297     *gj=0; gj+=gj_istep;
00298     *gi_data = 0; gi_data+=gi_istep;
00299     *gj_data = 0; gj_data+=gj_istep;
00300   }
00301 }
00302 
00303 //: Compute gradients of single plane of 2D data using 1x3 Sobel filters
00304 //  Computes both x and j gradients of an nx x nj plane of data
00305 VCL_DEFINE_SPECIALIZATION
00306 void vil_sobel_1x3_1plane(const double* src,
00307                           vcl_ptrdiff_t s_istep, vcl_ptrdiff_t s_jstep,
00308                           double* gi, vcl_ptrdiff_t gi_istep, vcl_ptrdiff_t gi_jstep,
00309                           double* gj, vcl_ptrdiff_t gj_istep, vcl_ptrdiff_t gj_jstep,
00310                           unsigned ni, unsigned nj)
00311 {
00312   const double* s_data = src;
00313   double *gi_data = gi;
00314   double *gj_data = gj;
00315 
00316   if (ni==0 || nj==0) return;
00317   if (ni==1)
00318   {
00319       // Zero the elements in the column
00320     for (unsigned j=0;j<nj;++j)
00321     {
00322       *gi_data = 0;
00323       *gj_data = 0;
00324       gi_data += gi_jstep;
00325       gj_data += gj_jstep;
00326     }
00327     return;
00328   }
00329   if (nj==1)
00330   {
00331       // Zero the elements in the column
00332     for (unsigned i=0;i<ni;++i)
00333     {
00334       *gi_data = 0;
00335       *gj_data = 0;
00336       gi_data += gi_istep;
00337       gj_data += gj_istep;
00338     }
00339     return;
00340   }
00341 
00342   // Compute relative grid positions
00343   //     o2
00344   //  o4    o5
00345   //     o7
00346   const vcl_ptrdiff_t o2 = s_jstep;
00347   const vcl_ptrdiff_t o4 = -s_istep;
00348   const vcl_ptrdiff_t o5 = s_istep;
00349   const vcl_ptrdiff_t o7 = -s_jstep;
00350 
00351   const unsigned ni1 = ni-1;
00352   const unsigned nj1 = nj-1;
00353 
00354   s_data += s_istep + s_jstep;
00355   gi_data += gi_jstep;
00356   gj_data += gj_jstep;
00357 
00358   for (unsigned j=1;j<nj1;++j)
00359   {
00360     const double* s = s_data;
00361     double* pgi = gi_data;
00362     double* pgj = gj_data;
00363 
00364     // Zero the first elements in the rows
00365     *pgi = 0; pgi+=gi_istep;
00366     *pgj = 0; pgj+=gj_istep;
00367 
00368     for (unsigned i=1;i<ni1;++i)
00369     {
00370     // Compute gradient in i
00371       *pgi = 0.5*(s[o5]-s[o4]);
00372     // Compute gradient in j
00373       *pgj = 0.5*(s[o2]-s[o7]);
00374 
00375       s+=s_istep;
00376       pgi += gi_istep;
00377       pgj += gj_istep;
00378     }
00379 
00380     // Zero the last elements in the rows
00381     *pgi = 0;
00382     *pgj = 0;
00383 
00384     // Move to next row
00385     s_data  += s_jstep;
00386     gi_data += gi_jstep;
00387     gj_data += gj_jstep;
00388   }
00389 
00390   // Zero the first and last rows
00391   for (unsigned i=0;i<ni;++i)
00392   {
00393     *gi=0; gi+=gi_istep;
00394     *gj=0; gj+=gj_istep;
00395     *gi_data = 0; gi_data+=gi_istep;
00396     *gj_data = 0; gj_data+=gj_istep;
00397   }
00398 }
00399