22 #include "firestation.h"
24 #include "color_train_widget.h"
25 #include "fuse_transfer_widget.h"
27 #include <fvcams/fileloader.h>
28 #include <fvcams/net.h>
29 #include <fvcams/shmem.h>
30 #include <fvwidgets/fuse_image_list_widget.h>
31 #include <gui_utils/avahi_dispatcher.h>
32 #include <utils/math/angle.h>
34 #ifdef HAVE_MIRROR_CALIB
35 # include <fvmodels/mirror/mirror_calib.h>
38 #include <arpa/inet.h>
39 #include <core/exception.h>
40 #include <fvutils/color/conversions.h>
41 #include <fvutils/color/yuv.h>
42 #include <fvutils/colormap/yuvcm.h>
43 #include <fvutils/draw/drawer.h>
44 #include <fvutils/ipc/shm_image.h>
45 #include <fvutils/scalers/lossy.h>
46 #include <fvutils/system/camargp.h>
47 #include <fvutils/writers/fvraw.h>
48 #include <fvutils/writers/jpeg.h>
49 #include <gdkmm/pixbuf.h>
55 using namespace firevision;
68 builder->get_widget(
"wndMain", m_wnd_main);
69 builder->get_widget(
"imgImage", m_img_image);
70 builder->get_widget(
"evtImageEventBox", m_evt_image);
71 builder->get_widget(
"trvShmImageIds", m_trv_shm_image_ids);
72 builder->get_widget(
"stbStatus", m_stb_status);
73 builder->get_widget(
"ckbContTrans", m_ckb_cont_trans);
74 builder->get_widget(
"spbUpdateTime", m_spb_update_time);
76 m_img_image->signal_size_allocate().connect(sigc::mem_fun(*
this, &Firestation::resize_image));
77 m_evt_image->signal_button_press_event().connect(sigc::mem_fun(*
this, &Firestation::image_click));
78 m_ckb_cont_trans->signal_toggled().connect(
79 sigc::mem_fun(*
this, &Firestation::enable_cont_img_trans));
84 builder->get_widget(
"tbtnExit", m_tbtn_exit);
85 builder->get_widget(
"tbtnCloseCamera", m_tbtn_close_camera);
86 builder->get_widget(
"tbtnUpdate", m_tbtn_update);
87 builder->get_widget(
"tbtnSave", m_tbtn_save);
88 builder->get_widget(
"tbtnOpenFile", m_tbtn_open_file);
89 builder->get_widget(
"tbtnOpenFolder", m_tbtn_open_folder);
90 builder->get_widget(
"tbtnOpenShm", m_tbtn_open_shm);
91 builder->get_widget(
"tbtnOpenFuse", m_tbtn_open_fuse);
93 m_tbtn_exit->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::exit));
94 m_tbtn_close_camera->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::close_camera));
95 m_tbtn_update->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::update_image));
96 m_tbtn_save->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::save_image));
97 m_tbtn_open_file->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::open_file));
98 m_tbtn_open_folder->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::open_folder));
99 m_tbtn_open_shm->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::open_shm));
100 m_tbtn_open_fuse->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::open_fuse));
104 builder->get_widget(
"fcdOpenImage", m_fcd_open_image);
105 builder->get_widget(
"fcdSaveImage", m_fcd_save_image);
106 builder->get_widget(
"dlgOpenShm", m_dlg_open_shm);
107 builder->get_widget(
"trvShmImageIds", m_trv_shm_image_ids);
108 builder->get_widget(
"dlgOpenFuse", m_dlg_open_fuse);
109 builder->get_widget(
"ckbFuseJpeg", m_ckb_fuse_jpeg);
110 builder->get_widget(
"trvFuseServices", m_trv_fuse_services);
112 #if GTK_VERSION_GE(3, 0)
113 Glib::RefPtr<Gtk::FileFilter> filter_jpg = Gtk::FileFilter::create();
115 Gtk::FileFilter *filter_jpg = Gtk::manage(
new Gtk::FileFilter());
117 filter_jpg->set_name(
"JPEG");
118 filter_jpg->add_pattern(
"*.jpg");
119 filter_jpg->add_pattern(
"*.jpeg");
121 #if GTK_VERSION_GE(3, 0)
122 Glib::RefPtr<Gtk::FileFilter> filter_fvraw = Gtk::FileFilter::create();
124 Gtk::FileFilter *filter_fvraw = Gtk::manage(
new Gtk::FileFilter());
126 filter_fvraw->set_name(
"FVRaw");
127 filter_fvraw->add_pattern(
"*.raw");
128 filter_fvraw->add_pattern(
"*.fvraw");
130 #if GTK_VERSION_GE(3, 0)
131 m_fcd_open_image->add_filter(filter_jpg);
132 m_fcd_open_image->add_filter(filter_fvraw);
134 m_fcd_save_image->add_filter(filter_jpg);
135 m_fcd_save_image->add_filter(filter_fvraw);
138 m_fcd_open_image->add_filter(*filter_jpg);
139 m_fcd_open_image->add_filter(*filter_fvraw);
141 m_fcd_save_image->add_filter(*filter_jpg);
142 m_fcd_save_image->add_filter(*filter_fvraw);
145 m_shm_list_store = Gtk::ListStore::create(m_shm_columns);
146 m_trv_shm_image_ids->set_model(m_shm_list_store);
147 m_trv_shm_image_ids->append_column(
"#", m_shm_columns.m_id);
148 m_trv_shm_image_ids->append_column(
"Name", m_shm_columns.m_name);
150 m_fuse_tree_store = Gtk::TreeStore::create(m_fuse_columns);
151 m_trv_fuse_services->set_model(m_fuse_tree_store);
153 m_trv_fuse_services->append_column(
"Name", m_fuse_columns.m_name);
158 builder->get_widget(
"cmbCtObjectType", m_cmb_ct_type);
159 builder->get_widget(
"btnCtStart", m_btn_ct_start);
160 builder->get_widget(
"btnCtSeg", m_btn_ct_seg);
161 builder->get_widget(
"spbtnCtCmDepth", m_spbtn_depth);
162 builder->get_widget(
"spbtnCtCmWidth", m_spbtn_width);
163 builder->get_widget(
"spbtnCtCmHeight", m_spbtn_height);
165 m_cmb_ct_type->signal_changed().connect(sigc::mem_fun(*
this, &Firestation::ct_object_changed));
166 m_cmb_ct_type->set_active(0);
168 m_btn_ct_start->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::ct_start));
170 m_ctw->update_image().connect(sigc::mem_fun(*
this, &Firestation::draw_image));
171 m_ctw->colormap_updated().connect(sigc::mem_fun(*
this, &Firestation::on_colormap_updated));
174 builder->get_widget(
"btnCtUnselect", btn);
175 m_ctw->set_reset_selection_btn(btn);
177 builder->get_widget(
"btnCtAdd", btn);
178 m_ctw->set_add_to_colormap_btn(btn);
180 builder->get_widget(
"btnCtReset", btn);
181 m_ctw->set_reset_colormap_btn(btn);
183 builder->get_widget(
"btnCtSaveHistos", btn);
184 m_ctw->set_save_histos_btn(btn);
186 builder->get_widget(
"btnCtLoadHistos", btn);
187 m_ctw->set_load_histos_btn(btn);
189 builder->get_widget(
"btnCtSaveColormap", btn);
190 m_ctw->set_save_colormap_btn(btn);
192 builder->get_widget(
"btnCtLoadColormap", btn);
193 m_ctw->set_load_colormap_btn(btn);
196 builder->get_widget(
"sclCtThreshold", scl);
197 m_ctw->set_threshold_scl(scl);
199 builder->get_widget(
"sclCtMinProb", scl);
200 m_ctw->set_min_prob_scl(scl);
202 builder->get_widget(
"sclCtLayerSelector", scl);
203 m_ctw->set_cm_layer_selector(scl);
206 builder->get_widget(
"imgCtSegmentation", img);
207 m_ctw->set_segmentation_img(img);
209 builder->get_widget(
"imgCtColormap", img);
210 m_ctw->set_colormap_img(img);
212 Gtk::FileChooserDialog *fcd;
213 builder->get_widget(
"fcdFilechooser", fcd);
214 m_ctw->set_filechooser_dlg(fcd);
216 m_btn_ct_seg->signal_toggled().connect(sigc::mem_fun(*
this, &Firestation::draw_image));
217 m_ctw->set_cm_selector(m_spbtn_depth, m_spbtn_width, m_spbtn_height);
221 #ifdef HAVE_MIRROR_CALIB
225 #ifndef HAVE_MIRROR_CALIB
228 builder->get_widget(
"ntbOptions", nb);
229 builder->get_widget(
"boxMirrorCalib", box);
230 nb->get_tab_label(*box)->set_sensitive(
false);
231 box->set_sensitive(
false);
234 builder->get_widget(
"sclMcLine", m_scl_mc_line);
235 m_scl_mc_line->signal_change_value().connect(
236 sigc::mem_fun(*
this, &Firestation::mc_on_line_angle_changed));
238 builder->get_widget(
"btnMcLoadMask", m_btn_mc_load_mask);
239 m_btn_mc_load_mask->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::mc_load_mask));
242 builder->get_widget(
"btnCalibLoad", m_btn_mc_load);
243 builder->get_widget(
"btnCalibSave", m_btn_mc_save);
244 builder->get_widget(
"entCalibDist", m_ent_mc_dist);
245 builder->get_widget(
"entCalibOri", m_ent_mc_ori);
246 builder->get_widget(
"fcdCalibSave", m_fcd_mc_save);
247 builder->get_widget(
"fcdCalibLoad", m_fcd_mc_load);
250 m_btn_mc_load->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::mc_load));
251 m_btn_mc_save->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::mc_save));
253 builder->get_widget(
"btnMcSetCenter", m_btn_mc_set_center);
254 m_btn_mc_set_center->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::mc_set_center));
256 builder->get_widget(
"btnMcMemorize", m_btn_mc_memorize);
257 m_btn_mc_memorize->signal_clicked().connect(sigc::mem_fun(*
this, &Firestation::mc_memorize));
259 builder->get_widget(
"btnMcSimulateClicks", m_btn_mc_simulate_clicks);
260 m_btn_mc_simulate_clicks->signal_clicked().connect(
261 sigc::mem_fun(*
this, &Firestation::mc_simulate_clicks));
263 builder->get_widget(
"entCalibDist", m_ent_mc_dist);
264 builder->get_widget(
"entCalibOri", m_ent_mc_ori);
267 builder->get_widget(
"fcdMcLoadMask", m_fcd_mc_load_mask);
268 builder->get_widget(
"fcdCalibSave", m_fcd_mc_save);
269 builder->get_widget(
"fcdCalibLoad", m_fcd_mc_load);
276 builder->get_widget(
"trvFuseRemoteLuts", trv);
277 m_ftw->set_remote_lut_list_trv(trv);
278 builder->get_widget(
"trvFuseLocalLuts", trv);
279 m_ftw->set_local_lut_list_trv(trv);
280 builder->get_widget(
"imgFuseLocal", img);
281 m_ftw->set_local_img(img);
282 builder->get_widget(
"imgFuseRemote", img);
283 m_ftw->set_remote_img(img);
284 builder->get_widget(
"btnFuseUpload", btn);
285 m_ftw->set_upload_btn(btn);
286 builder->get_widget(
"sclLocalLayerSelector", scl);
287 m_ftw->set_local_layer_selector(scl);
288 builder->get_widget(
"sclRemoteLayerSelector", scl);
289 m_ftw->set_remote_layer_selector(scl);
294 builder->get_widget(
"trvFuseImageList", trv);
295 m_filw->set_image_list_trv(trv);
296 Gtk::CheckButton *chk;
297 builder->get_widget(
"chkFuseImageListUpdate", chk);
298 m_filw->set_auto_update_chk(chk);
299 builder->get_widget(
"chkFuseCompression", chk);
300 m_filw->set_toggle_compression_chk(chk);
301 m_filw->image_selected().connect(sigc::mem_fun(*
this, &Firestation::on_fuse_image_selected));
304 m_yuv_orig_buffer = 0;
305 m_yuv_draw_buffer = 0;
306 m_yuv_scaled_buffer = 0;
307 m_rgb_scaled_buffer = 0;
312 m_img_cs = CS_UNKNOWN;
318 m_img_src = SRC_NONE;
319 m_op_mode = MODE_VIEWER;
321 m_cont_img_trans =
false;
323 mc_line_angle_deg = 0.0;
325 m_max_img_width = m_evt_image->get_width();
326 m_max_img_height = m_evt_image->get_height();
327 m_scaled_img_width = m_evt_image->get_width();
328 m_scaled_img_height = m_evt_image->get_height();
329 m_scale_factor = 1.0;
335 sigc::mem_fun(*
this, &Firestation::on_service_added));
336 m_avahi_dispatcher->signal_service_removed().connect(
337 sigc::mem_fun(*
this, &Firestation::on_service_removed));
339 m_avahi_thread->watch_service(
"_fountain._tcp", m_avahi_dispatcher);
340 m_avahi_thread->start();
346 if (m_yuv_orig_buffer)
347 free(m_yuv_orig_buffer);
348 if (m_yuv_draw_buffer)
349 free(m_yuv_draw_buffer);
350 if (m_yuv_scaled_buffer)
351 free(m_yuv_scaled_buffer);
352 if (m_rgb_scaled_buffer)
353 free(m_rgb_scaled_buffer);
358 #ifdef HAVE_MIRROR_CALIB
365 m_avahi_thread->cancel();
366 m_avahi_thread->join();
367 delete m_avahi_thread;
368 delete m_avahi_dispatcher;
371 delete m_fcd_open_image;
372 delete m_fcd_save_image;
373 delete m_dlg_open_shm;
374 delete m_dlg_open_fuse;
390 if (SRC_NONE != m_img_src) {
398 Firestation::close_camera()
400 if (SRC_NONE == m_img_src) {
404 m_img_src = SRC_NONE;
412 m_img_cs = CS_UNKNOWN;
416 m_img_image->clear();
417 m_img_image->set(
"gtk-missing-image");
419 m_ctw->set_src_buffer(NULL, 0, 0);
420 m_ctw->set_draw_buffer(NULL);
425 Firestation::save_image()
427 if (m_img_src == SRC_NONE) {
431 m_fcd_save_image->set_transient_for(*
this);
433 int result = m_fcd_save_image->run();
436 case (Gtk::RESPONSE_OK): {
439 Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
440 if (Glib::ustring(
"JPEG") == filter_name) {
442 }
else if (Glib::ustring(
"FVRaw") == filter_name) {
445 cout <<
"save_file(): unknown file format" << endl;
449 std::string filename = m_fcd_save_image->get_filename();
450 m_img_writer->set_filename(filename.c_str());
451 m_img_writer->set_dimensions(m_img_width, m_img_height);
452 m_img_writer->set_buffer(m_img_cs, m_yuv_orig_buffer);
453 m_img_writer->write();
455 std::cout <<
"Save file: " << filename << std::endl;
459 case (Gtk::RESPONSE_CANCEL):
break;
464 m_fcd_save_image->hide();
469 Firestation::update_image()
471 if (m_img_src == SRC_NONE) {
478 m_img_cs, YUV422_PLANAR, m_camera->buffer(), m_yuv_orig_buffer, m_img_width, m_img_height);
479 memcpy(m_yuv_draw_buffer,
481 colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
482 m_camera->dispose_buffer();
486 m_ctw->draw_segmentation_result();
493 Firestation::call_update_image()
495 if (!m_cont_img_trans) {
505 Firestation::enable_cont_img_trans()
507 if (m_cont_img_trans) {
508 m_cont_img_trans =
false;
512 int timeout = (int)rint(m_spb_update_time->get_value());
513 sigc::connection conn =
514 Glib::signal_timeout().connect(sigc::mem_fun(*
this, &Firestation::call_update_image), timeout);
515 m_cont_img_trans =
true;
520 Firestation::open_file()
522 m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
523 m_fcd_open_image->set_transient_for(*
this);
525 int result = m_fcd_open_image->run();
528 case Gtk::RESPONSE_OK: {
531 std::string filename = m_fcd_open_image->get_filename();
534 m_img_src = SRC_FILE;
539 case Gtk::RESPONSE_CANCEL: {
548 m_fcd_open_image->hide();
553 Firestation::open_folder()
555 m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
556 m_fcd_open_image->set_transient_for(*
this);
558 int result = m_fcd_open_image->run();
561 case Gtk::RESPONSE_OK: {
564 std::string extension;
565 Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
566 if (Glib::ustring(
"JPEG") == filter_name) {
568 }
else if (Glib::ustring(
"FVRaw") == filter_name) {
572 std::string folder = m_fcd_open_image->get_current_folder();
574 if (asprintf(&as,
"file:file:dir=%s:ext=%s", folder.c_str(), extension.c_str()) != -1) {
577 m_img_src = SRC_FILE;
581 printf(
"Cannot open folder, asprintf() ran out of memory");
587 case Gtk::RESPONSE_CANCEL: {
596 m_fcd_open_image->hide();
601 Firestation::open_shm()
605 shmit = SharedMemory::find(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h);
607 if (shmit == SharedMemory::end()) {
608 m_stb_status->push(
"No SHM images found");
611 unsigned int num_buffers = 0;
612 m_shm_list_store->clear();
614 while (shmit != SharedMemory::end()) {
616 Gtk::TreeModel::Row row = *(m_shm_list_store->append());
617 row[m_shm_columns.m_id] = num_buffers;
619 row[m_shm_columns.m_name] = h->
image_id();
624 m_dlg_open_shm->set_transient_for(*
this);
626 int result = m_dlg_open_shm->run();
629 case Gtk::RESPONSE_OK: {
632 Gtk::TreeModel::Path path;
633 Gtk::TreeViewColumn *column;
634 m_trv_shm_image_ids->get_cursor(path, column);
636 Gtk::TreeModel::iterator iter = m_shm_list_store->get_iter(path);
639 Gtk::TreeModel::Row row = *iter;
641 Glib::ustring name = row[m_shm_columns.m_name];
655 std::cout <<
"invalid iter" << std::endl;
661 case Gtk::RESPONSE_CANCEL:
break;
666 m_dlg_open_shm->hide();
671 Firestation::open_fuse()
673 Gtk::TreeModel::Children children = m_fuse_tree_store->children();
674 if (0 == children.size()) {
675 m_stb_status->push(
"No FUSE services found");
679 m_trv_fuse_services->expand_all();
680 m_dlg_open_fuse->set_transient_for(*
this);
682 int result = m_dlg_open_fuse->run();
685 case Gtk::RESPONSE_OK: {
686 Gtk::TreeModel::Path path;
687 Gtk::TreeViewColumn *column;
688 m_trv_fuse_services->get_cursor(path, column);
690 Gtk::TreeModel::iterator iter = m_fuse_tree_store->get_iter(path);
693 Gtk::TreeModel::Row row = *iter;
695 Glib::ustring hostname = row[m_fuse_columns.m_service_hostname];
696 unsigned short int port = row[m_fuse_columns.m_service_port];
697 Glib::ustring image_id = row[m_fuse_columns.m_image_id];
698 bool jpeg = m_ckb_fuse_jpeg->get_active();
703 m_camera =
new NetworkCamera(hostname.c_str(), port, image_id.c_str(), jpeg);
704 m_img_src = SRC_FUSE;
707 m_img_src = SRC_NONE;
712 std::cout <<
"invalid iter" << std::endl;
718 case Gtk::RESPONSE_CANCEL:
break;
723 m_dlg_open_fuse->hide();
727 Firestation::pre_open_img_src()
729 if (SRC_NONE != m_img_src) {
736 m_img_src = SRC_NONE;
742 Firestation::post_open_img_src()
744 if (m_img_src == SRC_NONE) {
752 m_img_width = m_camera->pixel_width();
753 m_img_height = m_camera->pixel_height();
754 m_img_cs = m_camera->colorspace();
756 m_img_size = colorspace_buffer_size(m_img_cs, m_img_width, m_img_height);
758 m_yuv_orig_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
759 m_yuv_draw_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
762 m_img_cs, YUV422_PLANAR, m_camera->buffer(), m_yuv_orig_buffer, m_img_width, m_img_height);
763 memcpy(m_yuv_draw_buffer,
765 colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
767 m_camera->dispose_buffer();
769 m_tbtn_update->set_sensitive(
true);
770 m_tbtn_save->set_sensitive(
true);
774 m_ctw->set_src_buffer(m_yuv_orig_buffer, m_img_width, m_img_height);
775 m_ctw->set_draw_buffer(m_yuv_draw_buffer);
776 m_ctw->draw_segmentation_result();
781 printf(
"Opening camera failed.\n");
786 Firestation::on_fuse_image_selected()
793 m_filw->get_selected_image(host_name, port, image_id, compression);
798 m_camera =
new NetworkCamera(host_name.c_str(), port, image_id.c_str(), compression);
799 m_img_src = SRC_FUSE;
801 m_img_src = SRC_NONE;
809 Firestation::on_colormap_updated()
811 m_ftw->set_current_colormap(m_ctw->get_colormap());
816 Firestation::draw_image()
818 if (m_img_src == SRC_NONE) {
830 if (scaled_width != m_scaled_img_width || scaled_height != m_scaled_img_height) {
831 m_scaled_img_width = scaled_width;
832 m_scaled_img_height = scaled_height;
836 if (m_rgb_scaled_buffer)
837 free(m_rgb_scaled_buffer);
838 if (m_yuv_scaled_buffer)
839 free(m_yuv_scaled_buffer);
840 m_yuv_scaled_buffer = malloc_buffer(YUV422_PLANAR, m_scaled_img_width, m_scaled_img_height);
844 if (m_btn_ct_seg->get_active()) {
845 unsigned int sld_img_size = m_scaled_img_width * m_scaled_img_height;
846 unsigned char u_seg = 255 / (
unsigned int)pow(2, m_spbtn_width->get_value());
847 unsigned char v_seg = 255 / (
unsigned int)pow(2, m_spbtn_height->get_value());
849 for (u = sld_img_size; u < sld_img_size + sld_img_size / 2; ++u) {
850 m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / u_seg) * u_seg;
853 for (; u < 2 * sld_img_size; ++u) {
854 m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / v_seg) * v_seg;
858 if (m_img_src == SRC_SHM) {
862 drawer.
set_buffer(m_yuv_scaled_buffer, m_scaled_img_width, m_scaled_img_height);
868 unsigned int roi_width =
870 unsigned int roi_height =
876 m_rgb_scaled_buffer =
877 (
unsigned char *)malloc(colorspace_buffer_size(RGB, m_scaled_img_width, m_scaled_img_height));
879 convert(YUV422_PLANAR,
884 m_scaled_img_height);
886 Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_data(m_rgb_scaled_buffer,
892 3 * m_scaled_img_width);
894 m_img_image->set(image);
901 Firestation::resize_image(Gtk::Allocation &allocation)
903 unsigned int new_width = (
unsigned int)allocation.get_width();
904 unsigned int new_height = (
unsigned int)allocation.get_height();
906 if (new_width != m_max_img_width || new_height != m_max_img_height) {
907 m_max_img_width = new_width;
908 m_max_img_height = new_height;
918 Firestation::image_click(GdkEventButton *event)
920 unsigned int offset_x;
921 unsigned int offset_y;
923 offset_x = (m_max_img_width - m_scaled_img_width) / 2;
924 offset_y = (m_max_img_height - m_scaled_img_height) / 2;
926 offset_x = offset_x > m_max_img_width ? 0 : offset_x;
927 offset_y = offset_y > m_max_img_height ? 0 : offset_y;
929 unsigned int image_x;
930 unsigned int image_y;
933 image_x = (
unsigned int)rint((event->x - offset_x) / m_scale_factor);
934 image_y = (
unsigned int)rint((event->y - offset_y) / m_scale_factor);
940 if (image_x > m_img_width || image_y > m_img_height) {
946 if (m_img_src != SRC_NONE) {
950 YUV422_PLANAR_YUV(m_yuv_orig_buffer, m_img_width, m_img_height, image_x, image_y, y, u, v);
951 printf(
"Y=%u U=%u Y=%u @ (%u, %u)\n",
960 case MODE_COLOR_TRAIN:
961 m_ctw->click(image_x, image_y, event->button);
965 case MODE_MIRROR_CALIB: {
966 #ifdef HAVE_MIRROR_CALIB
967 if (m_btn_mc_set_center->get_active()) {
968 m_calib_tool->set_center(image_x, image_y);
969 m_btn_mc_set_center->set_active(
false);
971 printf(
"Setting center to %u, %u\n", image_x, image_y);
973 printf(
"Using center to %d, %d\n", m_calib_tool->center_x(), m_calib_tool->center_y());
974 m_calib_tool->next_step();
975 const unsigned char *last_yuv = m_calib_tool->get_last_yuv_buffer();
976 memcpy(m_yuv_draw_buffer, last_yuv, m_img_size);
977 memcpy(m_yuv_orig_buffer, last_yuv, m_img_size);
978 m_calib_tool->draw_mark_lines(m_yuv_draw_buffer);
980 m_stb_status->push(m_calib_tool->get_state_description());
983 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
988 case MODE_MIRROR_CALIB_EVAL: {
989 #ifdef HAVE_MIRROR_CALIB
992 m_calib_tool->eval(image_x, image_y, &dist, &phi);
994 printf(
"(%u, %u) = POLAR(%.2f deg, %.2f meters)\n", image_x, image_y,
rad2deg(phi), dist);
997 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1010 Firestation::ct_start()
1012 if (m_op_mode == MODE_COLOR_TRAIN) {
1013 m_op_mode = MODE_VIEWER;
1014 m_stb_status->push(
"Leaving color training mode");
1016 if (m_img_src != SRC_NONE) {
1017 m_ctw->set_fg_object(ct_get_fg_object());
1019 m_op_mode = MODE_COLOR_TRAIN;
1021 m_stb_status->push(
"Entering color training mode");
1027 Firestation::ct_get_fg_object()
1029 int active = m_cmb_ct_type->get_active_row_number();
1047 return H_GOAL_YELLOW;
1055 default: printf(
"ct_get_fg_object(): UNKNOWN\n");
return H_UNKNOWN;
1060 Firestation::ct_object_changed()
1062 hint_t
object = ct_get_fg_object();
1063 m_ctw->set_fg_object(
object);
1067 Firestation::mc_draw_line()
1069 if (m_img_src != SRC_NONE) {
1070 #ifdef HAVE_MIRROR_CALIB
1071 memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer, m_img_size);
1072 MirrorCalibTool::draw_line(m_yuv_draw_buffer,
1074 m_calib_tool->center_x(),
1075 m_calib_tool->center_y(),
1080 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1086 Firestation::mc_on_line_angle_changed(Gtk::ScrollType scroll,
double value)
1088 mc_line_angle_deg = -1.0f * value;
1101 Firestation::mc_load_mask()
1103 m_fcd_mc_load_mask->set_transient_for(*
this);
1105 #if GTK_VERSION_GE(3, 0)
1106 Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1108 Gtk::FileFilter *filter_mirror = Gtk::manage(
new Gtk::FileFilter());
1110 filter_mirror->set_name(
"Robot Mask");
1111 filter_mirror->add_pattern(
"*.pnm");
1112 #if GTK_VERSION_GE(3, 0)
1113 m_fcd_mc_load_mask->add_filter(filter_mirror);
1115 m_fcd_mc_load_mask->add_filter(*filter_mirror);
1118 int result = m_fcd_mc_load_mask->run();
1121 case Gtk::RESPONSE_OK: {
1122 #ifdef HAVE_MIRROR_CALIB
1123 std::string filename = m_fcd_mc_load_mask->get_filename();
1124 m_calib_tool->load_mask(filename.c_str());
1127 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1131 case Gtk::RESPONSE_CANCEL:
break;
1135 m_fcd_mc_load_mask->hide();
1141 Firestation::mc_set_center()
1143 m_op_mode = MODE_MIRROR_CALIB;
1148 Firestation::mc_memorize()
1156 if (m_img_src != SRC_NONE) {
1157 #ifdef HAVE_MIRROR_CALIB
1158 double ori = mc_line_angle_deg;
1159 std::cout <<
"Starting calibration for ori = " << ori << std::endl;
1160 m_calib_tool->push_back(m_yuv_orig_buffer, m_img_size, m_img_width, m_img_height,
deg2rad(ori));
1161 m_op_mode = MODE_MIRROR_CALIB;
1162 std::cout <<
"Initialization for ori = " << ori <<
" completed" << std::endl;
1164 mc_line_angle_deg -= 120.0;
1166 m_scl_mc_line->set_value(-1.0f * mc_line_angle_deg);
1175 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1182 Firestation::mc_simulate_clicks()
1184 for (
int i = 1; i <= 3; ++i) {
1186 for (
int j = 1; j <= 8; ++j) {
1189 for (
int j = 1; j <= 2 * 8; ++j) {
1199 Firestation::mc_load()
1201 m_fcd_mc_load->set_transient_for(*
this);
1203 #if GTK_VERSION_GE(3, 0)
1204 Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1206 Gtk::FileFilter *filter_mirror = Gtk::manage(
new Gtk::FileFilter());
1208 filter_mirror->set_name(
"Mirror Calibration");
1209 filter_mirror->add_pattern(
"*.mirror");
1210 filter_mirror->add_pattern(
"*.bulb");
1211 #if GTK_VERSION_GE(3, 0)
1212 m_fcd_mc_load->add_filter(filter_mirror);
1214 m_fcd_mc_load->add_filter(*filter_mirror);
1217 int result = m_fcd_mc_load->run();
1220 case Gtk::RESPONSE_OK: {
1221 #ifdef HAVE_MIRROR_CALIB
1222 std::string filename = m_fcd_mc_load->get_filename();
1223 m_calib_tool->load(filename.c_str());
1224 m_op_mode = MODE_MIRROR_CALIB_EVAL;
1226 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1230 case Gtk::RESPONSE_CANCEL:
break;
1234 m_fcd_mc_load->hide();
1239 Firestation::mc_save()
1241 m_fcd_mc_save->set_transient_for(*
this);
1243 int result = m_fcd_mc_save->run();
1246 case (Gtk::RESPONSE_OK): {
1247 #ifdef HAVE_MIRROR_CALIB
1248 std::string filename = m_fcd_mc_save->get_filename();
1250 m_calib_tool->save(filename.c_str());
1252 printf(
"IPP and OpenCV not installed; mirror calibration does not work.\n");
1257 case (Gtk::RESPONSE_CANCEL):
break;
1262 m_fcd_mc_save->hide();
1268 const char * host = service->
host();
1269 const char * name = service->
name();
1270 const char * type = service->
type();
1271 const char * domain = service->
domain();
1272 unsigned short int port = service->
port();
1274 std::vector<FUSE_imageinfo_t> image_list;
1279 image_list = cam.image_list();
1281 e.
append(
"Could not open camera on %s:%d", host, port);
1288 printf(
"%zu images available on host %s.\n", image_list.size(), host);
1291 std::vector<FUSE_imageinfo_t>::iterator fit;
1293 Gtk::TreeModel::Children children = m_fuse_tree_store->children();
1294 Gtk::TreeModel::Row row = *(m_fuse_tree_store->append());
1295 row[m_fuse_columns.m_id] = children.size();
1296 row[m_fuse_columns.m_name] = Glib::ustring(name);
1297 row[m_fuse_columns.m_service_name] = Glib::ustring(name);
1298 row[m_fuse_columns.m_service_type] = Glib::ustring(type);
1299 row[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1300 row[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1301 row[m_fuse_columns.m_service_port] = port;
1303 for (fit = image_list.begin(); fit != image_list.end(); ++fit) {
1304 Gtk::TreeModel::Row childrow = *(m_fuse_tree_store->append(row.children()));
1305 childrow[m_fuse_columns.m_name] = Glib::ustring(fit->image_id);
1306 childrow[m_fuse_columns.m_service_name] = Glib::ustring(name);
1307 childrow[m_fuse_columns.m_service_type] = Glib::ustring(type);
1308 childrow[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1309 childrow[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1310 childrow[m_fuse_columns.m_service_port] = port;
1311 childrow[m_fuse_columns.m_image_id] = Glib::ustring(fit->image_id);
1312 childrow[m_fuse_columns.m_image_width] = fit->width;
1313 childrow[m_fuse_columns.m_image_height] = fit->height;
1314 childrow[m_fuse_columns.m_image_colorspace] =
1315 Glib::ustring(colorspace_to_string((colorspace_t)fit->colorspace));
1318 m_ftw->add_fountain_service(name, host, port);
1319 m_filw->add_fountain_service(name, host, port);
1325 const char *name = service->
name();
1326 const char *type = service->
type();
1327 const char *domain = service->
domain();
1329 Gtk::TreeModel::iterator rit = m_fuse_tree_store->children().begin();
1330 while (rit != m_fuse_tree_store->children().end()) {
1331 Glib::ustring n = (*rit)[m_fuse_columns.m_service_name];
1332 Glib::ustring t = (*rit)[m_fuse_columns.m_service_type];
1333 Glib::ustring d = (*rit)[m_fuse_columns.m_service_domain];
1335 if (strcmp(n.c_str(), name) == 0 && strcmp(t.c_str(), type) == 0
1336 && strcmp(d.c_str(), domain) == 0) {
1337 rit = m_fuse_tree_store->erase(rit);
1343 m_ftw->remove_fountain_service(name);
1344 m_filw->remove_fountain_service(name);
virtual ~Firestation()
Destructor.
Firestation(Glib::RefPtr< Gtk::Builder > builder)
Constructor.
Gtk::Window & get_window() const
Returns reference to main window.
sigc::signal< void, NetworkService * > signal_service_added()
Get "service added" signal.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
void append(const char *format,...) noexcept
Append messages to the message list.
Representation of a service announced or found via service discovery (i.e.
const char * type() const
Get type of service.
unsigned short int port() const
Get port of service.
const char * name() const
Get name of service.
const char * host() const
Get host of service.
const char * domain() const
Get domain of service.
virtual void close()=0
Close camera.
virtual void open()=0
Open the camera.
virtual void start()=0
Start image transfer from the camera.
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
void draw_rectangle(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Draw rectangle.
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
FvRaw Writer implementation.
virtual void scale()
Scale image.
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
virtual float get_scale_factor()
Returns the scale factor.
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
SharedMemoryImageBuffer * shared_memory_image_buffer()
Get the shared memory image buffer.
unsigned int roi_x() const
Get ROI X.
unsigned int roi_width() const
Get ROI width.
unsigned int roi_height() const
Get ROI height.
unsigned int roi_y() const
Get ROI Y.
bool circle_found() const
Check if circle was found .
Fawkes library namespace.
float deg2rad(float deg)
Convert an angle given in degrees to radians.
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
float rad2deg(float rad)
Convert an angle given in radians to degrees.