1 // This is brl/bseg/brec/brec_part_hierarchy_detector.cxx
2 #include <utility>
3 #include <iostream>
4 #include <algorithm>
5 #include "brec_part_hierarchy_detector.h"
6 //:
7 // \file
8 // \author Ozge C Ozcanli (ozge@lems.brown.edu)
9 // \date Oct 16, 2008
10
11 #include "brec_part_base.h"
12 #include "brec_part_gaussian.h"
13 #include "brec_part_hierarchy.h"
14
15 #include "vil/vil_image_view.h"
16 #include "vil/vil_image_resource.h"
17
18 #ifdef _MSC_VER
19 # include "vcl_msvc_warnings.h"
20 #endif
21
~brec_part_hierarchy_detector()22 brec_part_hierarchy_detector::~brec_part_hierarchy_detector()
23 {
24 auto it = map_rtree_.begin();
25 for ( ; it != map_rtree_.end(); it++) {
26 delete (*it).second;
27 }
28
29 map_rtree_.clear();
30
31 auto it2 = map_instance_.begin();
32 for ( ; it2 != map_instance_.end(); it2++) {
33 ((*it2).second).clear();
34 }
35
36 map_instance_.clear();
37 }
38
detect(const vil_image_resource_sptr & img)39 bool brec_part_hierarchy_detector::detect(const vil_image_resource_sptr& img)
40 {
41 // start from the primitives
42 std::vector<brec_part_instance_sptr> dumm_ins = h_->get_dummy_primitive_instances();
43 std::vector<brec_part_instance_sptr> parts_prims;
44 for (auto & dumm_in : dumm_ins) {
45 if (dumm_in->kind_ == brec_part_instance_kind::GAUSSIAN) {
46 brec_part_gaussian_sptr p = dumm_in->cast_to_gaussian();
47 if (!extract_gaussian_primitives(img, p->lambda0_, p->lambda1_, p->theta_, p->bright_, p->cutoff_percentage_, p->detection_threshold_, p->type_, parts_prims)) {
48 std::cout << "problems in extracting gaussian primitives!!\n";
49 return false;
50 }
51 }
52 }
53
54 map_instance_[0] = parts_prims;
55
56 // create an rtree
57 auto *tr = new Rtree_type();
58 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (0, tr));
59 for (const auto & parts_prim : parts_prims) {
60 tr->add(parts_prim);
61 }
62
63 unsigned highest = h_->highest_layer_id();
64 std::vector<brec_part_instance_sptr> parts_upper_most(parts_prims);
65 Rtree_type *rtree_upper_most = tr;
66 for (unsigned l = 1; l <= highest; l++) {
67 std::vector<brec_part_instance_sptr> parts_current;
68
69 extract_upper_layer(parts_upper_most, img->ni(), img->nj(), rtree_upper_most, parts_current);
70 std::cout << "extracted " << parts_current.size() << " parts of layer " << l << std::endl;
71
72 map_instance_[l] = parts_current;
73
74 auto *rtree_current = new Rtree_type();
75 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (l, rtree_current));
76
77 for (const auto & i : parts_current) {
78 rtree_current->add(i);
79 }
80
81 parts_upper_most.clear();
82 parts_upper_most = parts_current;
83
84 rtree_upper_most = rtree_current;
85 }
86
87 std::cout << "\textracted " << parts_upper_most.size() << " of highest layer: " << highest << " parts, rtree size: " << rtree_upper_most->size() << std::endl;
88
89 return true;
90 }
91
92 //: extracts instances of each layer in the given image, by rotating the detector with the given amount
detect(const vil_image_resource_sptr & img,float angle)93 bool brec_part_hierarchy_detector::detect(const vil_image_resource_sptr& img, float angle)
94 {
95 // start from the primitives
96 std::vector<brec_part_instance_sptr> dumm_ins = h_->get_dummy_primitive_instances();
97 std::vector<brec_part_instance_sptr> parts_prims;
98 for (auto & dumm_in : dumm_ins) {
99 if (dumm_in->kind_ == brec_part_instance_kind::GAUSSIAN) {
100 brec_part_gaussian_sptr p = dumm_in->cast_to_gaussian();
101 if (!extract_gaussian_primitives(img, p->lambda0_, p->lambda1_, p->theta_+angle, p->bright_, p->cutoff_percentage_, p->detection_threshold_, p->type_, parts_prims)) {
102 std::cout << "problems in extracting gaussian primitives!!\n";
103 return false;
104 }
105 }
106 }
107 map_instance_[0] = parts_prims;
108 std::cout << "extracted " << parts_prims.size() << " parts of layer 0\n";
109 // create an rtree
110 auto *tr = new Rtree_type();
111 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (0, tr));
112 for (const auto & parts_prim : parts_prims) {
113 tr->add(parts_prim);
114 }
115
116 unsigned highest = h_->highest_layer_id();
117 std::vector<brec_part_instance_sptr> parts_upper_most(parts_prims);
118 Rtree_type *rtree_upper_most = tr;
119 for (unsigned l = 1; l <= highest; l++) {
120 std::vector<brec_part_instance_sptr> parts_current;
121
122 extract_upper_layer(parts_upper_most, img->ni(), img->nj(), rtree_upper_most, parts_current);
123 std::cout << "extracted " << parts_current.size() << " parts of layer " << l << std::endl;
124
125 map_instance_[l] = parts_current;
126
127 auto *rtree_current = new Rtree_type();
128 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (l, rtree_current));
129
130 for (const auto & i : parts_current) {
131 rtree_current->add(i);
132 }
133
134 parts_upper_most.clear();
135 parts_upper_most = parts_current;
136
137 rtree_upper_most = rtree_current;
138 }
139
140 std::cout << "\textracted " << parts_upper_most.size() << " of highest layer: " << highest << " parts, rtree size: " << rtree_upper_most->size() << std::endl;
141
142 return true;
143 }
144
detect_primitives_using_trained_response_models(vil_image_view<float> & img,vil_image_view<float> & fg_prob_img,float angle,float prior_class)145 bool brec_part_hierarchy_detector::detect_primitives_using_trained_response_models(vil_image_view<float>& img, vil_image_view<float>& fg_prob_img, float angle, float prior_class)
146 {
147 // start from the primitives
148 std::vector<brec_part_instance_sptr> dumm_ins = h_->get_dummy_primitive_instances();
149 std::vector<brec_part_instance_sptr> parts_prims;
150 for (auto & dumm_in : dumm_ins) {
151 if (dumm_in->kind_ == brec_part_instance_kind::GAUSSIAN) {
152 brec_part_gaussian_sptr p = dumm_in->cast_to_gaussian();
153 if (!p->extract(img, fg_prob_img, angle, h_->model_dir(), parts_prims, prior_class)) {
154 std::cout << "problems in extracting gaussian primitives!!\n";
155 return false;
156 }
157 }
158 }
159
160 map_instance_[0] = parts_prims;
161
162 // create an rtree
163 auto *tr = new Rtree_type();
164 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (0, tr));
165 for (const auto & parts_prim : parts_prims) {
166 tr->add(parts_prim);
167 }
168
169 return true;
170 }
171
172 //: sets rho parameter of the primitives differently during training
173 // Rotates the detector with the given amount
detect_primitives_for_training(vil_image_view<float> & inp,vil_image_view<float> & fg_prob_img,float angle)174 bool brec_part_hierarchy_detector::detect_primitives_for_training(vil_image_view<float>& inp, vil_image_view<float>& fg_prob_img, float angle)
175 {
176 // start from the primitives
177 std::vector<brec_part_instance_sptr> dumm_ins = h_->get_dummy_primitive_instances();
178 std::vector<brec_part_instance_sptr> parts_prims;
179 for (auto & dumm_in : dumm_ins) {
180 if (dumm_in->kind_ == brec_part_instance_kind::GAUSSIAN) {
181 brec_part_gaussian_sptr p = dumm_in->cast_to_gaussian();
182 if (!p->extract(inp, fg_prob_img, angle, parts_prims)) {
183 std::cout << "problems in extracting gaussian primitives!!\n";
184 return false;
185 }
186 }
187 }
188 map_instance_[0] = parts_prims;
189 std::cout << "extracted " << parts_prims.size() << " primitives\n";
190
191 // create an rtree
192 auto *tr = new Rtree_type();
193 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (0, tr));
194 for (const auto & parts_prim : parts_prims) {
195 tr->add(parts_prim);
196 }
197
198 return true;
199 }
200
detect(vil_image_view<float> & img,vil_image_view<float> & fg_prob_img,float angle,unsigned rho_calculation_method,double radius,float prior_class,unsigned layer_id)201 bool brec_part_hierarchy_detector::detect(vil_image_view<float>& img, vil_image_view<float>& fg_prob_img, float angle, unsigned rho_calculation_method, double radius, float prior_class, unsigned layer_id)
202 {
203 switch (rho_calculation_method) {
204 case brec_detector_methods::POSTERIOR_NUMERATOR :
205 case brec_detector_methods::POSTERIOR :
206 if (!detect_primitives_using_trained_response_models(img, fg_prob_img, angle, prior_class))
207 return false;
208 break;
209 case brec_detector_methods::DENSITY_FOR_TRAINING :
210 if (!detect_primitives_for_training(img, fg_prob_img, angle))
211 return false;
212 break;
213 default:
214 std::cout << "Warning: unknown brec_detector_method encountered: " << rho_calculation_method << std::endl;
215 break;
216 }
217
218 std::cout << "extracted " << map_instance_[0].size() << " primitive parts." << std::endl;
219
220 unsigned highest = h_->highest_layer_id();
221 if (layer_id < highest)
222 highest = layer_id;
223
224 std::vector<brec_part_instance_sptr> parts_upper_most(map_instance_[0]);
225 Rtree_type *rtree_upper_most = map_rtree_[0];
226 for (unsigned l = 1; l <= highest; l++) {
227 std::vector<brec_part_instance_sptr> parts_current;
228
229 extract_upper_layer(parts_upper_most, rtree_upper_most, parts_current, rho_calculation_method, l*radius);
230 std::cout << "extracted " << parts_current.size() << " parts of layer " << l << std::endl;
231
232 map_instance_[l] = parts_current;
233
234 auto *rtree_current = new Rtree_type();
235 map_rtree_.insert(std::pair<unsigned, Rtree_type*> (l, rtree_current));
236
237 for (const auto & i : parts_current) {
238 rtree_current->add(i);
239 }
240
241 parts_upper_most.clear();
242 parts_upper_most = parts_current;
243
244 rtree_upper_most = rtree_current;
245 }
246
247 std::cout << "\textracted " << parts_upper_most.size() << " of highest layer: " << highest << " parts, rtree size: " << rtree_upper_most->size() << std::endl;
248
249 return true;
250 }
251
252 // check for existence of upper_p with central_p as its central part and map will tell if all the other parts exist
253 brec_part_instance_sptr
exists(const brec_part_base_sptr & upper_p,const brec_part_instance_sptr & central_p,unsigned,unsigned,Rtree_type * lower_rtree,float det_threshold)254 brec_part_hierarchy_detector::exists(const brec_part_base_sptr& upper_p,
255 const brec_part_instance_sptr& central_p, unsigned /*ni*/, unsigned /*nj*/, // FIXME - ni and nj unused
256 Rtree_type* lower_rtree,
257 float det_threshold)
258 {
259 // first check if types and layers of central_p instance matches with upper_p's info
260 if (upper_p->central_part()->type_ != central_p->type_ || upper_p->layer_ != central_p->layer_ + 1) {
261 std::cout << "central_p instance passed is not compatible with the upper layer part passed\n";
262 return nullptr;
263 }
264
265 brec_part_instance_sptr pi = new brec_part_instance(upper_p->layer_, upper_p->type_, brec_part_instance_kind::COMPOSED, central_p->x_, central_p->y_, 0.0f);
266 brec_hierarchy_edge_sptr e1 = new brec_hierarchy_edge(pi->cast_to_base(), central_p->cast_to_base(), true);
267 pi->add_outgoing_edge(e1);
268
269 // now for each other part of upper_p, check whether they exist in the map
270 float cx = central_p->x_; float cy = central_p->y_;
271 auto eit = upper_p->out_edges_begin();
272 eit++; // skip the central part
273 double strength = 1.0;
274
275 for ( ; eit != upper_p->out_edges_end(); eit++) {
276 vgl_box_2d<float> probe = (*eit)->get_probe_box(central_p);
277 std::vector<brec_part_instance_sptr> found;
278 lower_rtree->get(probe, found);
279
280 double best_fit = 0.0;
281 double best_fit_str = 1.0;
282 brec_part_instance_sptr best_part;
283 for (auto & i : found) {
284 if (i->strength_ > det_threshold && i->type_ == (*eit)->target()->type_)
285 {
286 vnl_vector_fixed<float, 2> v(i->x_-cx, i->y_-cy);
287 float dist, angle;
288 (*eit)->calculate_dist_angle(central_p, v, dist, angle);
289 double str = (*eit)->prob_density(dist, angle);
290
291 if (str < double(det_threshold))
292 continue;
293 if (best_fit < str) {
294 best_fit = str;
295 best_fit_str = i->strength_;
296 best_part = i;
297 }
298 }
299 }
300
301 if (best_fit <= 0)
302 return nullptr; // this sub-part not found
303 strength *= best_fit*best_fit_str;
304 if (best_part) {
305 brec_hierarchy_edge_sptr e2 = new brec_hierarchy_edge(pi->cast_to_base(), best_part->cast_to_base(), false);
306 pi->add_outgoing_edge(e2);
307 }
308 }
309 strength *= central_p->strength_;
310
311 // if all of them have been detected then declare existence at the central parts location
312 pi->strength_ = float(strength);
313
314 return pi;
315 }
316
317 //: check for existence of \p upper_p with \p central_p as its central part and map will tell if all the other parts exist
318 // No thresholding, \return a probabilistic score
319 brec_part_instance_sptr
exists(const brec_part_base_sptr & upper_p,const brec_part_instance_sptr & central_p,Rtree_type * lower_rtree)320 brec_part_hierarchy_detector::exists(const brec_part_base_sptr& upper_p,
321 const brec_part_instance_sptr& central_p,
322 Rtree_type* lower_rtree)
323 {
324 // first check if types and layers of central_p instance matches with upper_p's info
325 if (upper_p->central_part()->type_ != central_p->type_ || upper_p->layer_ != central_p->layer_ + 1) {
326 std::cout << "central_p instance passed is not compatible with the upper layer part passes\n";
327 return nullptr;
328 }
329
330 brec_part_instance_sptr pi = new brec_part_instance(upper_p->layer_, upper_p->type_, brec_part_instance_kind::COMPOSED, central_p->x_, central_p->y_, 0.0f);
331 brec_hierarchy_edge_sptr e1 = new brec_hierarchy_edge(pi->cast_to_base(), central_p->cast_to_base(), true);
332 pi->add_outgoing_edge(e1);
333
334 // now for each other part of upper_p, check whether they exist in the map
335 float cx = central_p->x_; float cy = central_p->y_;
336 auto eit = upper_p->out_edges_begin();
337 eit++; // skip the central part
338 double strength = 1.0;
339 for ( ; eit != upper_p->out_edges_end(); eit++) {
340 vgl_box_2d<float> probe = (*eit)->get_probe_box(central_p);
341 std::vector<brec_part_instance_sptr> found;
342 lower_rtree->get(probe, found);
343
344 double best_fit = 0.0;
345 double best_fit_str = 1.0;
346 brec_part_instance_sptr best_part;
347 for (auto & i : found) {
348 if (i->type_ == (*eit)->target()->type_) {
349 vnl_vector_fixed<float, 2> v(i->x_-cx, i->y_-cy);
350 float dist, angle;
351 (*eit)->calculate_dist_angle(central_p, v, dist, angle);
352 double str = (*eit)->prob_density(dist, angle);
353 if (best_fit < str) {
354 best_fit = str;
355 best_fit_str = i->strength_;
356 best_part = i;
357 }
358 }
359 }
360
361 if (best_fit <= 0 || !best_part)
362 return nullptr; // this sub-part not found
363
364 brec_hierarchy_edge_sptr e2 = new brec_hierarchy_edge(pi->cast_to_base(), best_part->cast_to_base(), false);
365 pi->add_outgoing_edge(e2);
366 strength *= best_fit*best_fit_str;
367 }
368 strength *= central_p->strength_;
369
370 // if all of them have been detected then declare existence at the central parts location
371 pi->strength_ = float(strength);
372
373 return pi;
374 }
375
376 //: given a set of detected lower level parts, create a set of instance detections for one layer above in the hierarchy
extract_upper_layer(std::vector<brec_part_instance_sptr> & extracted_parts,unsigned ni,unsigned nj,Rtree_type * extracted_parts_rtree,std::vector<brec_part_instance_sptr> & extracted_upper_parts)377 void brec_part_hierarchy_detector::extract_upper_layer(std::vector<brec_part_instance_sptr>& extracted_parts, unsigned ni, unsigned nj,
378 Rtree_type* extracted_parts_rtree,
379 std::vector<brec_part_instance_sptr>& extracted_upper_parts)
380 {
381 // for each detected part, check for the existence of each upper layer part that uses it as a central part
382 for (const auto& p : extracted_parts) {
383 // find this type in the primitive layer of the hierarchy
384 brec_part_base_sptr hp = h_->get_node(p->layer_, p->type_);
385 if (!hp)
386 continue;
387
388 // find the all the upper layer parts that use hp as a central part
389 // check the incoming edges of hp
390 for (auto eit = hp->in_edges_begin(); eit != hp->in_edges_end(); eit++) {
391 if (hp == (*eit)->source()->central_part()) {
392 brec_part_base_sptr hp_upper = (*eit)->source();
393
394 // now check for the existence of other primitives wrt to the central part and initiate an instance of it if so
395 brec_part_instance_sptr hp_upper_instance = exists(hp_upper, p, ni, nj, extracted_parts_rtree, hp_upper->detection_threshold_); // p will be its central part and map will tell if all the other parts exist
396 if (!hp_upper_instance)
397 continue;
398 if (hp_upper_instance->strength_ > hp_upper->detection_threshold_)
399 extracted_upper_parts.push_back(hp_upper_instance);
400 }
401 }
402 }
403 }
404
405 //: check for existence of \p upper_p with \p central_p as its central part and map will tell if all the other parts exist
406 // No thresholding, \return a probabilistic score
407 brec_part_instance_sptr
exists_for_training(const brec_part_base_sptr & upper_p,const brec_part_instance_sptr & central_p,Rtree_type * lower_rtree)408 brec_part_hierarchy_detector::exists_for_training(const brec_part_base_sptr& upper_p,
409 const brec_part_instance_sptr& central_p,
410 Rtree_type* lower_rtree)
411 {
412 // first check if types and layers of central_p instance matches with upper_p's info
413 if (upper_p->central_part()->type_ != central_p->type_ || upper_p->layer_ != central_p->layer_ + 1) {
414 std::cout << "central_p instance passed is not compatible with the upper layer part passes\n";
415 return nullptr;
416 }
417
418 brec_part_instance_sptr pi = new brec_part_instance(upper_p->layer_, upper_p->type_, brec_part_instance_kind::COMPOSED, central_p->x_, central_p->y_, 0.0f);
419 brec_hierarchy_edge_sptr e1 = new brec_hierarchy_edge(pi->cast_to_base(), central_p->cast_to_base(), true);
420 pi->add_outgoing_edge(e1);
421
422 // now for each other part of upper_p, check whether they exist in the map
423 float cx = central_p->x_; float cy = central_p->y_;
424 auto eit = upper_p->out_edges_begin();
425 eit++; // skip the central part
426 double rho = 1.0;
427 for ( ; eit != upper_p->out_edges_end(); eit++) {
428 vgl_box_2d<float> probe = (*eit)->get_probe_box(central_p);
429 std::vector<brec_part_instance_sptr> found;
430 lower_rtree->get(probe, found);
431
432 double best_fit = -100000.0;
433 brec_part_instance_sptr best_part;
434 for (auto & i : found) {
435 if (i->type_ == (*eit)->target()->type_) {
436 vnl_vector_fixed<float, 2> v(i->x_-cx, i->y_-cy);
437 float dist, angle;
438 (*eit)->calculate_dist_angle(central_p, v, dist, angle);
439 double rho = (*eit)->prob_density(dist, angle)*i->rho_c_f_;
440 if (best_fit < rho) {
441 best_fit = rho;
442 best_part = i;
443 }
444 }
445 }
446
447 if (best_fit <= 0 || !best_part)
448 return nullptr; // this sub-part not found
449
450 brec_hierarchy_edge_sptr e2 = new brec_hierarchy_edge(pi->cast_to_base(), best_part->cast_to_base(), false);
451 pi->add_outgoing_edge(e2);
452 rho *= best_fit;
453 }
454 rho *= central_p->rho_c_f_;
455
456 // if all of them have been detected then declare existence at the central parts location
457 pi->rho_c_f_ = rho;
458 pi->strength_ = float(rho);
459
460 return pi;
461 }
462
463 //: check for existence of \p upper_p with \p central_p as its central part and map will tell if all the other parts exist
464 // No thresholding, \return a probabilistic score
465 brec_part_instance_sptr
exists_using_hierarchies(const brec_part_base_sptr & upper_p,const brec_part_instance_sptr & central_p,Rtree_type * lower_rtree,double radius)466 brec_part_hierarchy_detector::exists_using_hierarchies(const brec_part_base_sptr& upper_p,
467 const brec_part_instance_sptr& central_p,
468 Rtree_type* lower_rtree, double radius)
469 {
470 // first check if types and layers of central_p instance matches with upper_p's info
471 if (upper_p->central_part()->type_ != central_p->type_ || upper_p->layer_ != central_p->layer_ + 1) {
472 std::cout << "central_p instance passed is not compatible with the upper layer part passes\n";
473 return nullptr;
474 }
475
476 double uniform = 1.0/radius * 1.0/8.0;
477
478 brec_part_instance_sptr pi = new brec_part_instance(upper_p->layer_, upper_p->type_, brec_part_instance_kind::COMPOSED, central_p->x_, central_p->y_, 0.0f);
479 brec_hierarchy_edge_sptr e1 = new brec_hierarchy_edge(pi->cast_to_base(), central_p->cast_to_base(), true);
480 pi->add_outgoing_edge(e1);
481
482 // now for each other part of upper_p, check whether they exist in the map
483 float cx = central_p->x_; float cy = central_p->y_;
484
485 auto eit = upper_p->out_edges_begin();
486 eit++; // skip the central part
487
488 float prior_non_c_b = 1.0f - (prior_c_f_ + prior_non_c_f_ + prior_c_b_);
489
490 double rho_c_f = central_p->rho_c_f_ * prior_c_f_;
491 double rho_c_b = central_p->rho_c_b_ * prior_c_b_;
492 double rho_nc_f = central_p->rho_nc_f_ * prior_non_c_f_;
493 double rho_nc_b = central_p->rho_nc_b_ * prior_non_c_b;
494
495 for ( ; eit != upper_p->out_edges_end(); eit++) {
496 vgl_box_2d<float> probe = (*eit)->get_probe_box(central_p);
497 std::vector<brec_part_instance_sptr> found;
498 lower_rtree->get(probe, found);
499
500 double best_score = -100000.0;
501 brec_part_instance_sptr best_part;
502 brec_hierarchy_edge_sptr best_edge;
503 for (auto & i : found) {
504 if (i == central_p) // skip itself
505 continue;
506 if (i->type_ == (*eit)->target()->type_) {
507 vnl_vector_fixed<float, 2> v(i->x_-cx, i->y_-cy);
508 float dist, angle;
509 (*eit)->calculate_dist_angle(central_p, v, dist, angle);
510 double dens = (*eit)->prob_density(dist, angle);
511 double rho_c_f_i = dens*i->rho_c_f_*rho_c_f;
512 double rho_c_b_i = dens*i->rho_c_b_*rho_c_b;
513 double rho_nc_f_i = uniform*i->rho_nc_f_*rho_nc_f;
514 double rho_nc_b_i = uniform*i->rho_nc_b_*rho_nc_b;
515
516 double s = std::min(rho_c_f_i/rho_c_b_i,rho_c_f_i/rho_nc_f_i);
517 s = std::min(s, rho_c_f_i/rho_nc_b_i);
518
519 if (best_score < s) {
520 best_score = s;
521 best_part = i;
522 best_edge = (*eit);
523 }
524 }
525 }
526
527 if (best_score <= 0 || !best_part)
528 return nullptr; // this sub-part not found
529
530 brec_hierarchy_edge_sptr e2 = new brec_hierarchy_edge(pi->cast_to_base(), best_part->cast_to_base(), false);
531 e2->set_model(best_edge->dist_model_, best_edge->angle_model_, best_edge->weight_);
532 pi->add_outgoing_edge(e2);
533 }
534
535 // now compute the score for the part with a second pass
536 eit = pi->out_edges_begin();
537 eit++; // skip the central part
538 for ( ; eit != pi->out_edges_end(); eit++) {
539 brec_part_instance_sptr pi2 = (*eit)->target()->cast_to_instance();
540 vnl_vector_fixed<float, 2> v(pi2->x_-cx, pi2->y_-cy);
541 float dist, angle;
542 (*eit)->calculate_dist_angle(central_p, v, dist, angle);
543 double dens = (*eit)->prob_density(dist, angle);
544 rho_c_f *= dens*pi2->rho_c_f_;
545 rho_c_b *= dens*pi2->rho_c_b_;
546 rho_nc_f *= uniform*pi2->rho_nc_f_;
547 rho_nc_b *= uniform*pi2->rho_nc_b_;
548 }
549
550 #if 0 // OZGE TODO: implement the contributions from the other classes
551 // compute the denominator by locating a part with the same primitives with this one in each hierarchy in the list
552 double sum = 0.0;
553 for (unsigned i = 0; i < class_hierarchies_.size(); i++) {
554 std::vector<double> scores;
555 if (class_hierarchies_[i]->get_score(pi, scores))
556 for (unsigned k = 0; k < scores.size(); k++)
557 sum += scores[k];
558 }
559 #endif // 0
560
561 // if all of them have been detected then declare existence at the central parts location
562 double den = (rho_c_f+rho_c_b+rho_nc_f+rho_nc_b);
563 pi->rho_c_f_ = rho_c_f/den;
564 pi->rho_c_b_ = rho_c_b/den;
565 pi->rho_nc_f_ = rho_nc_f/den;
566 pi->rho_nc_b_ = rho_nc_b/den;
567
568 pi->strength_ = float(pi->rho_c_f_);
569
570 return pi;
571 }
572
573
574 //: given a set of detected lower level parts, create a set of instance detections for one layer above in the hierarchy
575 // No thresholding, \return a probabilistic score
576 // rho_calculation_method = 0 if probabilistic score
577 // rho_calculation_method = 1 if training
578 // rho_calculation_method = 2 if using other hierarchies to compute a posterior
extract_upper_layer(std::vector<brec_part_instance_sptr> & extracted_parts,Rtree_type * extracted_parts_rtree,std::vector<brec_part_instance_sptr> & extracted_upper_parts,unsigned rho_calculation_method,double radius)579 void brec_part_hierarchy_detector::extract_upper_layer(std::vector<brec_part_instance_sptr>& extracted_parts,
580 Rtree_type* extracted_parts_rtree,
581 std::vector<brec_part_instance_sptr>& extracted_upper_parts, unsigned rho_calculation_method, double radius)
582 {
583 // for each detected part, check for the existence of each upper layer part that uses it as a central part
584 for (const auto& p : extracted_parts) {
585 // find this type
586 brec_part_base_sptr hp = h_->get_node(p->layer_, p->type_);
587 if (!hp)
588 continue;
589
590 if (p->layer_ == 1 && p->x_ == 165 && p->y_ == 189) {
591 std::cout << "here!\n";
592 }
593
594 // find the all the upper layer parts that use hp as a central part
595 // check the incoming edges of hp
596 for (auto eit = hp->in_edges_begin(); eit != hp->in_edges_end(); eit++) {
597 if ((*eit)->to_central() && hp == (*eit)->source()->central_part()) {
598 brec_part_base_sptr hp_upper = (*eit)->source();
599
600 // now check for the existence of other primitives wrt to the central part and initiate an instance of it if so
601 brec_part_instance_sptr hp_upper_instance;
602
603 // p will be its central part and map will tell if all the other parts exist
604 switch (rho_calculation_method) {
605 case brec_detector_methods::POSTERIOR_NUMERATOR : hp_upper_instance = exists(hp_upper, p, extracted_parts_rtree); break;
606 case brec_detector_methods::DENSITY_FOR_TRAINING : hp_upper_instance = exists_for_training(hp_upper, p, extracted_parts_rtree); break;
607 case brec_detector_methods::POSTERIOR : hp_upper_instance = exists_using_hierarchies(hp_upper, p, extracted_parts_rtree, radius); break;
608 default: std::cout << "Warning: unknown brec_detector_method encountered: " << rho_calculation_method << std::endl; break;
609 }
610
611 if (!hp_upper_instance)
612 continue;
613 extracted_upper_parts.push_back(hp_upper_instance);
614 }
615 }
616 }
617 }
618
619 //: Binary io, NOT IMPLEMENTED, signatures defined to use brec_part_hierarchy as a brdb_value
vsl_b_write(vsl_b_ostream &,brec_part_hierarchy_detector const &)620 void vsl_b_write(vsl_b_ostream & /*os*/, brec_part_hierarchy_detector const & /*ph*/)
621 {
622 std::cerr << "vsl_b_write() -- Binary io, NOT IMPLEMENTED, signatures defined to use brec_part_hierarchy_learner as a brdb_value\n";
623 return;
624 }
625
626 //: Binary io, NOT IMPLEMENTED, signatures defined to use brec_part_hierarchy as a brdb_value
vsl_b_read(vsl_b_istream &,brec_part_hierarchy_detector &)627 void vsl_b_read(vsl_b_istream & /*is*/, brec_part_hierarchy_detector & /*ph*/)
628 {
629 std::cerr << "vsl_b_read() -- Binary io, NOT IMPLEMENTED, signatures defined to use brec_part_hierarchy_learner as a brdb_value\n";
630 return;
631 }
632
vsl_b_read(vsl_b_istream & is,brec_part_hierarchy_detector * ph)633 void vsl_b_read(vsl_b_istream& is, brec_part_hierarchy_detector* ph)
634 {
635 delete ph;
636 bool not_null_ptr;
637 vsl_b_read(is, not_null_ptr);
638 if (not_null_ptr)
639 {
640 brec_part_hierarchy_sptr dummy;
641 ph = new brec_part_hierarchy_detector(dummy);
642 vsl_b_read(is, *ph);
643 }
644 else
645 ph = nullptr;
646 }
647
vsl_b_write(vsl_b_ostream & os,const brec_part_hierarchy_detector * & ph)648 void vsl_b_write(vsl_b_ostream& os, const brec_part_hierarchy_detector* &ph)
649 {
650 if (ph==nullptr)
651 {
652 vsl_b_write(os, false); // Indicate null pointer stored
653 }
654 else
655 {
656 vsl_b_write(os,true); // Indicate non-null pointer stored
657 vsl_b_write(os,*ph);
658 }
659 }
660