23 #include "color_train_widget.h" 25 #include "colormap_viewer_widget.h" 27 #include <core/exceptions/software.h> 28 #include <fvutils/color/color_object_map.h> 29 #include <fvutils/color/colorspaces.h> 30 #include <fvutils/color/conversions.h> 31 #include <fvutils/color/yuv.h> 32 #include <fvutils/color/zauberstab.h> 33 #include <fvutils/colormap/bayes/bayes_generator.h> 34 #include <fvutils/colormap/cmfile.h> 35 #include <fvutils/colormap/yuvcm.h> 36 #include <fvutils/draw/drawer.h> 37 #include <fvutils/scalers/lossy.h> 38 #include <fvutils/writers/jpeg.h> 40 using namespace firevision;
60 m_wnd_parent = parent;
61 m_btn_reset_selection = 0;
62 m_btn_add_to_colormap = 0;
63 m_btn_reset_colormap = 0;
64 m_btn_load_histos = 0;
65 m_btn_save_histos = 0;
66 m_btn_load_colormap = 0;
67 m_btn_save_colormap = 0;
70 m_spbtn_cm_height = 0;
71 m_img_segmentation = 0;
74 m_fcd_filechooser = 0;
89 m_fg_object = fg_object;
99 unsigned int img_width,
100 unsigned int img_height)
102 m_img_width = img_width;
103 m_img_height = img_height;
104 m_src_buffer = yuv422_buffer;
105 m_img_cs = YUV422_PLANAR;
106 m_img_size = colorspace_buffer_size(m_img_cs, m_img_width, m_img_height);
109 m_zauberstab->deleteRegion();
110 m_zauberstab->setBuffer(m_src_buffer, m_img_width, m_img_height);
111 m_zauberstab->setThreshold(10);
113 m_img_segmentation->clear();
114 m_img_segmentation->set(
"gtk-missing-image");
126 m_draw_buffer = buffer;
137 if (m_src_buffer == 0 || m_draw_buffer == 0) {
141 if (m_zauberstab->isEmptyRegion()) {
142 if (button == MOUSE_BUTTON_LEFT)
144 m_zauberstab->findRegion(x, y);
147 if (button == MOUSE_BUTTON_LEFT)
149 m_zauberstab->addRegion(x, y);
152 if (button == MOUSE_BUTTON_RIGHT)
154 m_zauberstab->deleteRegion(x, y);
158 memcpy(m_draw_buffer, m_src_buffer, m_img_size);
160 ZRegion *region = m_zauberstab->getRegion();
162 d->
set_buffer(m_draw_buffer, m_img_width, m_img_height);
164 for (
unsigned int s = 0; s < region->
slices->size(); s++) {
167 region->
slices->at(s)->rightX - region->
slices->at(s)->leftX,
173 m_signal_update_image();
181 m_zauberstab->deleteRegion();
184 if (m_src_buffer && m_draw_buffer) {
185 memcpy(m_draw_buffer, m_src_buffer, m_img_size);
188 m_signal_update_image();
197 m_btn_reset_selection = btn;
198 m_btn_reset_selection->signal_clicked().connect(
208 m_btn_add_to_colormap = btn;
209 m_btn_add_to_colormap->signal_clicked().connect(
219 m_btn_reset_colormap = btn;
220 m_btn_reset_colormap->signal_clicked().connect(
230 m_btn_load_histos = btn;
231 m_btn_load_histos->signal_clicked().connect(
241 m_btn_save_histos = btn;
242 m_btn_save_histos->signal_clicked().connect(
252 m_btn_load_colormap = btn;
253 m_btn_load_colormap->signal_clicked().connect(
263 m_btn_save_colormap = btn;
264 m_btn_save_colormap->signal_clicked().connect(
274 m_cvw->set_colormap_img(img);
283 m_img_segmentation = img;
284 m_seg_img_max_width = m_img_segmentation->get_width();
285 m_seg_img_max_height = m_img_segmentation->get_height();
286 m_img_segmentation->signal_size_allocate().connect(
287 sigc::mem_fun(*
this, &ColorTrainWidget::resize_seg_image));
291 ColorTrainWidget::resize_seg_image(Gtk::Allocation &allocation)
293 unsigned int new_width = (
unsigned int)allocation.get_width();
294 unsigned int new_height = (
unsigned int)allocation.get_height();
296 if (new_width != m_seg_img_max_width || new_height != m_seg_img_max_height) {
297 m_seg_img_max_width = new_width;
298 m_seg_img_max_height = new_height;
299 draw_segmentation_result();
309 m_scl_threshold = scl;
310 m_scl_threshold->signal_change_value().connect(
311 sigc::mem_fun(*
this, &ColorTrainWidget::set_threshold));
320 m_scl_min_prob = scl;
321 m_scl_min_prob->signal_change_value().connect(
322 sigc::mem_fun(*
this, &ColorTrainWidget::set_min_prob));
331 m_fcd_filechooser = dlg;
340 m_cvw->set_layer_selector(scl);
350 Gtk::SpinButton *width,
351 Gtk::SpinButton *height)
353 m_spbtn_cm_depth = depth;
354 m_spbtn_cm_width = width;
355 m_spbtn_cm_height = height;
364 return m_signal_update_image;
373 return m_signal_colormap_updated;
380 if (!m_fcd_filechooser) {
384 m_fcd_filechooser->set_title(
"Load histograms");
385 m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
387 m_fcd_filechooser->set_transient_for(*m_wnd_parent);
389 int result = m_fcd_filechooser->run();
392 case (Gtk::RESPONSE_OK): {
393 std::string filename = m_fcd_filechooser->get_filename();
397 m_generator->load_histograms(filename.c_str());
399 m_signal_colormap_updated();
402 if (m_spbtn_cm_depth)
403 m_spbtn_cm_depth->set_value(log(cur->
depth()) / log(2));
404 if (m_spbtn_cm_width)
405 m_spbtn_cm_width->set_value(log(cur->
width()) / log(2));
406 if (m_spbtn_cm_height)
407 m_spbtn_cm_height->set_value(log(cur->
height()) / log(2));
409 m_cvw->set_colormap(cur);
411 draw_segmentation_result();
415 case (Gtk::RESPONSE_CANCEL):
break;
420 m_fcd_filechooser->hide();
427 if (!m_fcd_filechooser) {
431 m_fcd_filechooser->set_title(
"Save histograms");
432 m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_SAVE);
434 m_fcd_filechooser->set_transient_for(*m_wnd_parent);
436 int result = m_fcd_filechooser->run();
439 case (Gtk::RESPONSE_OK): {
440 std::string filename = m_fcd_filechooser->get_filename();
441 m_generator->save_histograms(filename.c_str());
445 case (Gtk::RESPONSE_CANCEL):
break;
450 m_fcd_filechooser->hide();
461 unsigned int cm_depth;
462 if (m_spbtn_cm_depth) {
463 cm_depth = (
unsigned int)rint(pow(2.0, m_spbtn_cm_depth->get_value()));
468 unsigned int cm_width;
469 if (m_spbtn_cm_width) {
470 cm_width = (
unsigned int)rint(pow(2.0, m_spbtn_cm_width->get_value()));
475 unsigned int cm_height;
476 if (m_spbtn_cm_height) {
477 cm_height = (
unsigned int)rint(pow(2.0, m_spbtn_cm_height->get_value()));
482 if (!m_generator || cm_depth != m_generator->get_current()->depth()
483 || cm_width != m_generator->get_current()->width()
484 || cm_height != m_generator->get_current()->height()) {
487 m_cvw->set_colormap(m_generator->get_current());
490 if (m_fg_object == H_UNKNOWN) {
491 printf(
"CTW::add_to_colormap(): no fg object set\n");
495 m_generator->set_fg_object(m_fg_object);
496 m_generator->reset_undo();
497 m_generator->set_buffer(m_src_buffer, m_img_width, m_img_height);
498 m_generator->set_selection(m_zauberstab->getSelection());
499 m_generator->consider();
501 m_signal_colormap_updated();
507 draw_segmentation_result();
514 Gtk::MessageDialog dialog(*m_wnd_parent,
515 "Are you sure you want to reset the colormap?",
517 Gtk::MESSAGE_QUESTION,
518 Gtk::BUTTONS_OK_CANCEL);
520 int result = dialog.run();
522 if (result != Gtk::RESPONSE_OK)
526 m_generator->reset();
527 m_signal_colormap_updated();
533 draw_segmentation_result();
541 if (!m_fcd_filechooser) {
545 m_fcd_filechooser->set_title(
"Load colormap colormap");
546 m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
548 m_fcd_filechooser->set_transient_for(*m_wnd_parent);
550 int result = m_fcd_filechooser->run();
553 case (Gtk::RESPONSE_OK): {
556 std::string filename = m_fcd_filechooser->get_filename();
558 cmf.
read(filename.c_str());
560 YuvColormap *tycm = dynamic_cast<YuvColormap *>(tcm);
565 unsigned int cm_depth = tcm->
depth();
566 unsigned int cm_width = tcm->
width();
567 unsigned int cm_height = tcm->
height();
573 if (m_spbtn_cm_depth)
574 m_spbtn_cm_depth->set_value(log(cm_depth) / log(2));
575 if (m_spbtn_cm_width)
576 m_spbtn_cm_width->set_value(log(cm_width) / log(2));
577 if (m_spbtn_cm_height)
578 m_spbtn_cm_height->set_value(log(cm_height) / log(2));
580 m_signal_colormap_updated();
581 m_cvw->set_colormap(m_generator->get_current());
583 draw_segmentation_result();
587 case (Gtk::RESPONSE_CANCEL):
break;
592 m_fcd_filechooser->hide();
599 if (!m_fcd_filechooser) {
603 m_fcd_filechooser->set_title(
"Save colormap colormap");
604 m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_SAVE);
606 m_fcd_filechooser->set_transient_for(*m_wnd_parent);
608 int result = m_fcd_filechooser->run();
611 case (Gtk::RESPONSE_OK): {
612 std::string filename = m_fcd_filechooser->get_filename();
616 cmf.write(filename.c_str());
620 case (Gtk::RESPONSE_CANCEL):
break;
625 m_fcd_filechooser->hide();
638 return m_generator->get_current();
642 ColorTrainWidget::set_threshold(Gtk::ScrollType scroll,
double value)
644 unsigned int threshold = (
unsigned int)rint(value);
645 m_zauberstab->setThreshold(threshold);
651 ColorTrainWidget::set_min_prob(Gtk::ScrollType scroll,
double value)
657 m_generator->set_min_probability(value);
663 ColorTrainWidget::reset_gui()
665 m_scl_min_prob->set_value(0.0);
674 if (!m_src_buffer || !m_img_segmentation || !m_generator) {
678 unsigned char *seg_buffer = (
unsigned char *)malloc(m_img_size);
679 bzero(seg_buffer, m_img_size);
682 d.
set_buffer(seg_buffer, m_img_width, m_img_height);
686 for (
unsigned int w = 0; w < m_img_width; ++w) {
687 for (
unsigned int h = 0; h < m_img_height; ++h) {
688 unsigned int y = YUV422_PLANAR_Y_AT(m_src_buffer, m_img_width, w, h);
689 unsigned int u = YUV422_PLANAR_U_AT(m_src_buffer, m_img_width, m_img_height, w, h);
690 unsigned int v = YUV422_PLANAR_V_AT(m_src_buffer, m_img_width, m_img_height, w, h);
704 unsigned char *scaled_buffer =
705 (
unsigned char *)malloc(colorspace_buffer_size(m_img_cs, width, height));
709 unsigned char *rgb_buffer = (
unsigned char *)malloc(colorspace_buffer_size(RGB, width, height));
710 convert(m_img_cs, RGB, scaled_buffer, rgb_buffer, width, height);
712 Glib::RefPtr<Gdk::Pixbuf> image =
713 Gdk::Pixbuf::create_from_data(rgb_buffer,
720 Gdk::Pixbuf::SlotDestroyData(&free_rgb_buffer));
722 m_img_segmentation->set(image);
732 ColorTrainWidget::free_rgb_buffer(
const guint8 *rgb_buffer)
734 free(const_cast<guint8 *>(rgb_buffer));
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
void add_colormap(Colormap *colormap)
Add colormap.
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
std::vector< ZSlice * > * slices
slices
virtual unsigned int width() const
Get width of colormap.
virtual unsigned int depth() const =0
Get depth of colormap.
virtual unsigned int height() const =0
Get height of colormap.
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
void draw_rectangle_inverted(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Draw inverted rectangle.
virtual void read(const char *file_name)
Read file.
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
a region is a stack of slices, together with the y-position of the slice at the top
Zaubertab selection utility.
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
virtual unsigned int width() const =0
Get width of colormap.
virtual unsigned int depth() const
Get depth of colormap.
Colormap Generator using Bayes method.
virtual color_t determine(unsigned int y, unsigned int u, unsigned int v) const
Determine color class for given YUV value.
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
void color_point(unsigned int x, unsigned int y)
Color the given point.
virtual void scale()
Scale image.
static YUV_t get_color(color_t color)
YUV_t getter.
virtual unsigned int height() const
Get height of colormap.
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.