contrib/brl/bseg/bbgm/bbgm_apply.h
Go to the documentation of this file.
00001 // This is brl/bseg/bbgm/bbgm_apply.h
00002 #ifndef bbgm_apply_h_
00003 #define bbgm_apply_h_
00004 //:
00005 // \file
00006 // \brief Apply functors to distribution images
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date October 3, 2005
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   Apr 21, 2009  MJL  Update to work with vpdt
00013 // \endverbatim
00014 
00015 #include <vcl_cassert.h>
00016 #include <vil/vil_image_view.h>
00017 
00018 #include "bbgm_image_of.h"
00019 #include "bbgm_planes_to_sample.h"
00020 #include <vpdl/vpdt/vpdt_field_traits.h>
00021 
00022 //: Apply the functor at every pixel
00023 //  \returns an image of results, each vector component in a separate plane
00024 //  \param fail_val sets the value of pixels where the functor fails
00025 template <class dist_, class functor_, class T, bool single_ = false>
00026 struct bbgm_apply_no_data
00027 {
00028   static inline void apply(const bbgm_image_of<dist_>& dimg,
00029                            const functor_& functor,
00030                            vil_image_view<T>& result,
00031                            const T* fail_val = 0 )
00032   {
00033     typedef typename functor_::return_type return_T;
00034 
00035     const unsigned ni = dimg.ni();
00036     const unsigned nj = dimg.nj();
00037     const unsigned np = vpdt_field_traits<return_T>::dimension;
00038 
00039     if (ni==0 && nj==0)
00040       return;
00041 
00042     result.set_size(ni,nj,np);
00043 
00044     const vcl_ptrdiff_t planestep = result.planestep();
00045     const vcl_ptrdiff_t istep = result.istep();
00046     const vcl_ptrdiff_t jstep = result.jstep();
00047 
00048     return_T temp_val;
00049     typename bbgm_image_of<dist_>::const_iterator itr = dimg.begin();
00050     T* row = result.top_left_ptr();
00051     for (unsigned int j=0; j<nj; ++j, row+=jstep) {
00052       T* col = row;
00053       for (unsigned int i=0; i<ni; ++i, col+=istep, ++itr) {
00054         T* data = col;
00055         if ( functor(*itr,temp_val) ) {
00056           typename return_T::iterator v_itr = temp_val.begin();
00057           for (unsigned int p=0; p<np; ++p, data += planestep, ++v_itr) {
00058             *data = *v_itr;
00059           }
00060         }
00061         else if (fail_val) {
00062           const T* v_itr = fail_val;
00063           for (unsigned int p=0; p<np; ++p, data += planestep, ++v_itr) {
00064             *data = *v_itr;
00065           }
00066         }
00067       }
00068     }
00069   }
00070 };
00071 
00072 
00073 template <class dist_, class functor_, class T>
00074 struct bbgm_apply_no_data<dist_,functor_,T,true>
00075 {
00076   static inline void apply(const bbgm_image_of<dist_>& dimg,
00077                            const functor_& functor,
00078                            vil_image_view<T>& result,
00079                            const T* fail_val = 0 )
00080   {
00081     typedef typename functor_::return_type return_T;
00082 
00083     const unsigned ni = dimg.ni();
00084     const unsigned nj = dimg.nj();
00085 
00086     if (ni==0 && nj==0)
00087       return;
00088 
00089     result.set_size(ni,nj,1);
00090     const vcl_ptrdiff_t istep = result.istep();
00091     const vcl_ptrdiff_t jstep = result.jstep();
00092 
00093     return_T temp_val = return_T(0); // dummy initialisation, to avoid compiler warning; return_T could be bool, though...
00094     typename bbgm_image_of<dist_>::const_iterator itr = dimg.begin();
00095     T* row = result.top_left_ptr();
00096     for (unsigned int j=0; j<nj; ++j, row+=jstep) {
00097       T* col = row;
00098       for (unsigned int i=0; i<ni; ++i, col+=istep, ++itr) {
00099         if (functor(*itr, temp_val))
00100           *col = static_cast<T>(temp_val);
00101         else if (fail_val)
00102           *col = fail_val[0];
00103       }
00104     }
00105   }
00106 };
00107 
00108 //: Apply without data
00109 template <class dist_, class functor_, class T>
00110 void bbgm_apply(const bbgm_image_of<dist_>& dimg,
00111                 const functor_& functor,
00112                 vil_image_view<T>& result,
00113                 const T* fail_val = 0 )
00114 {
00115   typedef vpdt_field_traits<typename functor_::return_type> return_traits;
00116   bbgm_apply_no_data<dist_,functor_,T,return_traits::dimension == 1>::
00117       apply(dimg,functor,result,fail_val);
00118 }
00119 
00120 
00121 //: Apply the functor at every pixel
00122 //  \returns an image of results, each vector component in a separate plane
00123 //  \param fail_val sets the value of pixels where the functor fails
00124 template <class dist_, class functor_, class dT, class rT, bool single_ = false>
00125 struct bbgm_apply_data
00126 {
00127   static inline void apply(const bbgm_image_of<dist_>& dimg,
00128                            const functor_& functor,
00129                            const vil_image_view<dT>& data,
00130                            vil_image_view<rT>& result,
00131                            const rT* fail_val = 0 )
00132   {
00133     typedef typename functor_::return_type return_T;
00134     typedef typename dist_::field_type F;
00135 
00136     const unsigned ni = dimg.ni();
00137     const unsigned nj = dimg.nj();
00138     const unsigned d_np = vpdt_field_traits<F>::dimension;
00139     const unsigned r_np = vpdt_field_traits<return_T>::dimension;
00140     assert(data.ni() == ni);
00141     assert(data.nj() == nj);
00142     assert(data.nplanes() == d_np);
00143 
00144     result.set_size(ni,nj,r_np);
00145     const vcl_ptrdiff_t r_istep = result.istep();
00146     const vcl_ptrdiff_t r_jstep = result.jstep();
00147     const vcl_ptrdiff_t r_pstep = result.planestep();
00148     const vcl_ptrdiff_t d_istep = data.istep();
00149     const vcl_ptrdiff_t d_jstep = data.jstep();
00150     const vcl_ptrdiff_t d_pstep = data.planestep();
00151 
00152     return_T temp_val;
00153     F sample;
00154     typename bbgm_image_of<dist_>::const_iterator itr = dimg.begin();
00155     rT* r_row = result.top_left_ptr();
00156     const dT* d_row = data.top_left_ptr();
00157     for (unsigned int j=0; j<nj; ++j, d_row+=d_jstep, r_row+=r_jstep) {
00158       rT* r_col = r_row;
00159       const dT* d_col = d_row;
00160       for (unsigned int i=0; i<ni; ++i, d_col+=d_istep, r_col+=r_istep, ++itr) {
00161         rT* r_plane = r_col;
00162         const dT* d_plane = d_col;
00163         for (unsigned int k=0; k<d_np; ++k, d_plane+=d_pstep)
00164           sample[k] = *d_plane;
00165         if (functor(*itr, sample, temp_val)) {
00166           for (unsigned int k=0; k<r_np; ++k, r_plane+=r_pstep)
00167             *r_plane = temp_val[k];
00168         }
00169         else if ( fail_val ) {
00170           for (unsigned int k=0; k<r_np; ++k, r_plane+=r_pstep)
00171             *r_plane = fail_val[k];
00172         }
00173       }
00174     }
00175   }
00176 };
00177 
00178 
00179 template <class dist_, class functor_, class dT, class rT>
00180 struct bbgm_apply_data<dist_,functor_,dT,rT,true>
00181 {
00182   static inline void apply(const bbgm_image_of<dist_>& dimg,
00183                            const functor_& functor,
00184                            const vil_image_view<dT>& data,
00185                            vil_image_view<rT>& result,
00186                            const rT* fail_val = 0 )
00187   {
00188     typedef typename functor_::return_type return_T;
00189     typedef typename dist_::field_type F;
00190     const unsigned int data_dim = vpdt_field_traits<F>::dimension;
00191 
00192     const unsigned ni = dimg.ni();
00193     const unsigned nj = dimg.nj();
00194     const unsigned d_np = data_dim;
00195     assert(data.ni() == ni);
00196     assert(data.nj() == nj);
00197     assert(data.nplanes() == d_np);
00198 
00199     result.set_size(ni,nj,1);
00200     const vcl_ptrdiff_t r_istep = result.istep();
00201     const vcl_ptrdiff_t r_jstep = result.jstep();
00202     const vcl_ptrdiff_t d_istep = data.istep();
00203     const vcl_ptrdiff_t d_jstep = data.jstep();
00204     const vcl_ptrdiff_t d_pstep = data.planestep();
00205 
00206     return_T temp_val;
00207     F sample;
00208     typename bbgm_image_of<dist_>::const_iterator itr = dimg.begin();
00209     rT* r_row = result.top_left_ptr();
00210     const dT* d_row = data.top_left_ptr();
00211     for (unsigned int j=0; j<nj; ++j, d_row+=d_jstep, r_row+=r_jstep) {
00212       rT* r_col = r_row;
00213       const dT* d_col = d_row;
00214       for (unsigned int i=0; i<ni; ++i, d_col+=d_istep, r_col+=r_istep, ++itr) {
00215         const dT* d_plane = d_col;
00216         bbgm_planes_to_sample<dT,F,vpdt_field_traits<F>::dimension>::apply(d_plane,sample,d_pstep);
00217         if (functor(*itr, sample, temp_val))
00218           *r_col = static_cast<rT>(temp_val);
00219         else if ( fail_val )
00220           *r_col = fail_val[0];
00221       }
00222     }
00223   }
00224 };
00225 
00226 
00227 //: Apply with data
00228 template <class dist_, class functor_, class dT, class rT>
00229 void bbgm_apply(const bbgm_image_of<dist_>& dimg,
00230                 const functor_& functor,
00231                 const vil_image_view<dT>& data,
00232                 vil_image_view<rT>& result,
00233                 const rT* fail_val = 0 )
00234 {
00235   typedef vpdt_field_traits<typename functor_::return_type> return_traits;
00236   bbgm_apply_data<dist_,functor_,dT,rT,return_traits::dimension == 1>::
00237       apply(dimg,functor,data,result,fail_val);
00238 }
00239 
00240 
00241 #endif // bbgm_apply_h_