contrib/mul/vil3d/algo/vil3d_corners.txx
Go to the documentation of this file.
00001 // This is mul/vil3d/algo/vil3d_corners.txx
00002 #ifndef vil3d_corners_txx_
00003 #define vil3d_corners_txx_
00004 //:
00005 // \file
00006 // \brief  Class containing functions to estimate corner-ness in various ways.
00007 // \author Tim Cootes
00008 
00009 #include "vil3d_corners.h"
00010 
00011 #include <vil3d/vil3d_math.h>
00012 #include <vil3d/vil3d_plane.h>
00013 #include <vil3d/algo/vil3d_grad_3x3x3.h>
00014 #include <vil3d/algo/vil3d_smooth_121.h>
00015 #include <vcl_cassert.h>
00016 
00017 //: Compute gradients, products and smoothed versions
00018 template <class srcT, class destT>
00019 void vil3d_corners<srcT,destT>::compute_smooth_gradient_products(const vil3d_image_view<srcT>& src_im)
00020 {
00021   // Compute the gradients
00022   vil3d_grad_3x3x3(src_im,grad_i,grad_j,grad_k);
00023 
00024   unsigned ni=src_im.ni();
00025   unsigned nj=src_im.nj();
00026   unsigned nk=src_im.nk();
00027 
00028   // Set up grad_product_ and smooth_grad_product_ to be 6 plane
00029   // images, with the plane being the fastest varying (planestep=1)
00030   vil_pixel_format fmt = vil_pixel_format_of(destT());
00031   vil_memory_chunk_sptr chunk1 = new vil_memory_chunk(ni*nj*nk*6*sizeof(destT),
00032                                     vil_pixel_format_component_format(fmt));
00033   grad_product_ = vil3d_image_view<destT>(chunk1,
00034                                           reinterpret_cast<destT *>(chunk1->data()),
00035                                           ni, nj, nk, 6,
00036                                           6, 6*ni, 6*ni*nj, 1);
00037   vil_memory_chunk_sptr chunk2 = new vil_memory_chunk(ni*nj*nk*6*sizeof(destT),
00038                                     vil_pixel_format_component_format(fmt));
00039   smooth_grad_product_ = vil3d_image_view<destT>(chunk2,
00040                                           reinterpret_cast<destT *>(chunk2->data()),
00041                                           ni, nj, nk, 6,
00042                                           6, 6*ni, 6*ni*nj, 1);
00043 
00044   // Fill planes of grad_product_ with products of gradients
00045   vil3d_image_view<destT> gigi = vil3d_plane(grad_product_,0);
00046   vil3d_math_image_product(grad_i,grad_i,gigi);
00047   vil3d_image_view<destT> gigj = vil3d_plane(grad_product_,1);
00048   vil3d_math_image_product(grad_i,grad_j,gigj);
00049   vil3d_image_view<destT> gigk = vil3d_plane(grad_product_,2);
00050   vil3d_math_image_product(grad_i,grad_k,gigk);
00051   vil3d_image_view<destT> gjgj = vil3d_plane(grad_product_,3);
00052   vil3d_math_image_product(grad_j,grad_j,gjgj);
00053   vil3d_image_view<destT> gjgk = vil3d_plane(grad_product_,4);
00054   vil3d_math_image_product(grad_j,grad_k,gjgk);
00055   vil3d_image_view<destT> gkgk = vil3d_plane(grad_product_,5);
00056   vil3d_math_image_product(grad_k,grad_k,gkgk);
00057 
00058   // Smooth the products
00059   vil3d_smooth_121(grad_product_,smooth_grad_product_);
00060 }
00061 
00062 //: Computes cornerness measure for every pixel
00063 //  At each pixel, computes det(N)/trace(N), where
00064 //  N is a matrix generated by smoothing over gradient
00065 //  product matrices M = (gi, gj, gk)' * (gi, gj, gk),
00066 //  where gi = i-gradient at a pixel etc.
00067 //
00068 //  This is the Op3 corner operator described by Rohr.
00069 template <class srcT, class destT>
00070 void vil3d_corners<srcT,destT>::cornerness1(
00071                    const vil3d_image_view<srcT>& src_im,
00072                    vil3d_image_view<destT>& cornerness)
00073 {
00074   assert(src_im.nplanes()==1);
00075   compute_smooth_gradient_products(src_im);
00076 
00077   unsigned ni=src_im.ni();
00078   unsigned nj=src_im.nj();
00079   unsigned nk=src_im.nk();
00080 
00081   // Compute the cornerness value
00082   cornerness.set_size(ni,nj,nk);
00083 
00084   vcl_ptrdiff_t c_istep=cornerness.istep();
00085   vcl_ptrdiff_t c_jstep=cornerness.jstep();
00086   vcl_ptrdiff_t c_kstep=cornerness.kstep();
00087   vcl_ptrdiff_t s_istep=smooth_grad_product_.istep();
00088   vcl_ptrdiff_t s_jstep=smooth_grad_product_.jstep();
00089   vcl_ptrdiff_t s_kstep=smooth_grad_product_.kstep();
00090 
00091   destT* c_data = cornerness.origin_ptr();
00092   destT* s_data = smooth_grad_product_.origin_ptr();
00093   for (unsigned k=0;k<nk;++k,c_data+=c_kstep,s_data+=s_kstep)
00094   {
00095     destT* c_row = c_data;
00096     destT* s_row = s_data;
00097     for (unsigned j=0;j<nj;++j,c_row+=c_jstep,s_row+=s_jstep)
00098     {
00099       destT* c_p=c_row;
00100       destT* s_p=s_row;
00101       for (unsigned i=0;i<ni;++i,c_p+=c_istep,s_p+=s_istep)
00102       {
00103         // detN = det(N) where
00104         // N = (s_p[0] s_p[1] s_p[2])
00105         //     (s_p[1] s_p[3] s_p[4])
00106         //     (s_p[2] s_p[4] s_p[5])
00107         destT detN =   s_p[0]*(s_p[3]*s_p[5]-s_p[4]*s_p[4])
00108                      - s_p[1]*(s_p[1]*s_p[5]-s_p[2]*s_p[4])
00109                      + s_p[2]*(s_p[1]*s_p[3]-s_p[2]*s_p[3]);
00110         destT trN  = s_p[0]+s_p[3]+s_p[5];
00111         if (trN<1e-4) *c_p=0;
00112         else          *c_p=detN/trN;
00113       }
00114     }
00115   }
00116 }
00117 
00118 #define VIL3D_CORNERS_INSTANTIATE(srcT, destT) \
00119 template class vil3d_corners<srcT, destT >
00120 
00121 #endif // vil3d_corners_txx_