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());
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));
Colormap Generator using Bayes method.
static YUV_t get_color(color_t color)
YUV_t getter.
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
void add_colormap(Colormap *colormap)
Add colormap.
virtual unsigned int depth() const =0
Get depth of colormap.
virtual unsigned int height() const =0
Get height of colormap.
virtual unsigned int width() const =0
Get width of colormap.
void color_point(unsigned int x, unsigned int y)
Color the given point.
void draw_rectangle_inverted(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Draw inverted rectangle.
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
virtual void read(const char *file_name)
Read file.
virtual void write(const char *file_name)
Write file.
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 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.
virtual unsigned int height() const
Get height of colormap.
virtual unsigned int depth() const
Get depth of colormap.
virtual unsigned int width() const
Get width of colormap.
virtual color_t determine(unsigned int y, unsigned int u, unsigned int v) const
Determine color class for given YUV value.
a region is a stack of slices, together with the y-position of the slice at the top
std::vector< ZSlice * > * slices
slices
Zaubertab selection utility.