1 #include <iostream>
2 #include <cmath>
3 #include "bwm_observer_img.h"
4 //:
5 // \file
6
7 #include <bwm/algo/bwm_algo.h>
8 #include <bwm/algo/bwm_utils.h>
9 #include <bwm/algo/bwm_image_processor.h>
10 #include <bwm/bwm_tableau_mgr.h>
11
12 #include <bgui/bgui_image_tableau.h>
13 #include <bgui/bgui_image_utils.h>
14 #include "vgui/vgui_section_render.h"
15 #include "vgui/vgui_projection_inspector.h"
16
17 #include <bsol/bsol_algs.h>
18 #include <vsol/vsol_point_2d.h>
19 #include <vsol/vsol_box_2d.h>
20 #include <vsol/vsol_polygon_2d.h>
21 #include <vsol/vsol_polyline_2d.h>
22 #include <vsol/vsol_digital_curve_2d.h>
23 #include <vsol/vsol_line_2d.h>
24
25 #include "vgl/vgl_box_2d.h"
26 #include "vgl/vgl_polygon.h"
27
28 #include "vil/vil_image_view.h"
29 #include <vil/file_formats/vil_nitf2_image.h>
30
31 #ifdef _MSC_VER
32 # include "vcl_msvc_warnings.h"
33 #endif
34
bwm_observer_img(bgui_image_tableau_sptr const & img,std::string name,std::string image_path,bool display_image_path)35 bwm_observer_img::bwm_observer_img(bgui_image_tableau_sptr const& img, std::string name, std::string image_path, bool display_image_path)
36 : bgui_vsol2D_tableau(img), lock_vgui_status_(false), vgui_status_on_(false), draw_mode_(MODE_2D_POLY), img_tab_(img), viewer_(nullptr),
37 change_type_("change"), show_image_path_(false), start_x_(0), start_y_(0), moving_p_(nullptr), moving_v_(nullptr), moving_vertex_(false),
38 moving_polygon_(false), in_jog_mode_(false), row_(0), col_(0)
39 {
40 // LOAD IMAGE
41
42 vgui_range_map_params_sptr params;
43 vil_image_resource_sptr img_res = bwm_utils::load_image(image_path, params);
44 if (!img_res) {
45 //show_error("Image [" + image_path + "] NOT found");
46 return;
47 }
48 img->set_image_resource(img_res, params);
49
50 img->show_image_path(display_image_path);
51 img->set_file_name(image_path);
52 set_tab_name(name);
53 }
54
handle(const vgui_event & e)55 bool bwm_observer_img::handle(const vgui_event &e)
56 {
57 vgui_projection_inspector pi;
58
59 if (e.type == vgui_BUTTON_DOWN &&
60 e.button == vgui_MIDDLE &&
61 e.modifier == vgui_SHIFT)
62 {
63 bgui_vsol_soview2D* p=nullptr;
64 bwm_soview2D_vertex* v = nullptr;
65
66 // get the selected polyline or polygon
67 if ((p = (bgui_vsol_soview2D*) get_selected_object(POLYGON_TYPE)) ||
68 (p = (bgui_vsol_soview2D*) get_selected_object(POLYLINE_TYPE))) {
69 // take the position of the first point
70 pi.window_to_image_coordinates(e.wx, e.wy, start_x_, start_y_);
71 moving_p_ = p;
72 moving_polygon_ = true;
73 moving_vertex_ = false;
74 return true;
75 }
76 else if ((v = (bwm_soview2D_vertex*) get_selected_object(VERTEX_TYPE))) {
77 pi.window_to_image_coordinates(e.wx, e.wy, start_x_, start_y_);
78 moving_v_ = v;
79 moving_p_ = v->obj();
80 moving_vertex_ = true;
81 moving_polygon_ = false;
82 return true;
83 }
84 }
85 else if (e.type == vgui_MOTION && e.button == vgui_MIDDLE &&
86 e.modifier == vgui_SHIFT && moving_polygon_)
87 {
88 float x, y;
89 pi.window_to_image_coordinates(e.wx, e.wy, x, y);
90 float x_diff = x-start_x_;
91 float y_diff = y-start_y_;
92 moving_p_->translate(x_diff, y_diff);
93
94 // move all the vertices of the polyline or polygon
95 std::vector<bwm_soview2D_vertex*> vertices = vert_list[moving_p_->get_id()];
96 for (unsigned i=0; i<vertices.size(); i++) {
97 bwm_soview2D_vertex* v = vertices[i];
98 v->translate(x_diff, y_diff);
99 }
100 start_x_ = x;
101 start_y_ = y;
102
103 post_redraw();
104 return true;
105 }
106 else if (e.type == vgui_MOTION && e.button == vgui_MIDDLE &&
107 e.modifier == vgui_SHIFT && moving_vertex_)
108 {
109 float x, y;
110 pi.window_to_image_coordinates(e.wx, e.wy, x, y);
111 float x_diff = x-start_x_;
112 float y_diff = y-start_y_;
113 // find the polyline including this vertex
114 unsigned i = moving_v_->vertex_indx();
115 moving_v_->translate(x_diff, y_diff);
116 if (moving_p_->type_name().compare(POLYGON_TYPE) == 0) {
117 bgui_vsol_soview2D_polygon* polygon = (bgui_vsol_soview2D_polygon*) moving_p_;
118 polygon->sptr()->vertex(i)->set_x( polygon->sptr()->vertex(i)->x() + x_diff );
119 polygon->sptr()->vertex(i)->set_y( polygon->sptr()->vertex(i)->y() + y_diff );
120 }
121 else if (moving_p_->type_name().compare(POLYLINE_TYPE) == 0) {
122 bgui_vsol_soview2D_polyline* polyline = (bgui_vsol_soview2D_polyline*) moving_p_;
123 polyline->sptr()->vertex(i)->set_x( polyline->sptr()->vertex(i)->x() + x_diff );
124 polyline->sptr()->vertex(i)->set_y( polyline->sptr()->vertex(i)->y() + y_diff );
125 }
126 else {
127 std::cerr << moving_p_->type_name() << " is NOT movable!!!!\n";
128 }
129
130 start_x_ = x;
131 start_y_ = y;
132 post_redraw();
133 return true;
134 }
135 else if (e.type == vgui_BUTTON_UP && e.button == vgui_MIDDLE && e.modifier == vgui_SHIFT) {
136 this->deselect_all();
137 moving_vertex_ = false;
138 moving_polygon_ = false;
139 in_jog_mode_ = false;
140 return true;
141 }
142 return base::handle(e);
143 }
144
145 //eliminate the segmentation soviews
~bwm_observer_img()146 bwm_observer_img::~bwm_observer_img()
147 {
148 std::map<unsigned, std::vector<bgui_vsol_soview2D* > >::iterator mit =
149 seg_views.begin();
150 for (; mit!=seg_views.end(); ++mit)
151 {
152 std::vector<bgui_vsol_soview2D* > soviews = (*mit).second;
153 for (unsigned i=0; i<soviews.size(); i++) {
154 this->remove(soviews[i]);
155 }
156 }
157 seg_views.clear();
158 this->clear_reg_segmentation();
159 }
160
set_draw_mode(BWM_2D_DRAW_MODE mode)161 void bwm_observer_img::set_draw_mode(BWM_2D_DRAW_MODE mode)
162 {
163 // if mode changed from the last time
164 if (mode != draw_mode_) {
165 draw_mode_ = mode;
166 bool selectable = true;
167
168 if (mode == MODE_2D_VERTEX) // vertex mode
169 selectable = false;
170
171 // polygons are mapped to soview ID, make them unselectable
172 for (std::map<unsigned, bgui_vsol_soview2D*>::iterator it = obj_list.begin();
173 it != obj_list.end(); it++) {
174 //vgui_soview* p = vgui_soview::id_to_object(it->first);
175 it->second->set_selectable(selectable);
176 }
177 // vector of vertices are mapped soview ID for each polygon
178 for (std::map<unsigned, std::vector<bwm_soview2D_vertex* > >::iterator it=vert_list.begin();
179 it != vert_list.end(); it++) {
180 std::vector<bwm_soview2D_vertex* > v_list = it->second;
181 for (unsigned i=0; i<v_list.size(); i++)
182 v_list[i]->set_selectable(!selectable);
183 }
184 }
185 }
186
create_box(vsol_box_2d_sptr box)187 unsigned bwm_observer_img::create_box(vsol_box_2d_sptr box)
188 {
189 vsol_polygon_2d_sptr pbox = bsol_algs::poly_from_box(box);
190 return create_polygon(pbox);
191 }
192
create_polygon(vsol_polygon_2d_sptr poly2d)193 unsigned bwm_observer_img::create_polygon(vsol_polygon_2d_sptr poly2d)
194 {
195 float *x, *y;
196 bwm_algo::get_vertices_xy(poly2d, &x, &y);
197 unsigned nverts = poly2d->size();
198
199 this->set_foreground(1,1,0);
200 bgui_vsol_soview2D_polygon* polygon = this->add_vsol_polygon_2d(poly2d);
201 obj_list[polygon->get_id()] = polygon;
202 if (draw_mode_ == 1)
203 polygon->set_selectable(false);
204
205 std::vector<bwm_soview2D_vertex*> verts;
206 this->set_foreground(0,1,0);
207 for (unsigned i = 0; i<nverts; ++i) {
208 bwm_soview2D_vertex* vertex = new bwm_soview2D_vertex(x[i],y[i],0.5f, polygon, i);
209 if (draw_mode_ == 0)
210 vertex->set_selectable(false);
211 this->add(vertex);
212 verts.push_back(vertex);
213 }
214 vert_list[polygon->get_id()] = verts;
215 return polygon->get_id();
216 }
217
create_polyline(vsol_polyline_2d_sptr poly2d)218 unsigned bwm_observer_img::create_polyline(vsol_polyline_2d_sptr poly2d)
219 {
220 float *x, *y;
221 bwm_algo::get_vertices_xy(poly2d, &x, &y);
222 unsigned nverts = poly2d->size();
223 bgui_vsol_soview2D_polyline* polyline = this->add_vsol_polyline_2d(poly2d);
224 obj_list[polyline->get_id()] = polyline;
225
226 std::vector<bwm_soview2D_vertex*> verts;
227 this->set_foreground(0,1,0);
228 for (unsigned i = 0; i<nverts; ++i) {
229 bwm_soview2D_vertex* vertex = new bwm_soview2D_vertex(x[i],y[i],0.5f, polyline, i);
230 this->add(vertex);
231 verts.push_back(vertex);
232 }
233 vert_list[polyline->get_id()] = verts;
234 return polyline->get_id();
235 }
236
create_point(vsol_point_2d_sptr p)237 unsigned bwm_observer_img::create_point(vsol_point_2d_sptr p)
238 {
239 bgui_vsol_soview2D_point* point = this->add_vsol_point_2d(p);
240 obj_list[point->get_id()] = point;
241 return point->get_id();
242 }
243
244 //: save the polygon to paste later, always stores the last selected
copy()245 void bwm_observer_img::copy()
246 {
247 std::vector<vgui_soview*> select_list = this->get_selected_soviews();
248 if (select_list.size() > 1) {
249 std::cerr << "Please select only one object to copy\n";
250 return;
251 }
252 copy_obj_ = (vgui_soview2D*) select_list[0];
253 }
254
paste(float x,float y)255 void bwm_observer_img::paste(float x, float y)
256 {
257 if (!copy_obj_) {
258 std::cerr << "No object is selected to paste, COPY first\n";
259 return;
260 }
261
262 float cx, cy;
263 if (copy_obj_->type_name().compare(POLYGON_TYPE) == 0) {
264 bgui_vsol_soview2D_polygon* obj = (bgui_vsol_soview2D_polygon*) copy_obj_;
265 obj->get_centroid(&cx, &cy);
266 vsol_polygon_2d_sptr p = obj->sptr();
267
268 // translate it
269 unsigned int n = p->size();
270 std::vector<vsol_point_2d_sptr> vertices;
271
272 for (unsigned int i=0; i<n;i++)
273 vertices.push_back(new vsol_point_2d(p->vertex(i)->x() + (x-cx), p->vertex(i)->y() + (y-cy)));
274
275 vsol_polygon_2d_sptr new_p = new vsol_polygon_2d(vertices);
276 create_polygon(new_p);
277 post_redraw();
278 }
279 else if (copy_obj_->type_name().compare(POLYLINE_TYPE) == 0) {
280 bgui_vsol_soview2D_polyline* obj = (bgui_vsol_soview2D_polyline*) copy_obj_;
281 obj->get_centroid(&cx, &cy);
282 vsol_polyline_2d_sptr l = obj->sptr();
283 // translate it
284 unsigned int n = l->size();
285 std::vector<vsol_point_2d_sptr> vertices;
286
287 for (unsigned int i=0; i<n;i++)
288 vertices.push_back(new vsol_point_2d(l->vertex(i)->x() + (x-cx), l->vertex(i)->y() + (y-cy)));
289
290 vsol_polyline_2d_sptr new_p = new vsol_polyline_2d(vertices);
291 create_polyline(new_p);
292 post_redraw();
293 }
294
295 this->deselect_all();
296 }
297
clear_objects()298 void bwm_observer_img::clear_objects()
299 {
300 std::map<unsigned, bgui_vsol_soview2D*>::iterator oit = obj_list.begin();
301 for (; oit!=obj_list.end(); ++oit)
302 this->remove((*oit).second);
303 obj_list.clear();
304 std::map<unsigned, std::vector<bwm_soview2D_vertex* > >::iterator vsit =
305 vert_list.begin();
306 for (; vsit != vert_list.end(); ++vsit){
307 std::vector<bwm_soview2D_vertex* >::iterator vit = (*vsit).second.begin();
308 for (; vit != (*vsit).second.end(); ++vit)
309 this->remove(*vit);
310 }
311 vert_list.clear();
312 }
get_selected_line(bgui_vsol_soview2D_line_seg * & line)313 bool bwm_observer_img::get_selected_line(bgui_vsol_soview2D_line_seg* &line)
314 {
315 bgui_vsol_soview2D_line_seg* lseg = (bgui_vsol_soview2D_line_seg*)get_selected_object(LINE_SEG_TYPE);
316 if (lseg) {
317 line = lseg;
318 return true;
319 }
320 return false;
321 }
print_selected_line()322 void bwm_observer_img::print_selected_line(){
323 bgui_vsol_soview2D_line_seg* line_seg;
324 if(!get_selected_line(line_seg))
325 std::cout << "No selected line segment" << std::endl;
326 else{
327 vsol_point_2d_sptr p0 = line_seg->sptr()->p0();
328 vsol_point_2d_sptr p1 = line_seg->sptr()->p1();
329 std::cout << "sel line seg: " << vgl_point_2d<double>(p0->x(), p0->y()) << " -> " << vgl_point_2d<double>(p1->x(), p1->y()) << std::endl;
330 }
331 }
332
get_selected_box(bgui_vsol_soview2D_polygon * & box)333 bool bwm_observer_img::get_selected_box(bgui_vsol_soview2D_polygon* &box)
334 {
335 bgui_vsol_soview2D_polygon* p = (bgui_vsol_soview2D_polygon*)get_selected_object(POLYGON_TYPE);
336 if (p) {
337 #if 0
338 if (p->sptr()->size() != 4) {
339 std::cerr << "Selected polygon is not a box\n";
340 return false;
341 }
342 vsol_polygon_2d_sptr poly = p->sptr();
343 box = poly->get_bounding_box();
344 #endif
345 box = p;
346 return true;
347 }
348
349 return false;
350 }
get_selected_poly(bgui_vsol_soview2D_polygon * & poly)351 bool bwm_observer_img::get_selected_poly(bgui_vsol_soview2D_polygon* &poly){
352 bgui_vsol_soview2D_polygon* p = (bgui_vsol_soview2D_polygon*)get_selected_object(POLYGON_TYPE);
353 if(!p) return false;
354 poly = p;
355 return true;
356 }
get_selected_object(std::string type,bool warn)357 vgui_soview2D* bwm_observer_img::get_selected_object(std::string type,
358 bool warn)
359 {
360 std::vector<vgui_soview*> select_list = this->get_selected_soviews();
361 std::vector<vgui_soview2D*> objs;
362 vgui_soview2D* obj;
363
364 for (unsigned i=0; i<select_list.size(); i++) {
365 #if 0
366 std::cout << select_list[i]->type_name();
367 #endif
368 if (select_list[i]->type_name().compare(type) == 0) {
369 objs.push_back((vgui_soview2D*) select_list[i]);
370 }
371 }
372
373 if (objs.size() == 1) {
374 obj = (vgui_soview2D*) objs[0];
375 return obj;
376 }
377
378 if (warn)
379 std::cerr << "\nThe number of selected " << type << " is "
380 << objs.size() << ". Please select only one!!!\n";
381 return nullptr;
382 }
383
get_selected_objects(std::string type)384 std::vector<vgui_soview2D*> bwm_observer_img::get_selected_objects(std::string type)
385 {
386 std::vector<vgui_soview*> select_list = this->get_selected_soviews();
387 std::vector<vgui_soview2D*> objs;
388
389 for (unsigned i=0; i<select_list.size(); i++) {
390 std::cout << select_list[i]->type_name();
391 if (select_list[i]->type_name().compare(type) == 0) {
392 objs.push_back((vgui_soview2D*) select_list[i]);
393 }
394 }
395 std::cout << "Number of selected objects of type " << type << " = " << objs.size();
396 return objs;
397 }
398
399 std::vector<vsol_spatial_object_2d_sptr>
get_spatial_objects_2d()400 bwm_observer_img::get_spatial_objects_2d()
401 {
402 std::vector<vsol_spatial_object_2d_sptr> sos;
403 for (std::map<unsigned, bgui_vsol_soview2D*>::iterator soit = obj_list.begin();
404 soit != obj_list.end(); ++soit)
405 sos.push_back((*soit).second->base_sptr());
406 return sos;
407 }
408
delete_selected()409 void bwm_observer_img::delete_selected()
410 {
411 // first get the selected polygon
412 std::vector<vgui_soview*> select_list = this->get_selected_soviews();
413
414 if (select_list.size() == 0)
415 return;
416
417 if ((select_list.size() == 1) &&
418 ((select_list[0]->type_name().compare(POLYGON_TYPE) == 0) ||
419 (select_list[0]->type_name().compare(POLYLINE_TYPE) == 0)))
420 {
421 //first check to see if this is an image processing box
422
423 std::map<unsigned, std::vector<bgui_vsol_soview2D* > >::iterator mit =
424 seg_views.begin();
425 std::map<unsigned, std::vector<bgui_vsol_soview2D* > >::iterator to_remove =
426 seg_views.end();
427 for (; mit!=seg_views.end();++mit)
428 if (select_list[0]->get_id()==(*mit).first)
429 {
430 std::vector<bgui_vsol_soview2D* > edges = (*mit).second;
431
432 for (unsigned i=0; i<edges.size(); i++) {
433 this->remove(edges[i]);
434 }
435 to_remove = mit;
436 }
437 if (to_remove != seg_views.end())
438 seg_views.erase(to_remove);
439
440 // remove the polygon and the vertices
441 delete_polygon(select_list[0]);
442 }
443 else if (select_list[0]->type_name().compare(VERTEX_TYPE) == 0)
444 delete_vertex(select_list[0]);
445 this->post_redraw();
446 }
447
delete_all()448 void bwm_observer_img::delete_all()
449 {
450 this->clear_objects();
451 this->post_redraw();
452 }
453
delete_polygon(vgui_soview * obj)454 void bwm_observer_img::delete_polygon(vgui_soview* obj)
455 {
456 // remove the polygon
457 unsigned poly_id = obj->get_id();
458 this->remove(obj);
459 obj_list.erase(poly_id);
460
461 // remove the vertices
462 std::vector<bwm_soview2D_vertex*> v = vert_list[poly_id];
463 for (unsigned i=0; i<v.size(); i++) {
464 this->remove(v[i]);
465 }
466 vert_list.erase(poly_id);
467 this->post_redraw();
468 }
469
delete_vertex(vgui_soview * vertex)470 void bwm_observer_img::delete_vertex(vgui_soview* vertex)
471 {
472 bwm_soview2D_vertex* v = static_cast<bwm_soview2D_vertex*> (vertex);
473
474 if (v) {
475 bgui_vsol_soview2D* obj = v->obj();
476 unsigned i = v->vertex_indx();
477
478 // remove the vertex from the object
479 if (obj->type_name().compare(POLYGON_TYPE) == 0) {
480 bgui_vsol_soview2D_polygon* polygon = static_cast<bgui_vsol_soview2D_polygon*> (obj);
481 vsol_polygon_2d_sptr poly2d = polygon->sptr();
482 if (poly2d->size() == 3) {
483 std::cerr << "Cannot delete a vertex from a triangle\n";
484 return;
485 }
486
487 if (i >= poly2d->size()) {
488 std::cerr << "The index is invalid [" << i << " of " << poly2d->size() << '\n';
489 return;
490 }
491
492 std::vector<vsol_point_2d_sptr> new_vertices;
493 for (unsigned k=0; k < poly2d->size(); k++) {
494 if (k != i) // exclude the vertex to be deleted
495 new_vertices.push_back(poly2d->vertex(k));
496 }
497
498 // delete the object
499 delete_polygon(obj);
500
501 // draw the new one
502 vsol_polygon_2d_sptr new_poly = new vsol_polygon_2d(new_vertices);
503 create_polygon(new_poly);
504 }
505
506 else if (obj->type_name().compare(POLYLINE_TYPE) == 0) {
507 bgui_vsol_soview2D_polyline* polyline = static_cast<bgui_vsol_soview2D_polyline*> (obj);
508 vsol_polyline_2d_sptr poly2d = polyline->sptr();
509 if (poly2d->size() == 2) {
510 std::cerr << "Cannot delete a vertex from a polyline with 2 vertices\n";
511 return;
512 }
513
514 if (i >= poly2d->size()) {
515 std::cerr << "The index is invalid [" << i << " of " << poly2d->size() << '\n';
516 return;
517 }
518
519 std::vector<vsol_point_2d_sptr> new_vertices;
520 for (unsigned k=0; k < poly2d->size(); k++) {
521 if (k != i) // exclude the vertex to be deleted
522 new_vertices.push_back(poly2d->vertex(k));
523 }
524
525 // delete the object
526 delete_polygon(obj);
527
528 // draw the new one
529 vsol_polyline_2d_sptr new_poly = new vsol_polyline_2d(new_vertices);
530 create_polyline(new_poly);
531 }
532 }
533 }
534
clear_box()535 void bwm_observer_img::clear_box()
536 {
537 // get the selected box
538 bgui_vsol_soview2D_polygon* p = nullptr;
539
540 if (!this->get_selected_box(p))
541 {
542 std::cerr << "In bwm_observer_img::clear_box() - no box selected\n";
543 return ;
544 }
545
546 std::vector<bgui_vsol_soview2D* >& soviews = seg_views[p->get_id()];
547 for (unsigned i=0; i<soviews.size(); i++) {
548 this->remove(soviews[i]);
549 }
550
551 soviews.clear();
552 seg_views[p->get_id()] = soviews;
553 this->post_redraw();
554 // do not delete the information about deleted edges, we may want to bring them back
555 }
556
recover_edges()557 void bwm_observer_img::recover_edges()
558 {
559 //make sure the box is actually empty
560 this->clear_box();
561 // get the selected box
562 bgui_vsol_soview2D_polygon* p = nullptr;
563 if (!this->get_selected_box(p))
564 {
565 std::cerr << "In bwm_observer_img::clear_box() - no box selected\n";
566 return;
567 }
568
569 std::vector<vsol_digital_curve_2d_sptr > edges;
570 edges = edge_list[p->get_id()];
571 std::vector<bgui_vsol_soview2D*> soviews;
572 for (unsigned i=0; i<edges.size(); i++) {
573 bgui_vsol_soview2D_digital_curve* curve
574 = this->add_digital_curve(edges[i]);
575 soviews.push_back(curve);
576 }
577 seg_views[p->get_id()] = soviews;
578 post_redraw();
579 }
580
recover_lines()581 void bwm_observer_img::recover_lines()
582 {
583 //make sure the box is actually empty
584 this->clear_box();
585
586 // get the selected box
587 bgui_vsol_soview2D_polygon* p = nullptr;
588 if (!this->get_selected_box(p))
589 {
590 std::cerr << "In bwm_observer_img::clear_box() - no box selected\n";
591 return ;
592 }
593
594 std::vector<vsol_line_2d_sptr> lines;
595 lines = line_list[p->get_id()];
596 std::vector<bgui_vsol_soview2D*> soviews;
597 for (unsigned i=0; i<lines.size(); i++) {
598 bgui_vsol_soview2D_line_seg* line
599 = this->add_vsol_line_2d(lines[i]);
600 soviews.push_back(line);
601 }
602 seg_views[p->get_id()] = soviews;
603 post_redraw();
604 }
605 // display edges for experimental registration
606 void bwm_observer_img::
display_reg_seg(std::vector<vsol_digital_curve_2d_sptr> const & search_edges,std::vector<vsol_digital_curve_2d_sptr> const & model_edges)607 display_reg_seg(std::vector<vsol_digital_curve_2d_sptr> const& search_edges,
608 std::vector<vsol_digital_curve_2d_sptr> const& model_edges)
609 {
610 this->clear_reg_segmentation();
611 vgui_style_sptr mstyle = vgui_style::new_style(0.1f, 0.8f, 0.1f, 1.0f, 3.0f);
612 vgui_style_sptr sstyle = vgui_style::new_style(0.8f, 0.1f, 0.8f, 1.0f, 3.0f);
613
614 std::vector<vsol_digital_curve_2d_sptr>::const_iterator cit =
615 search_edges.begin();
616 for (; cit != search_edges.end(); ++cit)
617 reg_seg_views_.push_back(this->add_digital_curve(*cit, sstyle));
618
619 cit = model_edges.begin();
620 for (; cit != model_edges.end(); ++cit)
621 reg_seg_views_.push_back(this->add_digital_curve(*cit, mstyle));
622
623 this->post_redraw();
624 }
625
626 // clear the edges displayed for the experimental registration tasks
clear_reg_segmentation()627 void bwm_observer_img::clear_reg_segmentation()
628 {
629 for (std::vector<bgui_vsol_soview2D* >::iterator sit = reg_seg_views_.begin();
630 sit != reg_seg_views_.end(); ++sit)
631 this->remove(*sit);
632 reg_seg_views_.clear();
633 }
634
635
hist_plot()636 void bwm_observer_img::hist_plot()
637 {
638 bwm_image_processor::hist_plot(img_tab_);
639 }
640
hist_plot_in_poly()641 void bwm_observer_img::hist_plot_in_poly(){
642 bgui_vsol_soview2D_polygon* p;
643 if(!get_selected_poly(p)){
644 std::cerr << " No polygon to scan to produce hist plot\n";
645 return;
646 }
647 vsol_polygon_2d_sptr poly = p->sptr();
648 bwm_image_processor::hist_plot(img_tab_, poly);
649 }
650
intensity_profile(float start_col,float start_row,float end_col,float end_row)651 void bwm_observer_img::intensity_profile(float start_col, float start_row,
652 float end_col, float end_row)
653 {
654 bwm_image_processor::intensity_profile(img_tab_, start_col, start_row, end_col, end_row);
655 }
656
range_map()657 void bwm_observer_img::range_map()
658 {
659 bwm_image_processor::range_map(img_tab_);
660 }
661
toggle_show_image_path()662 void bwm_observer_img::toggle_show_image_path()
663 {
664 show_image_path_ = !show_image_path_;
665 img_tab_->show_image_path(show_image_path_);
666 }
667
step_edges_vd()668 void bwm_observer_img::step_edges_vd()
669 {
670 bgui_vsol_soview2D_polygon* p = nullptr;
671 if (!this->get_selected_box(p))
672 {
673 std::cerr << "In bwm_observer_img::step_edges_vd() - no box selected\n";
674 return;
675 }
676
677 std::vector<vsol_digital_curve_2d_sptr> edges;
678 vsol_polygon_2d_sptr poly = p->sptr();
679 vsol_box_2d_sptr box = poly->get_bounding_box();
680 if (!bwm_image_processor::step_edges_vd(img_tab_, box, edges))
681 {
682 std::cerr << "In bwm_observer_img::step_edges_vd() - no edges\n";
683 return;
684 }
685
686 // first clean up the box, if there is anything in it
687 clear_box();
688
689 std::vector<bgui_vsol_soview2D*> soviews;
690 for (std::vector<vsol_digital_curve_2d_sptr>::iterator eit = edges.begin();
691 eit != edges.end(); ++eit)
692 {
693 bgui_vsol_soview2D_digital_curve* curve = this->add_digital_curve(*eit);
694 soviews.push_back(curve);
695 }
696 edge_list[p->get_id()] = edges;
697 seg_views[p->get_id()] = soviews;
698 this->post_redraw();
699 }
700
lines_vd()701 void bwm_observer_img::lines_vd()
702 {
703 bgui_vsol_soview2D_polygon* p = nullptr;
704 if (!this->get_selected_box(p))
705 {
706 std::cerr << "In bwm_observer_img::lines_vd() - no box selected\n";
707 return ;
708 }
709
710 std::vector<vsol_line_2d_sptr> lines;
711 vsol_polygon_2d_sptr poly = p->sptr();
712 vsol_box_2d_sptr box = poly->get_bounding_box();
713 if (!bwm_image_processor::lines_vd(img_tab_, box, lines))
714 {
715 std::cerr << "In bwm_observer_img::lines_vd() - no lines\n";
716 return;
717 }
718
719 // first clean up the box, if there is anything in it
720 clear_box();
721
722 std::vector<bgui_vsol_soview2D*> soviews;
723 for (std::vector<vsol_line_2d_sptr>::iterator lit = lines.begin();
724 lit != lines.end(); ++lit)
725 {
726 bgui_vsol_soview2D_line_seg* line = this->add_vsol_line_2d(*lit);
727 // store in object list in order to save later if desired
728 obj_list[line->get_id()] = line;
729 // Gamze - do not add the lines one by one: create a vector and map it to the box
730 soviews.push_back(line);
731 }
732 line_list[p->get_id()] = lines;
733 seg_views[p->get_id()] = soviews;
734
735 this->post_redraw();
736 }
737
crop_image(vil_image_resource_sptr & chip)738 bool bwm_observer_img::crop_image(vil_image_resource_sptr& chip)
739 {
740 bgui_vsol_soview2D_polygon* p = nullptr;
741 if (!this->get_selected_box(p))
742 {
743 std::cerr << "In bwm_observer_img::crop_image() - no box selected\n";
744 return false;
745 }
746 vsol_polygon_2d_sptr poly = p->sptr();
747 vsol_box_2d_sptr box = poly->get_bounding_box();
748 return bwm_image_processor::crop_to_box(img_tab_, box, chip);
749 }
750
751 //: (x, y) is the target point to be positioned at the center of the grid cell containing this observer
752 //
move_to_point(float x,float y)753 void bwm_observer_img::move_to_point(float x, float y)
754 {
755 // the image size
756 unsigned ni = img_tab_->get_image_resource()->ni();
757 unsigned nj = img_tab_->get_image_resource()->nj();
758 if (x<0 || x>=ni || y<0 || y>=nj)
759 std::cerr << "In bwm_observer_img::move_to_point(.) -"
760 << " requested point outside of image bounds\n";
761 if (x<0) x=0;
762 if (x>=ni) x = ni-1;
763 if (y<0) y=0;
764 if (y>=nj) y = nj-1;
765 if (viewer_)
766 {
767 //Get the current viewer state (scale and offset)
768 float sx = viewer_->token.scaleX, sy = viewer_->token.scaleY;
769 float tx = viewer_->token.offsetX, ty = viewer_->token.offsetY;
770
771 //The position of this observer in the grid
772 unsigned r = this->row(), c = this->col();
773
774 //The grid tableau
775 vgui_grid_tableau_sptr grid = bwm_tableau_mgr::instance()->grid();
776 if (!grid)
777 return;
778
779 //The bounds of the grid cell containing this observer
780 float xorig , yorig, xmax, ymax;
781 grid->cell_bounding_box(c, r, xorig , yorig, xmax, ymax);
782
783 // target image point in window coordinates
784 float wx = sx*(x + tx/sx) + xorig;
785 float wy = (ymax-yorig - sy*(y + ty/sy))+ yorig;
786
787 // cell center in window coordinates
788 float twx = (xorig + xmax)/2;
789 float twy = (yorig + ymax)/2;
790
791 // The required translation to position in the center
792 float transx = twx-wx;
793 float transy = twy-wy;
794
795 viewer_->token.offsetX += transx;
796 viewer_->token.offsetY -= transy;
797 viewer_->post_redraw();
798
799 #if 0 // debug printouts
800 std::cout << "\n\n====--=====\n"
801 << "sx = " << sx << " sy = " << sy << '\n'
802 << "tx = " << tx << " ty = " << ty << '\n'
803 << "r = " << r << " c = " << c << '\n'
804 << "target point (" << x << ' ' << y << ")\n"
805 << "target point in window coords (" << wx << ' ' << wy << ")\n"
806 << "cell center in window coords ("
807 << twx << ' ' << twy << ")\n"
808 << "required tx = " << transx
809 << " required ty = " << transy << '\n'
810 << std::flush;
811 #endif
812 }
813 }
814
zoom_to_fit()815 void bwm_observer_img::zoom_to_fit()
816 {
817 if (!viewer_ || !img_tab_)
818 return;
819
820 if (!img_tab_->get_image_resource())
821 return;
822
823 // the image size
824 unsigned ni = img_tab_->get_image_resource()->ni();
825 unsigned nj = img_tab_->get_image_resource()->nj();
826
827 #if 0
828 // current viewer scale
829 float sx = viewer_->token.scaleX, sy = std::fabs(viewer_->token.scaleY);
830
831 // the window size
832 vgui_projection_inspector p_insp;
833 vgl_box_2d<float> bb(p_insp.x1, p_insp.x2, p_insp.y1, p_insp.y2);
834 float w = bb.width()*sx;
835 float h = bb.height()*sy;
836 #endif
837 //The grid tableau
838 vgui_grid_tableau_sptr grid = bwm_tableau_mgr::instance()->grid();
839 if (!grid)
840 return;
841
842 //The position of this observer in the grid
843 unsigned ro = this->row(), cl = this->col();
844
845 //The bounds of the grid cell containing this observer
846 float xorig , yorig, xmax, ymax;
847 grid->cell_bounding_box(cl, ro, xorig , yorig, xmax, ymax);
848
849 float w = xmax-xorig, h = ymax-yorig;
850
851 // the required scale to fit the image in the window
852 float required_scale_x = w/ni;
853 float required_scale_y = h/nj;
854 float r = required_scale_x;
855 if (r>required_scale_y)
856 r = required_scale_y;
857
858 // the center of the image
859 float cx = ni/2, cy = nj/2;
860
861 // set the scale on the viewer
862 viewer_->token.scaleX = r;
863 viewer_->token.scaleY = r;
864
865 // position so the image is centered
866 viewer_->token.offsetX = w/2.0-cx*r;
867 viewer_->token.offsetY = h/2.0-cy*r;
868
869 viewer_->post_redraw();
870 viewer_->post_redraw();
871 #if 0 //debug printouts
872 std::cout << "sx = " << sx << " sy = " << sy << '\n'
873 << "bb.w " << w << " bb.h " << h << '\n'
874 << "required scale = " << r << " c(" << cx << ' '
875 << cy << ")\n";
876 #endif
877 }
878
scroll_to_point()879 void bwm_observer_img::scroll_to_point()
880 {
881 static int ix = 0, iy = 0;
882 vgui_dialog zoom("Move to Image Position");
883 zoom.field ("image col", ix);
884 zoom.field ("image row", iy);
885 if (!zoom.ask())
886 return;
887 float x = static_cast<float>(ix), y = static_cast<float>(iy);
888 this->move_to_point(x,y);
889 }
890
init_mask()891 void bwm_observer_img::init_mask()
892 {
893 mask_ = nullptr;
894 change_polys_.clear();
895 }
896
set_change_type()897 void bwm_observer_img::set_change_type()
898 {
899 unsigned int type = 0;
900 vgui_dialog type_dialog("Change Type");
901
902 if (this->change_choices_.empty())
903 {
904 this->change_choices_.push_back("change");
905 this->change_choices_.push_back("don't care");
906 this->change_choices_.push_back("vehicle");
907 this->change_choices_.push_back("building");
908 this->change_choices_.push_back("shadow");
909 this->change_choices_.push_back("sewage");
910 this->change_choices_.push_back("car");
911 this->change_choices_.push_back("pick-up truck");
912 this->change_choices_.push_back("utility");
913 this->change_choices_.push_back("van");
914 this->change_choices_.push_back("suv");
915 this->change_choices_.push_back("minivan");
916 this->change_choices_.push_back("high-quality");
917 this->change_choices_.push_back("New Change Type");
918 }
919 type_dialog.choice("Change Type", this->change_choices_, type);
920 if (!type_dialog.ask())
921 return;
922
923 if (type > this->change_choices_.size()) {
924 std::cerr << "bwm_observer_img::set_change_type -- Invalid choice\n";
925 return;
926 }
927
928 if (this->change_choices_[type] == "New Change Type")
929 {
930 vgui_dialog new_change_dialog("New Change Type");
931 std::string new_change_type;
932 new_change_dialog.field("New Change Type", new_change_type);
933 new_change_dialog.ask();
934
935 bool already_listed = false;
936 for ( unsigned i = 0; i < this->change_choices_.size(); ++i )
937 {
938 if ( this->change_choices_[i] == new_change_type )
939 already_listed = true;
940 }
941 if ( !already_listed )
942 {
943 this->change_choices_.pop_back();
944 this->change_choices_.push_back(new_change_type);
945 this->change_choices_.push_back("New Change Type");
946 }
947
948 this->change_type_ = new_change_type;
949 }
950 else
951 change_type_ = this->change_choices_[type];
952 }
953
954
add_poly_to_mask()955 void bwm_observer_img::add_poly_to_mask()
956 {
957 bgui_vsol_soview2D_polygon* p=nullptr;
958
959 if (!ground_truth_)
960 ground_truth_ = new bvgl_changes();
961
962 // get the selected polygon
963 std::vector<vgui_soview2D*> polys = get_selected_objects(POLYGON_TYPE);
964 for (unsigned i=0; i<polys.size(); i++) {
965 p = (bgui_vsol_soview2D_polygon*) polys[i];
966 vsol_polygon_2d_sptr poly = p->sptr();
967 if (!poly)
968 continue;
969 vgl_polygon<double> v_poly = bsol_algs::vgl_from_poly(poly);
970 bvgl_change_obj_sptr obj = new bvgl_change_obj(v_poly, change_type_);
971 change_polys_[polys[i]->get_id()] = obj;
972 ground_truth_->add_obj(obj);
973 }
974 }
975
remove_poly_from_mask()976 void bwm_observer_img::remove_poly_from_mask()
977 {
978 bgui_vsol_soview2D_polygon* p=nullptr;
979 std::vector<vgui_soview2D*> polys = get_selected_objects(POLYGON_TYPE);
980 for (unsigned i=0; i<polys.size(); i++) {
981 p = (bgui_vsol_soview2D_polygon*) polys[i];
982 std::map<unsigned int, bvgl_change_obj_sptr>::iterator poly;
983 // search the change polygons for deletion
984 poly = change_polys_.find(p->get_id());
985 if (poly != change_polys_.end()) {
986 ground_truth_->remove_obj(poly->second);
987 change_polys_.erase(poly->first);
988 }
989 }
990 }
991
992 #if 0 // commented out
993 void bwm_observer_img::create_mask()
994 {
995 mask_ = 0;
996 //index through the polygons and create the boolean mask image
997 // the image size
998 unsigned ni = img_tab_->get_image_resource()->ni();
999 unsigned nj = img_tab_->get_image_resource()->nj();
1000 vil_image_view<unsigned char>* mask = new vil_image_view<unsigned char>(ni, nj);
1001 mask->fill(0);
1002
1003 // fill the change areas
1004 for (std::map<unsigned int, vsol_polygon_2d_sptr>::iterator pit = mask_polys_.begin();
1005 pit != mask_polys_.end(); ++pit)
1006 {
1007 vgl_polygon<double> v_poly = bsol_algs::vgl_from_poly(pit->second);
1008 vgl_polygon_scan_iterator<double> psi(v_poly, false);
1009 for (psi.reset(); psi.next();){
1010 int y = psi.scany();
1011 for (int x = psi.startx(); x<=psi.endx(); ++x)
1012 {
1013 unsigned u = static_cast<unsigned>(x);
1014 unsigned v = static_cast<unsigned>(y);
1015 (*mask)(u,v) = 255;
1016 }
1017 }
1018 }
1019
1020 // fill the don't care areas
1021 for (std::map<unsigned int, vsol_polygon_2d_sptr>::iterator pit = mask_dontcare_polys_.begin();
1022 pit != mask_dontcare_polys_.end(); ++pit)
1023 {
1024 vgl_polygon<double> v_poly = bsol_algs::vgl_from_poly(pit->second);
1025 vgl_polygon_scan_iterator<double> psi(v_poly, false);
1026 for (psi.reset(); psi.next();){
1027 int y = psi.scany();
1028 for (int x = psi.startx(); x<=psi.endx(); ++x)
1029 {
1030 unsigned u = static_cast<unsigned>(x);
1031 unsigned v = static_cast<unsigned>(y);
1032 (*mask)(u,v) = 125;
1033 }
1034 }
1035 }
1036 mask_ = mask;
1037 }
1038 #endif // 0
1039
mask()1040 vil_image_view_base_sptr bwm_observer_img::mask()
1041 {
1042 return ground_truth_->create_mask_from_objs(img_tab_->get_image_resource()->ni(), img_tab_->get_image_resource()->nj(), "change");
1043 }
1044
save_changes_binary()1045 bool bwm_observer_img::save_changes_binary()
1046 {
1047 std::string fname = bwm_utils::select_file();
1048 vsl_b_ofstream os(fname);
1049 ground_truth_->b_write(os);
1050 return true;
1051 }
1052
load_changes_binary()1053 bool bwm_observer_img::load_changes_binary()
1054 {
1055 std::string fname = bwm_utils::select_file();
1056 vsl_b_ifstream is(fname);
1057 if (ground_truth_ == nullptr)
1058 ground_truth_= new bvgl_changes();
1059 ground_truth_->b_read(is);
1060
1061 // draw the polygons on the image
1062 for (unsigned i=0; i<ground_truth_->size(); i++) {
1063 bvgl_change_obj_sptr obj = ground_truth_->obj(i);
1064 vgl_polygon<double> poly = obj->poly();
1065 vsol_polygon_2d_sptr poly2d = bsol_algs::poly_from_vgl(poly);
1066 unsigned id = this->create_polygon(poly2d);
1067 change_polys_[id] = obj;
1068 }
1069 return true;
1070 }
1071