1 //:
2 // \file
3 // \author Ozge C Ozcanli (ozge@lems.brown.edu)
4 // \date October 16, 2008
5 
6 #include "brec_part_base.h"
7 #include "brec_hierarchy_edge.h"
8 
9 #include <bxml/bxml_find.h>
10 #include "vgl/vgl_point_2d.h"
11 
12 //: we assume that the part that is added first as the outgoing part is the central part
13 brec_part_base_sptr
central_part()14 brec_part_base::central_part()
15 {
16   if (out_edges().size() == 0) return nullptr;
17   else return (*out_edges_begin())->target();
18 }
19 
20 //: we assume that the part that is added first as the outgoing part is the central part
21 brec_hierarchy_edge_sptr
edge_to_central_part()22 brec_part_base::edge_to_central_part()
23 {
24   if (out_edges().size() == 0) return nullptr;
25   else return *out_edges_begin();
26 }
27 
28 brec_hierarchy_edge_sptr
edge_to_second_part()29 brec_part_base::edge_to_second_part()
30 {
31   if (out_edges().size() < 2) return nullptr;
32   auto eit = out_edges_begin();
33   eit++;
34   return *eit;
35 }
36 
37 //: marking receptive field is only possible for brec_part_instance class instances
mark_receptive_field(vil_image_view<vxl_byte> &,unsigned)38 bool brec_part_base::mark_receptive_field(vil_image_view<vxl_byte>& /*img*/, unsigned /*plane*/)
39 {
40   return true;
41 }
42 
mark_center(vil_image_view<vxl_byte> &,unsigned)43 bool brec_part_base::mark_center(vil_image_view<vxl_byte>& /*img*/, unsigned /*plane*/)
44 {
45   return true;
46 }
47 
xml_element()48 bxml_data_sptr brec_part_base::xml_element()
49 {
50   bxml_element* data = new bxml_element("base");
51   data->set_attribute("layer", layer_);
52   data->set_attribute("type", type_);
53   data->set_attribute("det_thres", detection_threshold_);
54   data->set_attribute("prior_prob", prior_prob_);
55   data->set_attribute("log_likelihood", log_likelihood_); // only used during training to pick the best parts
56 
57   data->append_text("\n ");
58   return data;
59 }
60 
xml_parse_element(bxml_data_sptr data)61 bool brec_part_base::xml_parse_element(bxml_data_sptr data)
62 {
63   bxml_element query("base");
64   bxml_data_sptr base_root = bxml_find_by_name(data, query);
65 
66   if (!base_root)
67     return false;
68 
69   if (base_root->type() == bxml_data::ELEMENT) {
70     ((bxml_element*)base_root.ptr())->get_attribute("prior_prob", prior_prob_); // don't return false if cannot find these
71     ((bxml_element*)base_root.ptr())->get_attribute("log_likelihood", log_likelihood_);
72     return ((bxml_element*)base_root.ptr())->get_attribute("layer", layer_) &&
73            ((bxml_element*)base_root.ptr())->get_attribute("type", type_) &&
74            ((bxml_element*)base_root.ptr())->get_attribute("det_thres", detection_threshold_);
75   } else
76     return false;
77 }
78 
cast_to_base(void)79 brec_part_base* brec_part_base::cast_to_base(void)
80 {
81   return this;
82 }
83 
cast_to_gaussian(void)84 brec_part_gaussian* brec_part_base::cast_to_gaussian(void)
85 {
86   return nullptr;
87 }
88 
cast_to_instance(void)89 brec_part_instance* brec_part_base::cast_to_instance(void)
90 {
91   return nullptr;
92 }
93 
94 
cast_to_gaussian(void)95 brec_part_gaussian* brec_part_instance::cast_to_gaussian(void)
96 {
97   return nullptr;
98 }
99 
cast_to_instance(void)100 brec_part_instance* brec_part_instance::cast_to_instance(void)
101 {
102   return this;
103 }
104 
105 
mark_receptive_field(vil_image_view<vxl_byte> & img,unsigned plane)106 bool brec_part_instance::mark_receptive_field(vil_image_view<vxl_byte>& img, unsigned plane)
107 {
108   if (this->out_degree() == 0)
109     return false;
110 
111   for (auto eit = this->out_edges_begin(); eit != this->out_edges_end(); eit++) {
112     brec_part_instance_sptr pi = (*eit)->target()->cast_to_instance();
113     pi->mark_receptive_field(img, plane);
114   }
115   return true;
116 }
117 
mark_receptive_field(vil_image_view<float> & img,float val)118 bool brec_part_instance::mark_receptive_field(vil_image_view<float>& img, float val)
119 {
120   if (this->out_degree() == 0)
121     return false;
122 
123   for (auto eit = this->out_edges_begin(); eit != this->out_edges_end(); eit++) {
124     brec_part_instance_sptr pi = (*eit)->target()->cast_to_instance();
125     pi->mark_receptive_field(img, val);
126   }
127   return true;
128 }
129 
mark_center(vil_image_view<float> & img,float val)130 bool brec_part_instance::mark_center(vil_image_view<float>& img, float val)
131 {
132   if (this->out_degree() == 0)
133     return false;
134 
135   for (auto eit = this->out_edges_begin(); eit != this->out_edges_end(); eit++) {
136     brec_part_instance_sptr pi = (*eit)->target()->cast_to_instance();
137     pi->mark_center(img, val);
138   }
139   return true;
140 }
141 
mark_center(vil_image_view<vxl_byte> & img,unsigned plane)142 bool brec_part_instance::mark_center(vil_image_view<vxl_byte>& img, unsigned plane)
143 {
144   if (img.nplanes() <= plane)
145     return false;
146 
147   int ni = (int)img.ni();
148   int nj = (int)img.nj();
149 
150   int ic = (int)std::floor(x_ + 0.5f);
151   int jc = (int)std::floor(y_ + 0.5f);
152   if (ic >= 0 && jc >= 0 && ic < ni && jc < nj)
153     img(ic, jc, plane) = (vxl_byte)(strength_*255);
154 
155   return true;
156 }
157 
158 //: this method should be overwritten by inheriting classes so should never be called
159 vnl_vector_fixed<float,2>
direction_vector(void)160 brec_part_instance::direction_vector(void)  // return a unit vector that gives direction of this instance in the image
161 {
162   vnl_vector_fixed<float,2> v;
163   v(1) = 1.0f;
164   v(2) = 0.0f;
165   return v;
166 }
167 
168 
xml_element()169 bxml_data_sptr brec_part_instance::xml_element()
170 {
171   bxml_data_sptr data_super = brec_part_base::xml_element();
172 
173   bxml_element* data = new bxml_element("instance");
174   data->set_attribute("kind",kind_);
175   data->set_attribute("x",x_);
176   data->set_attribute("y",y_);
177   data->set_attribute("strength",strength_);
178   data->set_attribute("rho",rho_c_f_);
179   data->set_attribute("cnt",cnt_);
180   data->append_text("\n ");
181   data->append_data(data_super);
182   data->append_text("\n ");
183 
184   return data;
185 }
186 
xml_parse_element(bxml_data_sptr data)187 bool brec_part_instance::xml_parse_element(bxml_data_sptr data)
188 {
189   bxml_element query("instance");
190   bxml_data_sptr ins_root = bxml_find_by_name(data, query);
191 
192   if (!ins_root)
193     return false;
194 
195   if (ins_root->type() == bxml_data::ELEMENT) {
196     bool found = (((bxml_element*)ins_root.ptr())->get_attribute("kind", kind_) &&
197                   ((bxml_element*)ins_root.ptr())->get_attribute("x", x_) &&
198                   ((bxml_element*)ins_root.ptr())->get_attribute("y", y_) &&
199                   ((bxml_element*)ins_root.ptr())->get_attribute("strength", strength_) &&
200                   ((bxml_element*)ins_root.ptr())->get_attribute("rho", rho_c_f_) &&
201                   ((bxml_element*)ins_root.ptr())->get_attribute("cnt", cnt_)
202                  );
203     if (!found)
204       return false;
205 
206     return brec_part_base::xml_parse_element(ins_root);
207   } else
208     return false;
209 }
210 
211 //: return a simple box with diagonal 2*radius centered on this instance
212 vgl_box_2d<float>
get_probe_box(float radius)213 brec_part_instance::get_probe_box(float radius)
214 {
215   float b_r = radius/float(std::sqrt(2.0)); // we want maximal distance in the box to be radius
216   vgl_point_2d<float> pr0(x_-b_r, y_-b_r), pr1(x_+b_r, y_+b_r);
217   vgl_box_2d<float> probe;
218   probe.add(pr0); probe.add(pr1);
219 
220   return probe;
221 }
222