Fawkes API  Fawkes Development Version
firestation.cpp
1 /***************************************************************************
2  * firestation.cpp - Firestation
3  *
4  * Created: Wed Oct 10 14:19:30 2007
5  * Copyright 2007-2008 Daniel Beck
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "firestation.h"
23 #include "color_train_widget.h"
24 #include "fuse_transfer_widget.h"
25 
26 #include <utils/math/angle.h>
27 
28 #include <fvwidgets/fuse_image_list_widget.h>
29 #include <gui_utils/avahi_dispatcher.h>
30 
31 #include <fvcams/fileloader.h>
32 #include <fvcams/shmem.h>
33 #include <fvcams/net.h>
34 
35 #ifdef HAVE_MIRROR_CALIB
36 #include <fvmodels/mirror/mirror_calib.h>
37 #endif
38 
39 #include <fvutils/ipc/shm_image.h>
40 #include <fvutils/color/conversions.h>
41 #include <fvutils/color/yuv.h>
42 #include <fvutils/colormap/yuvcm.h>
43 #include <fvutils/scalers/lossy.h>
44 #include <fvutils/system/camargp.h>
45 #include <fvutils/writers/jpeg.h>
46 #include <fvutils/writers/fvraw.h>
47 #include <fvutils/draw/drawer.h>
48 
49 #include <core/exception.h>
50 
51 #include <gdkmm/pixbuf.h>
52 
53 #include <arpa/inet.h>
54 
55 #include <iostream>
56 
57 using namespace std;
58 using namespace fawkes;
59 using namespace firevision;
60 
61 /** @class Firestation "firestation.h"
62  * Control GUI for vision related stuff.
63  * @author Daniel Beck
64  */
65 
66 /** Constructor.
67  * @param builder Gtk Builder
68  */
69 Firestation::Firestation(Glib::RefPtr<Gtk::Builder> builder)
70 {
71  // --- main window ------------------------------------------------
72  builder->get_widget("wndMain", m_wnd_main);
73  builder->get_widget("imgImage", m_img_image);
74  builder->get_widget("evtImageEventBox", m_evt_image);
75  builder->get_widget("trvShmImageIds", m_trv_shm_image_ids);
76  builder->get_widget("stbStatus", m_stb_status);
77  builder->get_widget("ckbContTrans", m_ckb_cont_trans);
78  builder->get_widget("spbUpdateTime", m_spb_update_time);
79 
80  m_img_image->signal_size_allocate().connect( sigc::mem_fun(*this, &Firestation::resize_image) );
81  m_evt_image->signal_button_press_event().connect( sigc::mem_fun(*this, &Firestation::image_click) );
82  m_ckb_cont_trans->signal_toggled().connect( sigc::mem_fun(*this, &Firestation::enable_cont_img_trans) );
83 
84  // ----------------------------------------------------------------
85 
86 
87  // --- toolbar widgets --------------------------------------------
88  builder->get_widget("tbtnExit", m_tbtn_exit);
89  builder->get_widget("tbtnCloseCamera", m_tbtn_close_camera);
90  builder->get_widget("tbtnUpdate", m_tbtn_update);
91  builder->get_widget("tbtnSave", m_tbtn_save);
92  builder->get_widget("tbtnOpenFile", m_tbtn_open_file);
93  builder->get_widget("tbtnOpenFolder", m_tbtn_open_folder);
94  builder->get_widget("tbtnOpenShm", m_tbtn_open_shm);
95  builder->get_widget("tbtnOpenFuse", m_tbtn_open_fuse);
96 
97  m_tbtn_exit->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::exit) );
98  m_tbtn_close_camera->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::close_camera) );
99  m_tbtn_update->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::update_image) );
100  m_tbtn_save->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::save_image) );
101  m_tbtn_open_file->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_file) );
102  m_tbtn_open_folder->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_folder) );
103  m_tbtn_open_shm->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_shm) );
104  m_tbtn_open_fuse->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_fuse) );
105  // ----------------------------------------------------------------
106 
107 
108  // --- dialogs ----------------------------------------------------
109  builder->get_widget("fcdOpenImage", m_fcd_open_image);
110  builder->get_widget("fcdSaveImage", m_fcd_save_image);
111  builder->get_widget("dlgOpenShm", m_dlg_open_shm);
112  builder->get_widget("trvShmImageIds", m_trv_shm_image_ids);
113  builder->get_widget("dlgOpenFuse", m_dlg_open_fuse);
114  builder->get_widget("ckbFuseJpeg", m_ckb_fuse_jpeg);
115  builder->get_widget("trvFuseServices", m_trv_fuse_services);
116 
117 #if GTK_VERSION_GE(3,0)
118  Glib::RefPtr<Gtk::FileFilter> filter_jpg = Gtk::FileFilter::create();
119 #else
120  Gtk::FileFilter *filter_jpg = Gtk::manage(new Gtk::FileFilter());
121 #endif
122  filter_jpg->set_name("JPEG");
123  filter_jpg->add_pattern("*.jpg");
124  filter_jpg->add_pattern("*.jpeg");
125 
126 #if GTK_VERSION_GE(3,0)
127  Glib::RefPtr<Gtk::FileFilter> filter_fvraw = Gtk::FileFilter::create();
128 #else
129  Gtk::FileFilter *filter_fvraw = Gtk::manage(new Gtk::FileFilter());
130 #endif
131  filter_fvraw->set_name("FVRaw");
132  filter_fvraw->add_pattern("*.raw");
133  filter_fvraw->add_pattern("*.fvraw");
134 
135 #if GTK_VERSION_GE(3,0)
136  m_fcd_open_image->add_filter(filter_jpg);
137  m_fcd_open_image->add_filter(filter_fvraw);
138 
139  m_fcd_save_image->add_filter(filter_jpg);
140  m_fcd_save_image->add_filter(filter_fvraw);
141 
142 #else
143  m_fcd_open_image->add_filter(*filter_jpg);
144  m_fcd_open_image->add_filter(*filter_fvraw);
145 
146  m_fcd_save_image->add_filter(*filter_jpg);
147  m_fcd_save_image->add_filter(*filter_fvraw);
148 #endif
149 
150  m_shm_list_store = Gtk::ListStore::create(m_shm_columns);
151  m_trv_shm_image_ids->set_model(m_shm_list_store);
152  m_trv_shm_image_ids->append_column("#", m_shm_columns.m_id);
153  m_trv_shm_image_ids->append_column("Name", m_shm_columns.m_name);
154 
155  m_fuse_tree_store = Gtk::TreeStore::create(m_fuse_columns);
156  m_trv_fuse_services->set_model(m_fuse_tree_store);
157  // m_trv_fuse_services->append_column("#", m_fuse_columns.m_id);
158  m_trv_fuse_services->append_column("Name", m_fuse_columns.m_name);
159  // ----------------------------------------------------------------
160 
161 
162  // --- color train widget -----------------------------------------
163  m_ctw = new ColorTrainWidget(this);
164  builder->get_widget("cmbCtObjectType", m_cmb_ct_type);
165  builder->get_widget("btnCtStart", m_btn_ct_start);
166  builder->get_widget("btnCtSeg", m_btn_ct_seg);
167  builder->get_widget("spbtnCtCmDepth", m_spbtn_depth);
168  builder->get_widget("spbtnCtCmWidth", m_spbtn_width);
169  builder->get_widget("spbtnCtCmHeight", m_spbtn_height);
170 
171  m_cmb_ct_type->signal_changed().connect(sigc::mem_fun(*this, &Firestation::ct_object_changed));
172  m_cmb_ct_type->set_active(0);
173 
174  m_btn_ct_start->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::ct_start) );
175 
176  m_ctw->update_image().connect( sigc::mem_fun(*this, &Firestation::draw_image) );
177  m_ctw->colormap_updated().connect( sigc::mem_fun(*this, &Firestation::on_colormap_updated) );
178 
179  Gtk::Button* btn;
180  builder->get_widget("btnCtUnselect", btn);
181  m_ctw->set_reset_selection_btn(btn);
182 
183  builder->get_widget("btnCtAdd", btn);
184  m_ctw->set_add_to_colormap_btn(btn);
185 
186  builder->get_widget("btnCtReset", btn);
187  m_ctw->set_reset_colormap_btn(btn);
188 
189  builder->get_widget("btnCtSaveHistos", btn);
190  m_ctw->set_save_histos_btn(btn);
191 
192  builder->get_widget("btnCtLoadHistos", btn);
193  m_ctw->set_load_histos_btn(btn);
194 
195  builder->get_widget("btnCtSaveColormap", btn);
196  m_ctw->set_save_colormap_btn(btn);
197 
198  builder->get_widget("btnCtLoadColormap", btn);
199  m_ctw->set_load_colormap_btn(btn);
200 
201  Gtk::Scale* scl;
202  builder->get_widget("sclCtThreshold", scl);
203  m_ctw->set_threshold_scl(scl);
204 
205  builder->get_widget("sclCtMinProb", scl);
206  m_ctw->set_min_prob_scl(scl);
207 
208  builder->get_widget("sclCtLayerSelector", scl);
209  m_ctw->set_cm_layer_selector(scl);
210 
211  Gtk::Image* img;
212  builder->get_widget("imgCtSegmentation", img);
213  m_ctw->set_segmentation_img(img);
214 
215  builder->get_widget("imgCtColormap", img);
216  m_ctw->set_colormap_img(img);
217 
218  Gtk::FileChooserDialog* fcd;
219  builder->get_widget("fcdFilechooser", fcd);
220  m_ctw->set_filechooser_dlg(fcd);
221 
222 
223  m_btn_ct_seg->signal_toggled().connect( sigc::mem_fun(*this, &Firestation::draw_image) );
224  m_ctw->set_cm_selector(m_spbtn_depth, m_spbtn_width, m_spbtn_height);
225  // ----------------------------------------------------------------
226 
227 
228  // --- mirror calibration -----------------------------------------
229 #ifdef HAVE_MIRROR_CALIB
230  m_calib_tool = new firevision::MirrorCalibTool();
231 #endif
232 
233 #ifndef HAVE_MIRROR_CALIB
234  Gtk::Notebook *nb;
235  Gtk::HBox *box;
236  builder->get_widget("ntbOptions", nb);
237  builder->get_widget("boxMirrorCalib", box);
238  nb->get_tab_label(*box)->set_sensitive(false);
239  box->set_sensitive(false);
240 #endif
241 
242  builder->get_widget("sclMcLine", m_scl_mc_line);
243  m_scl_mc_line->signal_change_value().connect( sigc::mem_fun(*this, &Firestation::mc_on_line_angle_changed) );
244 
245  builder->get_widget("btnMcLoadMask", m_btn_mc_load_mask);
246  m_btn_mc_load_mask->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_load_mask) );
247 
248  //builder->get_widget("btnMcStart", m_btn_mc_start);
249  builder->get_widget("btnCalibLoad", m_btn_mc_load);
250  builder->get_widget("btnCalibSave", m_btn_mc_save);
251  builder->get_widget("entCalibDist", m_ent_mc_dist);
252  builder->get_widget("entCalibOri", m_ent_mc_ori);
253  builder->get_widget("fcdCalibSave", m_fcd_mc_save);
254  builder->get_widget("fcdCalibLoad", m_fcd_mc_load);
255 
256  //m_btn_mc_start->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_start) );
257  m_btn_mc_load->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_load) );
258  m_btn_mc_save->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_save) );
259 
260  builder->get_widget("btnMcSetCenter", m_btn_mc_set_center);
261  m_btn_mc_set_center->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_set_center) );
262 
263  builder->get_widget("btnMcMemorize", m_btn_mc_memorize);
264  m_btn_mc_memorize->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_memorize) );
265 
266  builder->get_widget("btnMcSimulateClicks", m_btn_mc_simulate_clicks);
267  m_btn_mc_simulate_clicks->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_simulate_clicks) );
268 
269  builder->get_widget("entCalibDist", m_ent_mc_dist);
270  builder->get_widget("entCalibOri", m_ent_mc_ori);
271 
272  // ----------------------------------------------------------------
273  builder->get_widget("fcdMcLoadMask", m_fcd_mc_load_mask);
274  builder->get_widget("fcdCalibSave", m_fcd_mc_save);
275  builder->get_widget("fcdCalibLoad", m_fcd_mc_load);
276  // ----------------------------------------------------------------
277 
278 
279  // --- fuse transfer widget ---------------------------------------
280  m_ftw = new FuseTransferWidget();
281 
282  Gtk::TreeView* trv;
283  builder->get_widget("trvFuseRemoteLuts", trv);
284  m_ftw->set_remote_lut_list_trv(trv);
285  builder->get_widget("trvFuseLocalLuts", trv);
286  m_ftw->set_local_lut_list_trv(trv);
287  builder->get_widget("imgFuseLocal", img);
288  m_ftw->set_local_img(img);
289  builder->get_widget("imgFuseRemote", img);
290  m_ftw->set_remote_img(img);
291  builder->get_widget("btnFuseUpload", btn);
292  m_ftw->set_upload_btn(btn);
293  builder->get_widget("sclLocalLayerSelector", scl);
294  m_ftw->set_local_layer_selector(scl);
295  builder->get_widget("sclRemoteLayerSelector", scl);
296  m_ftw->set_remote_layer_selector(scl);
297  // ----------------------------------------------------------------
298 
299 
300  // --- fuse image list widget -------------------------------------
301  m_filw = new FuseImageListWidget();
302  builder->get_widget("trvFuseImageList", trv);
303  m_filw->set_image_list_trv(trv);
304  Gtk::CheckButton* chk;
305  builder->get_widget("chkFuseImageListUpdate", chk);
306  m_filw->set_auto_update_chk(chk);
307  builder->get_widget("chkFuseCompression", chk);
308  m_filw->set_toggle_compression_chk(chk);
309  m_filw->image_selected().connect( sigc::mem_fun(*this, &Firestation::on_fuse_image_selected) );
310  // ----------------------------------------------------------------
311 
312  m_yuv_orig_buffer = 0;
313  m_yuv_draw_buffer = 0;
314  m_yuv_scaled_buffer = 0;
315  m_rgb_scaled_buffer = 0;
316 
317  m_img_width = 0;
318  m_img_height = 0;
319  m_img_size = 0;
320  m_img_cs = CS_UNKNOWN;
321 
322  m_img_writer = 0;
323  m_camera = 0;
324  m_shm_buffer = 0;
325 
326  m_img_src = SRC_NONE;
327  m_op_mode = MODE_VIEWER;
328 
329  m_cont_img_trans = false;
330 
331  mc_line_angle_deg = 0.0;
332 
333  m_max_img_width = m_evt_image->get_width();
334  m_max_img_height = m_evt_image->get_height();
335  m_scaled_img_width = m_evt_image->get_width();
336  m_scaled_img_height = m_evt_image->get_height();
337  m_scale_factor = 1.0;
338 
339  m_avahi_thread = new AvahiThread();
340  m_avahi_dispatcher = new AvahiDispatcher;
341 
342  m_avahi_dispatcher->signal_service_added().connect( sigc::mem_fun( *this, &Firestation::on_service_added ) );
343  m_avahi_dispatcher->signal_service_removed().connect( sigc::mem_fun( *this, &Firestation::on_service_removed ) );
344 
345  m_avahi_thread->watch_service("_fountain._tcp", m_avahi_dispatcher);
346  m_avahi_thread->start();
347 }
348 
349 /** Destructor. */
351 {
352  if (m_yuv_orig_buffer) free(m_yuv_orig_buffer);
353  if (m_yuv_draw_buffer) free(m_yuv_draw_buffer);
354  if (m_yuv_scaled_buffer) free(m_yuv_scaled_buffer);
355  if (m_rgb_scaled_buffer) free(m_rgb_scaled_buffer);
356 
357  delete m_camera;
358  delete m_img_writer;
359 
360 #ifdef HAVE_MIRROR_CALIB
361  delete m_calib_tool;
362 #endif
363  delete m_ctw;
364  delete m_ftw;
365  delete m_filw;
366 
367  m_avahi_thread->cancel();
368  m_avahi_thread->join();
369  delete m_avahi_thread;
370  delete m_avahi_dispatcher;
371 
372  delete m_wnd_main;
373  delete m_fcd_open_image;
374  delete m_fcd_save_image;
375  delete m_dlg_open_shm;
376  delete m_dlg_open_fuse;
377 }
378 
379 /** Returns reference to main window.
380  * @return reference to main window
381  */
382 Gtk::Window&
384 {
385  return *m_wnd_main;
386 }
387 
388 /** Exit routine. */
389 void
390 Firestation::exit()
391 {
392  if (SRC_NONE != m_img_src)
393  { m_camera->close(); }
394 
395  m_wnd_main->hide();
396 }
397 
398 void
399 Firestation::close_camera()
400 {
401  if (SRC_NONE == m_img_src)
402  { return; }
403 
404  m_img_src = SRC_NONE;
405 
406  m_camera->close();
407  delete m_camera;
408  m_camera = 0;
409 
410  m_img_width = 0;
411  m_img_height = 0;
412  m_img_cs = CS_UNKNOWN;
413 
414  m_img_size = 0;
415 
416  m_img_image->clear();
417  m_img_image->set("gtk-missing-image");
418 
419  m_ctw->set_src_buffer(NULL, 0, 0);
420  m_ctw->set_draw_buffer(NULL);
421 }
422 
423 /** Saves the current image. */
424 void
425 Firestation::save_image()
426 {
427  if (m_img_src == SRC_NONE)
428  { return; }
429 
430  m_fcd_save_image->set_transient_for(*this);
431 
432  int result = m_fcd_save_image->run();
433 
434  switch(result)
435  {
436  case(Gtk::RESPONSE_OK):
437  {
438  delete m_img_writer;
439 
440  Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
441  if ( Glib::ustring("JPEG") == filter_name )
442  {
443  m_img_writer = new JpegWriter();
444  }
445  else if( Glib::ustring("FVRaw") == filter_name )
446  {
447  m_img_writer = new FvRawWriter();
448  }
449  else
450  {
451  cout << "save_file(): unknown file format" << endl;
452  break;
453  }
454 
455  std::string filename = m_fcd_save_image->get_filename();
456  m_img_writer->set_filename( filename.c_str() );
457  m_img_writer->set_dimensions(m_img_width, m_img_height);
458  m_img_writer->set_buffer(m_img_cs, m_yuv_orig_buffer);
459  m_img_writer->write();
460 
461  std::cout << "Save file: " << filename << std::endl;
462  break;
463  }
464 
465  case(Gtk::RESPONSE_CANCEL):
466  break;
467 
468  default:
469  break;
470  }
471 
472  m_fcd_save_image->hide();
473 }
474 
475 /** Reads in a new image for the current image source. */
476 void
477 Firestation::update_image()
478 {
479  if (m_img_src == SRC_NONE)
480  { return; }
481 
482  try
483  {
484  m_camera->capture();
485  convert(m_img_cs, YUV422_PLANAR,
486  m_camera->buffer(), m_yuv_orig_buffer,
487  m_img_width, m_img_height);
488  memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer,
489  colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
490  m_camera->dispose_buffer();
491 
492  draw_image();
493 
494  m_ctw->draw_segmentation_result();
495  }
496  catch (Exception& e)
497  {
498  e.print_trace();
499  }
500 }
501 
502 bool
503 Firestation::call_update_image()
504 {
505  if ( !m_cont_img_trans )
506  { return false; }
507 
508  update_image();
509 
510  return true;
511 }
512 
513 void
514 Firestation::enable_cont_img_trans()
515 {
516  if (m_cont_img_trans)
517  {
518  m_cont_img_trans = false;
519  return;
520  }
521 
522  int timeout = (int) rint( m_spb_update_time->get_value() );
523  sigc::connection conn = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Firestation::call_update_image), timeout);
524  m_cont_img_trans = true;
525 }
526 
527 /** Reads in an image from a file. */
528 void
529 Firestation::open_file()
530 {
531  m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
532  m_fcd_open_image->set_transient_for(*this);
533 
534  int result = m_fcd_open_image->run();
535 
536  switch(result)
537  {
538  case Gtk::RESPONSE_OK:
539  {
540  pre_open_img_src();
541 
542  std::string filename = m_fcd_open_image->get_filename();
543 
544  m_camera = new FileLoader( filename.c_str() );
545  m_img_src = SRC_FILE;
546  post_open_img_src();
547  break;
548  }
549 
550  case Gtk::RESPONSE_CANCEL:
551  {
552  break;
553  }
554 
555  default:
556  {
557  break;
558  }
559  }
560 
561  m_fcd_open_image->hide();
562 }
563 
564 /** Reads in images from a directory. */
565 void
566 Firestation::open_folder()
567 {
568  m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
569  m_fcd_open_image->set_transient_for(*this);
570 
571  int result = m_fcd_open_image->run();
572 
573  switch(result)
574  {
575  case Gtk::RESPONSE_OK:
576  {
577  pre_open_img_src();
578 
579  std::string extension;
580  Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
581  if ( Glib::ustring("JPEG") == filter_name )
582  { extension = "jpg"; }
583  else if ( Glib::ustring("FVRaw") == filter_name )
584  { extension = "raw"; }
585 
586  std::string folder = m_fcd_open_image->get_current_folder();
587  char* as;
588  if (asprintf(&as, "file:file:dir=%s:ext=%s", folder.c_str(), extension.c_str()) != -1) {
589  CameraArgumentParser cap(as);
590  m_camera = new FileLoader( &cap );
591  m_img_src = SRC_FILE;
592  post_open_img_src();
593  free(as);
594  } else {
595  printf("Cannot open folder, asprintf() ran out of memory");
596  }
597 
598  break;
599  }
600 
601  case Gtk::RESPONSE_CANCEL:
602  {
603  break;
604  }
605 
606  default:
607  {
608  break;
609  }
610  }
611 
612  m_fcd_open_image->hide();
613 }
614 
615 /** Opens a SHM image. */
616 void
617 Firestation::open_shm()
618 {
619  unsigned int num_buffers = 0;
622  shmit = SharedMemory::find(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h);
623 
624  if (shmit == SharedMemory::end())
625  {
626  m_stb_status->push("No SHM images found");
627  return;
628  }
629  else
630  {
631  m_shm_list_store->clear();
632 
633  while ( shmit != SharedMemory::end() )
634  {
635  ++num_buffers;
636  Gtk::TreeModel::Row row = *(m_shm_list_store->append());
637  row[m_shm_columns.m_id] = num_buffers;
639  row[m_shm_columns.m_name] = h->image_id();
640  shmit++;
641  }
642  }
643 
644  m_dlg_open_shm->set_transient_for(*this);
645 
646  int result = m_dlg_open_shm->run();
647 
648  switch(result)
649  {
650  case Gtk::RESPONSE_OK:
651  {
652  delete m_shm_buffer;
653 
654  Gtk::TreeModel::Path path;
655  Gtk::TreeViewColumn* column;
656  m_trv_shm_image_ids->get_cursor(path, column);
657 
658  Gtk::TreeModel::iterator iter = m_shm_list_store->get_iter(path);
659 
660  if (iter)
661  {
662  Gtk::TreeModel::Row row = *iter;
663  if (row)
664  {
665  Glib::ustring name = row[m_shm_columns.m_name];
666  pre_open_img_src();
667 
668  try
669  {
670  m_camera = new SharedMemoryCamera( name.c_str() );
671  }
672  catch (Exception& e)
673  {
674  e.print_trace();
675  }
676 
677  m_img_src = SRC_SHM;
678 
679  post_open_img_src();
680  }
681  }
682  else
683  {
684  std::cout << "invalid iter" << std::endl;
685  }
686 
687  break;
688  }
689 
690  case Gtk::RESPONSE_CANCEL:
691  break;
692 
693  default:
694  break;
695  }
696 
697  m_dlg_open_shm->hide();
698 }
699 
700 /** Connects to a FUSE server. */
701 void
702 Firestation::open_fuse()
703 {
704  Gtk::TreeModel::Children children = m_fuse_tree_store->children();
705  if ( 0 == children.size() )
706  {
707  m_stb_status->push("No FUSE services found");
708  return;
709  }
710 
711  m_trv_fuse_services->expand_all();
712  m_dlg_open_fuse->set_transient_for(*this);
713 
714  int result = m_dlg_open_fuse->run();
715 
716  switch(result)
717  {
718  case Gtk::RESPONSE_OK:
719  {
720  Gtk::TreeModel::Path path;
721  Gtk::TreeViewColumn* column;
722  m_trv_fuse_services->get_cursor(path, column);
723 
724  Gtk::TreeModel::iterator iter = m_fuse_tree_store->get_iter(path);
725 
726  if (iter)
727  {
728  Gtk::TreeModel::Row row = *iter;
729  if (row)
730  {
731  Glib::ustring hostname = row[m_fuse_columns.m_service_hostname];
732  unsigned short int port = row[m_fuse_columns.m_service_port];
733  Glib::ustring image_id = row[m_fuse_columns.m_image_id];
734  bool jpeg = m_ckb_fuse_jpeg->get_active();
735 
736  pre_open_img_src();
737 
738  try
739  {
740  m_camera = new NetworkCamera(hostname.c_str(), port, image_id.c_str(), jpeg);
741  m_img_src = SRC_FUSE;
742  post_open_img_src();
743  }
744  catch (Exception& e)
745  {
746  m_img_src = SRC_NONE;
747  e.print_trace();
748  }
749  }
750  }
751  else
752  {
753  std::cout << "invalid iter" << std::endl;
754  }
755 
756  break;
757  }
758 
759  case Gtk::RESPONSE_CANCEL:
760  break;
761 
762  default:
763  break;
764  }
765 
766  m_dlg_open_fuse->hide();
767 }
768 
769 void
770 Firestation::pre_open_img_src()
771 {
772  if (SRC_NONE != m_img_src)
773  {
774  m_camera->stop();
775  m_camera->close();
776 
777  delete m_camera;
778  m_camera = 0;
779 
780  m_img_src = SRC_NONE;
781  }
782 }
783 
784 /** Stuff that is executed after an image source has been selected. */
785 void
786 Firestation::post_open_img_src()
787 {
788  if (m_img_src == SRC_NONE) { return; }
789 
790  try
791  {
792  m_camera->open();
793  m_camera->start();
794  m_camera->capture();
795  m_img_width = m_camera->pixel_width();
796  m_img_height = m_camera->pixel_height();
797  m_img_cs = m_camera->colorspace();
798 
799  m_img_size = colorspace_buffer_size( m_img_cs,
800  m_img_width,
801  m_img_height );
802 
803  m_yuv_orig_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
804  m_yuv_draw_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
805 
806  convert(m_img_cs, YUV422_PLANAR,
807  m_camera->buffer(), m_yuv_orig_buffer,
808  m_img_width, m_img_height);
809  memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer,
810  colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
811 
812  m_camera->dispose_buffer();
813 
814  m_tbtn_update->set_sensitive(true);
815  m_tbtn_save->set_sensitive(true);
816 
817  draw_image();
818 
819  m_ctw->set_src_buffer(m_yuv_orig_buffer, m_img_width, m_img_height);
820  m_ctw->set_draw_buffer(m_yuv_draw_buffer);
821  m_ctw->draw_segmentation_result();
822 
823  mc_draw_line();
824  }
825  catch (Exception& e)
826  {
827  e.print_trace();
828  printf("Opening camera failed.\n");
829  }
830 
831 }
832 
833 void
834 Firestation::on_fuse_image_selected()
835 {
836  string host_name;
837  unsigned short port;
838  string image_id;
839  bool compression;
840 
841  m_filw->get_selected_image(host_name, port, image_id, compression);
842 
843  pre_open_img_src();
844 
845  try
846  {
847  m_camera = new NetworkCamera( host_name.c_str(), port, image_id.c_str(), compression );
848  m_img_src = SRC_FUSE;
849  }
850  catch (Exception& e)
851  {
852  m_img_src = SRC_NONE;
853  e.print_trace();
854  }
855 
856  post_open_img_src();
857 }
858 
859 void
860 Firestation::on_colormap_updated()
861 {
862  m_ftw->set_current_colormap( m_ctw->get_colormap() );
863 }
864 
865 /** Draws the image. */
866 void
867 Firestation::draw_image()
868 {
869  if ( m_img_src == SRC_NONE ) { return; }
870 
871  LossyScaler scaler;
872  scaler.set_original_buffer( m_yuv_draw_buffer );
873  scaler.set_original_dimensions(m_img_width, m_img_height);
874  scaler.set_scaled_dimensions(m_max_img_width, m_max_img_height);
875 
876  unsigned int scaled_width = scaler.needed_scaled_width();
877  unsigned int scaled_height = scaler.needed_scaled_height();
878 
879  if (scaled_width != m_scaled_img_width || scaled_height != m_scaled_img_height)
880  {
881  m_scaled_img_width = scaled_width;
882  m_scaled_img_height = scaled_height;
883  m_scale_factor = scaler.get_scale_factor();
884  }
885 
886  if (m_rgb_scaled_buffer) free(m_rgb_scaled_buffer);
887  if (m_yuv_scaled_buffer) free(m_yuv_scaled_buffer);
888  m_yuv_scaled_buffer = malloc_buffer(YUV422_PLANAR, m_scaled_img_width,
889  m_scaled_img_height);
890  scaler.set_scaled_buffer(m_yuv_scaled_buffer);
891  scaler.scale();
892 
893  if (m_btn_ct_seg->get_active()) {
894  unsigned int sld_img_size = m_scaled_img_width * m_scaled_img_height;
895  unsigned char u_seg = 255 / (unsigned int)pow(2, m_spbtn_width->get_value());
896  unsigned char v_seg = 255 / (unsigned int)pow(2, m_spbtn_height->get_value());
897  unsigned int u = 0;
898  for (u = sld_img_size; u < sld_img_size + sld_img_size / 2; ++u) {
899  m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / u_seg) * u_seg;
900  }
901 
902  for (; u < 2 * sld_img_size; ++u) {
903  m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / v_seg) * v_seg;
904  }
905  }
906 
907  if ( m_img_src == SRC_SHM )
908  {
909  SharedMemoryCamera* shm_camera = dynamic_cast<SharedMemoryCamera*>(m_camera);
910  if ( shm_camera->shared_memory_image_buffer()->circle_found() )
911  {
912  Drawer drawer;
913  drawer.set_buffer(m_yuv_scaled_buffer, m_scaled_img_width, m_scaled_img_height);
914  drawer.set_color(YUV_t::white());
915  unsigned int roi_x = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_x() * m_scale_factor );
916  unsigned int roi_y = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_y() * m_scale_factor );
917  unsigned int roi_width = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_width() * m_scale_factor );
918  unsigned int roi_height = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_height() * m_scale_factor );
919  drawer.draw_rectangle( roi_x, roi_y, roi_width, roi_height );
920  }
921  }
922 
923  m_rgb_scaled_buffer = (unsigned char*) malloc( colorspace_buffer_size( RGB,
924  m_scaled_img_width,
925  m_scaled_img_height ) );
926 
927  convert( YUV422_PLANAR, RGB,
928  m_yuv_scaled_buffer, m_rgb_scaled_buffer,
929  m_scaled_img_width, m_scaled_img_height );
930 
931  Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_data( m_rgb_scaled_buffer,
932  Gdk::COLORSPACE_RGB,
933  false,
934  8,
935  m_scaled_img_width,
936  m_scaled_img_height,
937  3 * m_scaled_img_width );
938 
939  m_img_image->set(image);
940 }
941 
942 /** Signal handler that is called whenever the window size is changed.
943  * @param allocation a Gtk allocation
944  */
945 void
946 Firestation::resize_image(Gtk::Allocation& allocation)
947 {
948  unsigned int new_width = (unsigned int) allocation.get_width();
949  unsigned int new_height = (unsigned int) allocation.get_height();
950 
951  if (new_width != m_max_img_width || new_height != m_max_img_height)
952  {
953  m_max_img_width = new_width;
954  m_max_img_height = new_height;
955  draw_image();
956  }
957 }
958 
959 /** Handles mouse clicks in the image area.
960  * @param event a Gtk event
961  * @return true if signal was handled
962  */
963 bool
964 Firestation::image_click(GdkEventButton* event)
965 {
966  unsigned int offset_x;
967  unsigned int offset_y;
968 
969  offset_x = (m_max_img_width - m_scaled_img_width) / 2;
970  offset_y = (m_max_img_height - m_scaled_img_height) / 2;
971 
972  offset_x = offset_x > m_max_img_width ? 0 : offset_x;
973  offset_y = offset_y > m_max_img_height ? 0 : offset_y;
974 
975  unsigned int image_x;
976  unsigned int image_y;
977 
978  if (event != NULL) {
979  image_x = (unsigned int)rint( (event->x - offset_x) / m_scale_factor);
980  image_y = (unsigned int)rint( (event->y - offset_y) / m_scale_factor);
981  } else {
982  image_x = 0;
983  image_y = 0;
984  }
985 
986  if ( image_x > m_img_width || image_y > m_img_height )
987  { return true; }
988 
989  switch (m_op_mode)
990  {
991  case MODE_VIEWER:
992  if (m_img_src != SRC_NONE)
993  {
994  register unsigned char y;
995  register unsigned char u;
996  register unsigned char v;
997  YUV422_PLANAR_YUV( m_yuv_orig_buffer,
998  m_img_width,
999  m_img_height,
1000  image_x,
1001  image_y,
1002  y, u, v );
1003  printf( "Y=%d U=%d Y=%d @ (%d, %d)\n",
1004  (unsigned int) y, (unsigned int) u, (unsigned int) v,
1005  image_x, image_y );
1006  }
1007  break;
1008 
1009  case MODE_COLOR_TRAIN:
1010  m_ctw->click(image_x, image_y, event->button);
1011  draw_image();
1012  break;
1013 
1014  case MODE_MIRROR_CALIB:
1015  {
1016 #ifdef HAVE_MIRROR_CALIB
1017  if (m_btn_mc_set_center->get_active()) {
1018  m_calib_tool->set_center(image_x, image_y);
1019  m_btn_mc_set_center->set_active(false);
1020  mc_draw_line();
1021  printf("Setting center to %d, %d\n", image_x, image_y);
1022  } else {
1023  printf("Using center to %d, %d\n", m_calib_tool->center_x(), m_calib_tool->center_y());
1024  m_calib_tool->next_step();
1025  const unsigned char* last_yuv = m_calib_tool->get_last_yuv_buffer();
1026  memcpy(m_yuv_draw_buffer, last_yuv, m_img_size);
1027  memcpy(m_yuv_orig_buffer, last_yuv, m_img_size);
1028  m_calib_tool->draw_mark_lines(m_yuv_draw_buffer);
1029  draw_image();
1030  m_stb_status->push(m_calib_tool->get_state_description());
1031  }
1032 #else
1033  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1034 #endif
1035  break;
1036  }
1037 
1038  case MODE_MIRROR_CALIB_EVAL:
1039  {
1040 #ifdef HAVE_MIRROR_CALIB
1041  float dist;
1042  float phi;
1043  m_calib_tool->eval(image_x, image_y, &dist, &phi);
1044  phi = normalize_mirror_rad(phi);
1045  printf("(%d, %d) = POLAR(%.2f deg, %.2f meters)\n",
1046  image_x, image_y,
1047  rad2deg(phi), dist);
1048  //printf("Distance: %2f\t Phi: %2f\n", dist, phi);
1049 #else
1050  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1051 #endif
1052  break;
1053  }
1054 
1055  default:
1056  break;
1057  }
1058 
1059  return true;
1060 }
1061 
1062 /** Starts the color training. */
1063 void
1064 Firestation::ct_start()
1065 {
1066  if (m_op_mode == MODE_COLOR_TRAIN)
1067  {
1068  m_op_mode = MODE_VIEWER;
1069  m_stb_status->push("Leaving color training mode");
1070  }
1071  else
1072  {
1073  if (m_img_src != SRC_NONE)
1074  {
1075  m_ctw->set_fg_object( ct_get_fg_object() );
1076 
1077  m_op_mode = MODE_COLOR_TRAIN;
1078 
1079  m_stb_status->push("Entering color training mode");
1080  }
1081  }
1082 }
1083 
1084 hint_t
1085 Firestation::ct_get_fg_object()
1086 {
1087  int active = m_cmb_ct_type->get_active_row_number();
1088  switch(active)
1089  {
1090  case 0: //Ball
1091  return H_BALL;
1092 
1093  case 1: //Field
1094  return H_FIELD;
1095 
1096  case 2: //Lines
1097  return H_LINE;
1098 
1099  case 3: //Robot (Team A or all)
1100  return H_ROBOT;
1101 
1102  case 4: //Robot (Team B)
1103  return H_ROBOT_OPP;
1104 
1105  case 5: //Goal (yellow)
1106  return H_GOAL_YELLOW;
1107 
1108  case 6: //Goal (sky-blue)
1109  return H_GOAL_BLUE;
1110 
1111  case 7: //Background
1112  return H_UNKNOWN;
1113 
1114  default:
1115  printf("ct_get_fg_object(): UNKNOWN\n");
1116  return H_UNKNOWN;
1117  }
1118 }
1119 
1120 void
1121 Firestation::ct_object_changed()
1122 {
1123  hint_t object = ct_get_fg_object();
1124  m_ctw->set_fg_object(object);
1125 }
1126 
1127 void
1128 Firestation::mc_draw_line()
1129 {
1130  if (m_img_src != SRC_NONE) {
1131 #ifdef HAVE_MIRROR_CALIB
1132  memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer, m_img_size);
1133  MirrorCalibTool::draw_line(m_yuv_draw_buffer,
1134  mc_line_angle_deg,
1135  m_calib_tool->center_x(),
1136  m_calib_tool->center_y(),
1137  m_img_width,
1138  m_img_height);
1139  draw_image();
1140 #else
1141  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1142 #endif
1143  }
1144 }
1145 
1146 bool
1147 Firestation::mc_on_line_angle_changed(Gtk::ScrollType scroll, double value)
1148 {
1149  mc_line_angle_deg = -1.0f * value;
1150  mc_line_angle_deg =
1151  rad2deg(normalize_mirror_rad(deg2rad(mc_line_angle_deg)));
1152  // Why -1.0f * value?
1153  // We want to display angles from the robot's real-world perspective.
1154  // We want to calculate with angles from the (mirrored!) image's perspective.
1155  // So when the user chooses 90 degrees, he wants to look to the left from the
1156  // robots perspective. But due to the mirroring, that's the right side in the
1157  // image, so we take -90 degrees.
1158  mc_draw_line();
1159  return true;
1160 }
1161 
1162 void
1163 Firestation::mc_load_mask()
1164 {
1165  m_fcd_mc_load_mask->set_transient_for(*this);
1166 
1167 #if GTK_VERSION_GE(3,0)
1168  Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1169 #else
1170  Gtk::FileFilter *filter_mirror = Gtk::manage(new Gtk::FileFilter());
1171 #endif
1172  filter_mirror->set_name("Robot Mask");
1173  filter_mirror->add_pattern("*.pnm");
1174 #if GTK_VERSION_GE(3,0)
1175  m_fcd_mc_load_mask->add_filter(filter_mirror);
1176 #else
1177  m_fcd_mc_load_mask->add_filter(*filter_mirror);
1178 #endif
1179 
1180  int result = m_fcd_mc_load_mask->run();
1181 
1182  switch(result)
1183  {
1184  case Gtk::RESPONSE_OK:
1185  {
1186 #ifdef HAVE_MIRROR_CALIB
1187  std::string filename = m_fcd_mc_load_mask->get_filename();
1188  m_calib_tool->load_mask( filename.c_str() );
1189  //m_op_mode = MODE_MIRROR_CALIB_EVAL;
1190 #else
1191  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1192 #endif
1193  break;
1194  }
1195  case Gtk::RESPONSE_CANCEL:
1196  break;
1197  default:
1198  break;
1199  }
1200 
1201  m_fcd_mc_load_mask->hide();
1202 }
1203 
1204 /** Enters MODE_MIRROR_CALIB mode which waits for a click to mark the
1205  * preliminary center of the image. */
1206 void
1207 Firestation::mc_set_center()
1208 {
1209  m_op_mode = MODE_MIRROR_CALIB;
1210 }
1211 
1212 /** Start the mirror calibration process. */
1213 void
1214 Firestation::mc_memorize()
1215 {
1216  /* if (m_op_mode == MODE_MIRROR_CALIB)
1217  {
1218  m_op_mode = MODE_VIEWER;
1219  m_stb_status->push("Leaving mirror calibration mode");
1220  }
1221  else */ if (m_img_src != SRC_NONE)
1222  {
1223 #ifdef HAVE_MIRROR_CALIB
1224  double ori = mc_line_angle_deg;
1225  std::cout << "Starting calibration for ori = " << ori << std::endl;
1226  m_calib_tool->push_back(m_yuv_orig_buffer, m_img_size,
1227  m_img_width, m_img_height, deg2rad(ori));
1228  m_op_mode = MODE_MIRROR_CALIB;
1229  std::cout << "Initialization for ori = " << ori << " completed" << std::endl;
1230 
1231  mc_line_angle_deg -= 120.0;
1232  mc_line_angle_deg =
1233  rad2deg(normalize_mirror_rad(deg2rad(mc_line_angle_deg)));
1234  m_scl_mc_line->set_value(-1.0f * mc_line_angle_deg);
1235  // Why -1.0f * mc_line_angle_deg?
1236  // We want to display angles from the robot's real-world perspective.
1237  // We want to calculate with angles from the (mirrored!) image's perspective.
1238  // So when the user chooses 90 degrees, he wants to look to the left from the
1239  // robots perspective. But due to the mirroring, that's the right side in the
1240  // image, so we take -90 degrees.
1241  mc_draw_line();
1242 #else
1243  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1244 #endif
1245  }
1246 }
1247 
1248 /** Start the mirror calibration process. */
1249 void
1250 Firestation::mc_simulate_clicks()
1251 {
1252  for (int i = 1; i <= 3; ++i) {
1253  image_click(NULL); // SHARPENING
1254  for (int j = 1; j <= 8; ++j) { image_click(NULL); } // EDGE_DETECTION
1255  for (int j = 1; j <= 2*8; ++j) { image_click(NULL); } // COMBINATION
1256  image_click(NULL); // PRE_MARKING
1257  image_click(NULL); // FINAL_MARKING
1258  }
1259 }
1260 
1261 /** Load mirror calibration data from a file. */
1262 void
1263 Firestation::mc_load()
1264 {
1265  m_fcd_mc_load->set_transient_for(*this);
1266 
1267 #if GTK_VERSION_GE(3,0)
1268  Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1269 #else
1270  Gtk::FileFilter *filter_mirror = Gtk::manage(new Gtk::FileFilter());
1271 #endif
1272  filter_mirror->set_name("Mirror Calibration");
1273  filter_mirror->add_pattern("*.mirror");
1274  filter_mirror->add_pattern("*.bulb");
1275 #if GTK_VERSION_GE(3,0)
1276  m_fcd_mc_load->add_filter(filter_mirror);
1277 #else
1278  m_fcd_mc_load->add_filter(*filter_mirror);
1279 #endif
1280 
1281  int result = m_fcd_mc_load->run();
1282 
1283  switch(result)
1284  {
1285  case Gtk::RESPONSE_OK:
1286  {
1287 #ifdef HAVE_MIRROR_CALIB
1288  std::string filename = m_fcd_mc_load->get_filename();
1289  m_calib_tool->load( filename.c_str() );
1290  m_op_mode = MODE_MIRROR_CALIB_EVAL;
1291 #else
1292  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1293 #endif
1294  break;
1295  }
1296  case Gtk::RESPONSE_CANCEL:
1297  break;
1298  default:
1299  break;
1300  }
1301 
1302  m_fcd_mc_load->hide();
1303 }
1304 
1305 /** Save calibration data to a file. */
1306 void
1307 Firestation::mc_save()
1308 {
1309  m_fcd_mc_save->set_transient_for(*this);
1310 
1311  int result = m_fcd_mc_save->run();
1312 
1313  switch(result)
1314  {
1315  case(Gtk::RESPONSE_OK):
1316  {
1317 #ifdef HAVE_MIRROR_CALIB
1318  std::string filename = m_fcd_mc_save->get_filename();
1319 
1320  m_calib_tool->save( filename.c_str() );
1321 #else
1322  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1323 #endif
1324  break;
1325  }
1326 
1327  case(Gtk::RESPONSE_CANCEL):
1328  break;
1329 
1330  default:
1331  break;
1332  }
1333 
1334  m_fcd_mc_save->hide();
1335 
1336 }
1337 
1338 void
1339 Firestation::on_service_added( NetworkService* service )
1340 {
1341  const char* host = service->host();
1342  const char* name = service->name();
1343  const char* type = service->type();
1344  const char* domain = service->domain();
1345  unsigned short int port = service->port();
1346 
1347  std::vector<FUSE_imageinfo_t> image_list;
1348  NetworkCamera cam(host, port);
1349  try
1350  {
1351  cam.open();
1352  cam.start();
1353  image_list = cam.image_list();
1354  }
1355  catch (Exception& e)
1356  {
1357  e.append("Could not open camera on %s:%d", host, port);
1358  e.print_trace();
1359  return;
1360  }
1361  cam.close();
1362 
1363 #ifdef DEBUG_PRINT
1364  printf("%zu images available on host %s.\n", image_list.size(), host);
1365 #endif /* DEBUG_PRINT */
1366 
1367  std::vector<FUSE_imageinfo_t>::iterator fit;
1368 
1369  Gtk::TreeModel::Children children = m_fuse_tree_store->children();
1370  Gtk::TreeModel::Row row = *(m_fuse_tree_store->append());
1371  row[m_fuse_columns.m_id] = children.size();
1372  row[m_fuse_columns.m_name] = Glib::ustring(name);
1373  row[m_fuse_columns.m_service_name] = Glib::ustring(name);
1374  row[m_fuse_columns.m_service_type] = Glib::ustring(type);
1375  row[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1376  row[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1377  row[m_fuse_columns.m_service_port] = port;
1378 
1379  for (fit = image_list.begin(); fit != image_list.end(); ++fit)
1380  {
1381  Gtk::TreeModel::Row childrow = *(m_fuse_tree_store->append(row.children()));
1382  childrow[m_fuse_columns.m_name] = Glib::ustring(fit->image_id);
1383  childrow[m_fuse_columns.m_service_name] = Glib::ustring(name);
1384  childrow[m_fuse_columns.m_service_type] = Glib::ustring(type);
1385  childrow[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1386  childrow[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1387  childrow[m_fuse_columns.m_service_port] = port;
1388  childrow[m_fuse_columns.m_image_id] = Glib::ustring(fit->image_id);
1389  childrow[m_fuse_columns.m_image_width] = fit->width;
1390  childrow[m_fuse_columns.m_image_height] = fit->height;
1391  childrow[m_fuse_columns.m_image_colorspace] = Glib::ustring( colorspace_to_string((colorspace_t) fit->colorspace) );
1392  }
1393 
1394  m_ftw->add_fountain_service(name, host, port);
1395  m_filw->add_fountain_service(name, host, port);
1396 }
1397 
1398 void
1399 Firestation::on_service_removed( NetworkService* service )
1400 {
1401  const char* name = service->name();
1402  const char* type = service->type();
1403  const char* domain = service->domain();
1404 
1405  Gtk::TreeModel::Children children = m_fuse_tree_store->children();
1406  Gtk::TreeModel::iterator rit;
1407  for (rit = children.begin(); rit != children.end(); ++rit)
1408  {
1409  Glib::ustring n = (*rit)[m_fuse_columns.m_service_name];
1410  Glib::ustring t = (*rit)[m_fuse_columns.m_service_type];
1411  Glib::ustring d = (*rit)[m_fuse_columns.m_service_domain];
1412 
1413  if ( strcmp( n.c_str(), name) == 0 &&
1414  strcmp( t.c_str(), type) == 0 &&
1415  strcmp( d.c_str(), domain) == 0 )
1416  {
1417  m_fuse_tree_store->erase(rit);
1418  }
1419  }
1420 
1421  m_ftw->remove_fountain_service(name);
1422  m_filw->remove_fountain_service(name);
1423 }
virtual float get_scale_factor()
Returns the scale factor.
Definition: lossy.cpp:147
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
Definition: lossy.cpp:140
Shared memory image buffer header.
Definition: shm_image.h:69
virtual std::vector< FUSE_imageinfo_t > & image_list()
List the available images.
Definition: net.cpp:429
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
Definition: lossy.cpp:126
virtual ~Firestation()
Destructor.
unsigned int roi_y() const
Get ROI Y.
Definition: shm_image.cpp:285
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
Definition: lossy.cpp:119
Avahi dispatcher.
This widget displays all available Fuse images in a tree view.
This class implements the logic for a GUI that allows to transfer LUTs via FUSE.
Fawkes library namespace.
Shared Memory iterator.
Definition: shm.h:114
const char * host() const
Get host of service.
Definition: service.cpp:368
STL namespace.
Draw to an image.
Definition: drawer.h:34
virtual void open()
Open the camera.
Definition: net.cpp:196
Camera argument parser.
Definition: camargp.h:38
unsigned short int port() const
Get port of service.
Definition: service.cpp:378
Lossy image scaler.
Definition: lossy.h:35
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
Definition: angle.h:75
bool circle_found() const
Check if circle was found .
Definition: shm_image.cpp:483
unsigned int roi_width() const
Get ROI width.
Definition: shm_image.cpp:295
FvRaw Writer implementation.
Definition: fvraw.h:34
Base class for exceptions in Fawkes.
Definition: exception.h:36
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
Definition: drawer.cpp:62
const char * image_id() const
Get image number.
Definition: shm_image.cpp:881
virtual void start()
Start image transfer from the camera.
Definition: net.cpp:219
JPEG file writer.
Definition: jpeg.h:36
Gtk::Window & get_window() const
Returns reference to main window.
Shared memory camera.
Definition: shmem.h:38
void draw_rectangle(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Draw rectangle.
Definition: drawer.cpp:212
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
Definition: lossy.cpp:83
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
Definition: lossy.cpp:92
Avahi main thread.
Definition: avahi_thread.h:54
Representation of a service announced or found via service discovery (i.e.
Definition: service.h:37
float rad2deg(float rad)
Convert an angle given in radians to degrees.
Definition: angle.h:48
virtual void close()
Close camera.
Definition: net.cpp:311
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
SharedMemoryImageBuffer * shared_memory_image_buffer()
Get the shared memory image buffer.
Definition: shmem.cpp:236
unsigned int roi_x() const
Get ROI X.
Definition: shm_image.cpp:275
This class encapsulates the routines necessary for interactive mirror calibration.
Definition: mirror_calib.h:43
const char * domain() const
Get domain of service.
Definition: service.cpp:358
This widget implements the complete color training process.
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
Definition: lossy.cpp:133
Network camera.
Definition: net.h:42
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:37
virtual void scale()
Scale image.
Definition: lossy.cpp:153
sigc::signal< void, NetworkService * > signal_service_added()
Get "service added" signal.
const char * type() const
Get type of service.
Definition: service.cpp:348
unsigned int roi_height() const
Get ROI height.
Definition: shm_image.cpp:305
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
Definition: drawer.cpp:77
Load images from files.
Definition: fileloader.h:39
const char * name() const
Get name of service.
Definition: service.cpp:312
Firestation(Glib::RefPtr< Gtk::Builder > builder)
Constructor.
Definition: firestation.cpp:69