1 // This is brl/bseg/brec/brec_part_base.h
2 #ifndef brec_part_base_h_
3 #define brec_part_base_h_
4 //:
5 // \file
6 // \brief base class for composable parts
7 //
8 // \author Ozge C Ozcanli (ozge@lems.brown.edu)
9 // \date Oct 16, 2008
10 //
11 // \verbatim
12 //  Modifications
13 //   <none yet>
14 // \endverbatim
15 
16 #include "brec_part_base_sptr.h"
17 #include "brec_hierarchy_edge_sptr.h"
18 class brec_part_gaussian;
19 
20 #include <bgrl2/bgrl2_vertex.h>
21 #include <bsta/bsta_histogram.h>
22 #include <bxml/bxml_document.h>
23 
24 #include <vnl/vnl_vector_fixed.h>
25 #include <vil/vil_image_view.h>
26 #include <vgl/vgl_box_2d.h>
27 
28 class brec_part_base : public bgrl2_vertex<brec_hierarchy_edge>
29 {
30  public:
31 
brec_part_base(unsigned layer,unsigned type)32   brec_part_base(unsigned layer, unsigned type) : bgrl2_vertex<brec_hierarchy_edge>(), layer_(layer), type_(type), activation_radius_(0.0f), detection_threshold_(0.01f) {}
33 
34   //: this constructor should only be used during parsing
brec_part_base()35   brec_part_base() : layer_(0), type_(0), prior_prob_(0) {}
36 
37   //: we assume that the part that is added first as the outgoing part is the central part
38   brec_part_base_sptr central_part();
39 
40   //: we assume that the part that is added first as the outgoing part is the central part
41   brec_hierarchy_edge_sptr edge_to_central_part();
42   brec_hierarchy_edge_sptr edge_to_second_part();
43 
44   virtual bool mark_receptive_field(vil_image_view<vxl_byte>& img, unsigned plane);
45   virtual bool mark_center(vil_image_view<vxl_byte>& img, unsigned plane);
46 
47   virtual brec_part_gaussian* cast_to_gaussian(void);
48   virtual brec_part_instance* cast_to_instance(void);
49   virtual brec_part_base* cast_to_base(void);
50 
51   virtual bxml_data_sptr xml_element();
52   virtual bool xml_parse_element(bxml_data_sptr data);
53 
54   unsigned layer_;
55   unsigned type_;
56 
57   float activation_radius_;
58   float detection_threshold_;
59 
60   double prior_prob_;  // prior probability of the composition
61   double log_likelihood_; // only used during training to pick the best parts
62 };
63 
64 class brec_part_instance_kind
65 {
66  public:
67   enum possible_kinds {
68     GAUSSIAN,   // only GAUSSIAN is implemented for now in brec_part_gaussian
69     EDGE,
70     COMPOSED,   // the instance could be a composition if not primitive
71   };
72 };
73 
74 class brec_posterior_types
75 {
76  public:
77   enum types {
78     CLASS_FOREGROUND,
79     CLASS_BACKGROUND,
80     NON_CLASS_FOREGROUND,
81     NON_CLASS_BACKGROUND,
82   };
83 };
84 
85 class brec_part_instance : public brec_part_base
86 {
87  public:
88 
brec_part_instance(unsigned layer,unsigned type,unsigned kind,float x,float y,float strength)89   brec_part_instance(unsigned layer, unsigned type, unsigned kind, float x, float y, float strength) : brec_part_base(layer, type),
90     x_(x), y_(y), strength_(strength), kind_(kind), rho_c_f_(0.0), rho_c_b_(0.0), rho_nc_f_(0.0), rho_nc_b_(0.0), cnt_(0) {}
91 
92   //: this constructor should only be used during parsing
brec_part_instance()93   brec_part_instance() : brec_part_base(0, 0), x_(0), y_(0), strength_(0), kind_(0) {}
94 
95   brec_part_gaussian* cast_to_gaussian(void) override;
96   brec_part_instance* cast_to_instance(void) override;
97 
98   bool mark_receptive_field(vil_image_view<vxl_byte>& img, unsigned plane) override;
99   bool mark_center(vil_image_view<vxl_byte>& img, unsigned plane) override;
100   virtual bool mark_receptive_field(vil_image_view<float>& img, float val);
101   virtual bool mark_center(vil_image_view<float>& img, float val);
102 
103   virtual vnl_vector_fixed<float,2> direction_vector(void);  // return a unit vector that gives direction of this instance in the image
104 
105   //: collect operator responses from the input image's foreground regions
106   //  The input \p img and the \p fg_prob_img (foreground probability image) are float images with values in [0,1] range
107   //  assumes histogram is initialized
108   //  virtual method needs to be implemented by inheriting classes depending on the nature of the part
update_response_hist(vil_image_view<float> &,vil_image_view<float> &,vil_image_view<bool> &,bsta_histogram<float> &)109   virtual bool update_response_hist(vil_image_view<float>& /*img*/, vil_image_view<float>& /*fg_prob_img*/, vil_image_view<bool>& /*mask_img*/, bsta_histogram<float>& /*fg_h*/) { return false; }
fit_distribution_to_response_hist(bsta_histogram<float> &)110   virtual bool fit_distribution_to_response_hist(bsta_histogram<float>& /*fg_h*/) { return false; }
111 
112   //: use the background \p mean_img and \p std_dev_img to construct response model for background and calculate posterior ratio of foreground and background
update_foreground_posterior(vil_image_view<float> &,vil_image_view<float> &,vil_image_view<bool> &,vil_image_view<float> &,vil_image_view<float> &)113   virtual bool update_foreground_posterior(vil_image_view<float>& /*inp*/,
114                                            vil_image_view<float>& /*fg_prob_img*/,
115                                            vil_image_view<bool>& /*mask*/,
116                                            vil_image_view<float>& /*mean_img*/,
117                                            vil_image_view<float>& /*std_dev_img*/) { return false; }
118 
119   bxml_data_sptr xml_element() override;
120   bool xml_parse_element(bxml_data_sptr data) override;
121 
122   //: return a simple box with diagonal 2*radius centered on this instance
123   vgl_box_2d<float> get_probe_box(float radius);
location()124   vnl_vector_fixed<float,2> location() const { return vnl_vector_fixed<float,2>(x_, y_); }
125 
126   float x_, y_;  // location
127   float strength_;
128   unsigned kind_;   // one of brec_part_instance_kind enum types
129   //double rho_;  // the posterior probability of observing this instance
130                // if the part is a primitive part, this is given by:
131                // rho(alpha) = [p(alpha in foreground)p(strength|alpha in foreground)] / [p(alpha in background)p(strength|alpha in background)]
132                //
133                // each instance should have a foreground probability p(alpha in foreground) (for some operators, this may be calculated from a kernel region, e.g. for gaussian operators)
134                // p(alpha in background) = 1 - p(alpha in foreground) by convention
135 
136   //: there are 4 possibilities regarding existence of a part: class instance in the foreground, class instance in the background, non-class instance in the foreground, non-class instance in the background
137   double rho_c_f_;  //posterior of class, fore
138   double rho_c_b_;  // posterior of class, back
139   double rho_nc_f_;  // posterior of non-class, fore
140   double rho_nc_b_;  // posterior of non-class, back
141 
142   int cnt_; // a variable used to update expected rho_ as new data comes in
143 };
144 
145 #endif  //brec_part_base_h_
146