contrib/brl/bseg/bbgm/bbgm_view_maker.h
Go to the documentation of this file.
00001 // This is brl/bseg/bbgm/bbgm_view_maker.h
00002 #ifndef bbgm_mean_viewer_h_
00003 #define bbgm_mean_viewer_h_
00004 //:
00005 // \file
00006 // \brief Helper classes to make a vil_image_view from an image of distributions
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date Mar 15, 2009
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   <none yet>
00013 // \endverbatim
00014 
00015 #include <vil/vil_image_view.h>
00016 #include <vbl/vbl_ref_count.h>
00017 #include <bbgm/bbgm_viewer.h>
00018 #include <bbgm/bbgm_apply.h>
00019 #include <vpdl/vpdt/vpdt_mixture_accessors.h>
00020 #include <vpdl/vpdt/vpdt_enable_if.h>
00021 #include <vil/vil_math.h>
00022 #include <vcl_cassert.h>
00023 
00024 //: base class for objects that extract the mean from an image of distribution
00025 class bbgm_view_maker_base : public vbl_ref_count
00026 {
00027  public:
00028   //: return the type_info for the distribution type
00029   virtual const vcl_type_info& dist_typeid() const=0;
00030 
00031   //: Return the maximum number of components if a mixture
00032   // If not a mixture return 1
00033   virtual unsigned int max_components(const bbgm_image_sptr& dimg) const=0;
00034 
00035   //: Compute the mean of the distribution image to produce a vil image
00036   // \param component_idx indicated the component index to operate on.
00037   //        If < 0 or not a mixture then operate on the whole distribution
00038   virtual bool apply(const bbgm_image_sptr& dimg,
00039                      vil_image_view<double>& image,
00040                      const double* fail_val,
00041                      int component_idx = -1) const=0;
00042 };
00043 
00044 
00045 //: base class for objects that extract the mean from an image of distribution
00046 template <class dist_type, class func_type, class Disambiguate= void>
00047 class bbgm_view_maker
00048   : public bbgm_view_maker_base
00049 {
00050   //: return the type_info for the distribution type
00051   virtual const vcl_type_info& dist_typeid() const
00052   { return typeid(dist_type); }
00053 
00054   //: Return the maximum number of components if a mixture
00055   // If not a mixture return 1
00056   virtual unsigned int max_components(const bbgm_image_sptr& dimg) const
00057   { return 1; }
00058 
00059   //: Compute the mean of the distribution image to produce a vil image
00060   // \param component_idx indicated the component index to operate on.
00061   //        If < 0 or not a mixture then operate on the whole distribution
00062   virtual bool apply(const bbgm_image_sptr& dimg,
00063                      vil_image_view<double>& image,
00064                      const double* fail_val,
00065                      int component_idx = -1) const
00066   {
00067     typedef typename dist_type::component_type d_test;
00068     typedef bbgm_image_of<dist_type> dist_image;
00069     const dist_image* d = dynamic_cast<const dist_image*>(dimg.ptr());
00070     if (!d)
00071       return false;
00072 
00073     func_type func;
00074     bbgm_apply(*d, func, image, fail_val);
00075     return true;
00076   }
00077 };
00078 
00079 
00080 //: helper class to determine the maximum number of components in an image of mixtures
00081 template <class dist_type, class = void>
00082 struct bbgm_num_components
00083 {
00084   static unsigned int max(const bbgm_image_of<dist_type>& dist_image)
00085   {
00086     vpdt_num_components_accessor<dist_type> func;
00087     vil_image_view<unsigned int> count;
00088     unsigned int fail_val = 0;
00089     bbgm_apply(dist_image, func, count, &fail_val);
00090     unsigned int min_val, max_val;
00091     vil_math_value_range(count, min_val, max_val);
00092     return max_val;
00093   }
00094 };
00095 
00096 //: helper class to determine the maximum number of components in an image of mixtures
00097 // For fixed sized mixtures \return the fixed maximum number of components
00098 template <class dist_type>
00099 struct bbgm_num_components<dist_type, typename dist_type::max_components>
00100 {
00101   static unsigned int max(const bbgm_image_of<dist_type>& dist_image)
00102   {
00103     return dist_type::max_components;
00104   }
00105 };
00106 
00107 
00108 //: base class for objects that extract the mean from an image of distribution
00109 // Specialization for mixtures
00110 template <class dist_type, class func_type>
00111 class bbgm_view_maker<dist_type, func_type,
00112                       typename vpdt_enable_if<vpdt_is_mixture<dist_type> >::type>
00113   : public bbgm_view_maker_base
00114 {
00115   //: Return the type_info for the distribution type
00116   virtual const vcl_type_info& dist_typeid() const
00117   { return typeid(dist_type); }
00118 
00119   //: Return the maximum number of components if a mixture
00120   // If not a mixture return 1
00121   virtual unsigned int max_components(const bbgm_image_sptr& dimg) const
00122   {
00123     typedef bbgm_image_of<dist_type> dist_image;
00124     const dist_image* d = dynamic_cast<const dist_image*>(dimg.ptr());
00125     assert(d);
00126     return bbgm_num_components<dist_type>::max(*d);
00127   }
00128 
00129   //: Compute the mean of the distribution image to produce a vil image
00130   // \param component_idx indicated the component index to operate on.
00131   //        If < 0 or not a mixture then operate on the whole distribution
00132   virtual bool apply(const bbgm_image_sptr& dimg,
00133                      vil_image_view<double>& image,
00134                      const double* fail_val,
00135                      int component_idx = -1) const
00136   {
00137     typedef bbgm_image_of<dist_type> dist_image;
00138     typedef typename dist_type::component_type comp_type;
00139     const dist_image* d = dynamic_cast<const dist_image*>(dimg.ptr());
00140     if (!d)
00141       return false;
00142 
00143     typedef typename func_type::template rebind<comp_type>::other func_comp;
00144     typedef vpdt_mixture_accessor<dist_type, func_comp> func_mix;
00145     if (component_idx < 0 || (func_type::valid_functor && !func_mix::valid_functor))
00146     {
00147       func_type func;
00148       bbgm_apply(*d, func, image, fail_val);
00149       return true;
00150     }
00151     else if (func_mix::valid_functor)
00152     {
00153       func_mix func(component_idx);
00154       bbgm_apply(*d, func, image, fail_val);
00155       return true;
00156     }
00157     return false;
00158   }
00159 };
00160 
00161 
00162 #endif // bbgm_mean_viewer_h_