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