contrib/mul/mipa/mipa_sample_histo_boxes.txx
Go to the documentation of this file.
00001 #ifndef mipa_sample_histo_boxes_txx_
00002 #define mipa_sample_histo_boxes_txx_
00003 //:
00004 // \file
00005 // \brief Functions to sample blocks of histograms
00006 // \author Tim Cootes
00007 
00008 #include "mipa_sample_histo_boxes.h"
00009 #include <vcl_cassert.h>
00010 
00011 //: Extract data from an image of histograms over nested boxes
00012 //  Assume h_im(i,j,A) gives frequency stored in angle bin A
00013 //  for (i,j)th histogram, organised so that h_im.planestep()=1
00014 //  This copies the individual histograms from a rectangular
00015 //  region of the image with corner (i0,j0).
00016 //
00017 //  It samples a grid of 2ni x 2nj histos,
00018 //  ie h_im([i0,i0+2ni),[j0,j0+2nj)).
00019 //
00020 //  The first 4*nA*ni*nj elements of v are copies of the
00021 //  histograms.  The next nA*ni*nj elements are a set of
00022 //  pooled histograms, adding the 4 histos in each 2 x 2 block.
00023 //  The final nA elements give a total histogram, adding
00024 //  all the histograms in the region together.
00025 template<class srcT, class vT>
00026 void mipa_sample_histo_boxes_3L(const vil_image_view<srcT>& h_im,
00027                                 unsigned i0, unsigned j0,
00028                                 vnl_vector<vT>& vec,
00029                                 unsigned ni, unsigned nj)
00030 {
00031   unsigned nA=h_im.nplanes();
00032   vec.set_size(nA*(5*ni*nj+1));
00033 
00034   assert(h_im.planestep()==1);
00035   assert(h_im.istep()==int(nA));
00036 
00037   // Set up some pointers and offsets so that we
00038   // can do everything in one pass.
00039   vT *v = vec.data_block();
00040   unsigned dv1=nA,dv2=2*ni*nA,dv3=dv1+dv2;
00041 
00042   vT *w = v + 4*nA*ni*nj;  // Start of data for 2x2 blocks
00043   vT *sum = w + nA*ni*nj;  // Start of data for total summation
00044 
00045   // Zero the total summation
00046   for (unsigned a=0;a<nA;++a) sum[a]=0;
00047 
00048   const srcT *h_row = &h_im(i0,j0);
00049   vcl_ptrdiff_t hj_step = 2*h_im.jstep();
00050   unsigned dh1=nA,dh2=nA*h_im.ni(),dh3=dh1+dh2;
00051 
00052   for (unsigned j=0;j<nj;++j,h_row+=hj_step,v+=dv2)
00053   {
00054     // Set pointers to start of each pair of rows
00055     const srcT *h = h_row;
00056 
00057     // Process i-th 2x2 block in the row
00058     // (The +=nA at end of each pass steps to next pair)
00059     for (unsigned i=0;i<ni;++i,v+=nA,h+=nA,w+=nA)
00060       for (unsigned a=0;a<nA;++a,++v,++h)
00061       {
00062         // Copy elements from 2 x 2 block into vector
00063         v[0]=h[0];     v[dv1]=h[dh1];
00064         v[dv2]=h[dh2]; v[dv3]=h[dh3];
00065 
00066         // Sum elements over 2 x 2 block
00067         w[a] = v[0]+v[dv1]+v[dv2]+v[dv3];
00068 
00069         // Add this to the total sum
00070         sum[a]+=w[a];
00071       }
00072   }
00073 }
00074 
00075 
00076 //---------------------- Perform inverse transform -------------------
00077 // Note this is mainly used in testing
00078 // Note only the first 4*nA*ni*nj elements of v are accessed
00079 
00080 template<class srcT, class vT>
00081 void mipa_sample_histo_boxes_3L_inv(vil_image_view<srcT>& h_im,
00082                                     unsigned i0, unsigned j0,
00083                                     const vnl_vector<vT>& vec,
00084                                     unsigned ni, unsigned nj)
00085 {
00086   unsigned nA=h_im.nplanes();
00087   //vec.set_size(nA*(5*ni*nj+1));
00088 
00089   assert(h_im.planestep()==1);
00090   assert(h_im.istep()==int(nA));
00091 
00092   // Set up some pointers and offsets so that we
00093   // can do everything in one pass.
00094   const vT *v = vec.data_block();
00095   unsigned dv1=nA,dv2=2*ni*nA,dv3=dv1+dv2;
00096 
00097   srcT *h_row = &h_im(i0,j0);
00098   vcl_ptrdiff_t hj_step = 2*h_im.jstep();
00099   unsigned dh1=nA,dh2=nA*h_im.ni(),dh3=dh1+dh2;
00100 
00101   for (unsigned j=0;j<nj;++j,h_row+=hj_step,v+=dv2)
00102   {
00103     // Set pointers to start of each pair of rows
00104     srcT *h = h_row;
00105 
00106     // Process i-th 2x2 block in the row
00107     // (The +=nA at end of each pass steps to next pair)
00108     for (unsigned i=0;i<ni;++i,v+=nA,h+=nA)
00109     {
00110       for (unsigned a=0;a<nA;++a,++v,++h)
00111       {
00112         // Copy elements from vector into 2 x 2 block
00113         h[0  ]=srcT(v[0]);   h[dh1]=srcT(v[dv1]);
00114         h[dh2]=srcT(v[dv2]); h[dh3]=srcT(v[dv3]);
00115       }
00116     }
00117   }
00118 }
00119 
00120 
00121 #undef MIPA_SAMPLE_HISTO_BOXES_INSTANTIATE
00122 #define MIPA_SAMPLE_HISTO_BOXES_INSTANTIATE(srcT, vT) \
00123 template void mipa_sample_histo_boxes_3L(const vil_image_view<srcT >& h_im, \
00124                                          unsigned i0, unsigned j0, \
00125                                          vnl_vector<vT >& vec, \
00126                                          unsigned ni, unsigned nj)
00127 
00128 #undef MIPA_SAMPLE_HISTO_BOXES_INV_INSTANTIATE
00129 #define MIPA_SAMPLE_HISTO_BOXES_INV_INSTANTIATE(srcT, vT) \
00130 template void mipa_sample_histo_boxes_3L_inv(vil_image_view<srcT >& h_im, \
00131                                              unsigned i0, unsigned j0, \
00132                                              const vnl_vector<vT >& vec, \
00133                                              unsigned ni, unsigned nj)
00134 
00135 #endif // mipa_sample_histo_boxes_txx_