Fawkes API Fawkes Development Version

color_train_widget.cpp

00001 
00002 /***************************************************************************
00003  *  color_train_widget.cpp - Color training widget
00004  *
00005  *  Created: Thu Mar 20 22:19:36 2008
00006  *  Copyright  2008  Daniel Beck
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <tools/firestation/color_train_widget.h>
00024 #include <tools/firestation/colormap_viewer_widget.h>
00025 #include <fvutils/color/yuv.h>
00026 #include <fvutils/color/zauberstab.h>
00027 #include <fvutils/color/colorspaces.h>
00028 #include <fvutils/color/conversions.h>
00029 #include <fvutils/draw/drawer.h>
00030 #include <fvutils/scalers/lossy.h>
00031 #include <fvutils/colormap/bayes/bayes_generator.h>
00032 #include <fvutils/colormap/yuvcm.h>
00033 #include <fvutils/colormap/cmfile.h>
00034 
00035 #include <fvutils/writers/jpeg.h>
00036 
00037 #include <fvutils/color/color_object_map.h>
00038 
00039 #include <core/exceptions/software.h>
00040 
00041 using namespace firevision;
00042 
00043 /** @class ColorTrainWidget "color_train_widget.h"
00044  * This widget implements the complete color training process.
00045  *
00046  * @author Daniel Beck
00047  */
00048 
00049 /** Constructor.
00050  * @param parent the parent window
00051  */
00052 ColorTrainWidget::ColorTrainWidget(Gtk::Window* parent)
00053 {
00054   m_generator = 0;
00055   m_zauberstab = new Zauberstab();
00056   m_cvw = new ColormapViewerWidget();
00057 
00058   m_src_buffer = 0;
00059   m_draw_buffer = 0;
00060 
00061   m_wnd_parent = parent;
00062   m_btn_reset_selection = 0;
00063   m_btn_add_to_colormap = 0;
00064   m_btn_reset_colormap = 0;
00065   m_btn_load_histos = 0;
00066   m_btn_save_histos = 0;
00067   m_btn_load_colormap = 0;
00068   m_btn_save_colormap = 0;
00069   m_spbtn_cm_depth = 0;
00070   m_spbtn_cm_width = 0;
00071   m_spbtn_cm_height = 0;
00072   m_img_segmentation = 0;
00073   m_scl_threshold = 0;
00074   m_scl_min_prob = 0;
00075   m_fcd_filechooser = 0;
00076 }
00077 
00078 /** Destructor. */
00079 ColorTrainWidget::~ColorTrainWidget()
00080 {
00081   delete m_cvw;
00082   delete m_generator;
00083   delete m_zauberstab;
00084 }
00085 
00086 /** Set the current foreground object.
00087  * @param fg_object the foreground object
00088  */
00089 void
00090 ColorTrainWidget::set_fg_object(hint_t fg_object)
00091 {
00092   m_fg_object = fg_object;
00093 }
00094 
00095 /** Set the buffer containing the image data.
00096  * @param yuv422_buffer the YUV422_PLANAR buffer holding the image data
00097  * @param img_width the width of the image
00098  * @param img_height the height of the image
00099  */
00100 void
00101 ColorTrainWidget::set_src_buffer(unsigned char* yuv422_buffer,
00102                     unsigned int img_width, unsigned int img_height)
00103 {
00104   m_img_width = img_width;
00105   m_img_height = img_height;
00106   m_src_buffer = yuv422_buffer;
00107   m_img_cs = YUV422_PLANAR;
00108   m_img_size = colorspace_buffer_size( m_img_cs, m_img_width, m_img_height );
00109 
00110   if (yuv422_buffer)
00111     {
00112       m_zauberstab->deleteRegion();
00113       m_zauberstab->setBuffer(m_src_buffer, m_img_width, m_img_height);
00114       m_zauberstab->setThreshold(10);
00115     }
00116   else
00117     {
00118       m_img_segmentation->clear();
00119       m_img_segmentation->set("gtk-missing-image");
00120     }
00121 }
00122 
00123 /** Set the buffer to draw the selection into.
00124  * It is assumed that this buffer has the same dimensions as the buffer holding
00125  * the soruce image.
00126  * @param buffer the draw buffer
00127  */
00128 void
00129 ColorTrainWidget::set_draw_buffer(unsigned char* buffer)
00130 {
00131   m_draw_buffer = buffer;
00132 }
00133 
00134 /** The user clicked into the image.
00135  * @param x the x-coordinate
00136  * @param y the y-coordinate
00137  * @param button 1 for left click, 3 for right click @see GdkEventButton
00138  */
00139 void
00140 ColorTrainWidget::click(unsigned int x, unsigned int y, unsigned int button)
00141 {
00142   if (m_src_buffer == 0 || m_draw_buffer == 0)
00143     { return; }
00144 
00145   if ( m_zauberstab->isEmptyRegion() )
00146     {
00147       if (button == MOUSE_BUTTON_LEFT) //left click
00148                         {
00149                                 m_zauberstab->findRegion(x, y);
00150                         }
00151     }
00152   else
00153     {
00154       if (button == MOUSE_BUTTON_LEFT) //left click
00155                         {
00156                                 m_zauberstab->addRegion(x, y);
00157                         }
00158 
00159       if (button == MOUSE_BUTTON_RIGHT) //right click
00160                         {
00161                                 m_zauberstab->deleteRegion(x, y);
00162                         }
00163     }
00164 
00165   memcpy(m_draw_buffer, m_src_buffer, m_img_size);
00166 
00167   ZRegion *region = m_zauberstab->getRegion();
00168   Drawer *d = new Drawer();
00169   d->set_buffer( m_draw_buffer, m_img_width, m_img_height );
00170 
00171   for (unsigned int s = 0; s < region->slices->size(); s++)
00172     {
00173       d->draw_rectangle_inverted( region->slices->at(s)->leftX,
00174                                 region->slices->at(s)->y,
00175                                 region->slices->at(s)->rightX - region->slices->at(s)->leftX,
00176                                 1 );
00177     }
00178 
00179   delete d;
00180 
00181   m_signal_update_image();
00182 }
00183 
00184 /** Reset the selection. */
00185 void
00186 ColorTrainWidget::reset_selection()
00187 {
00188   if (m_zauberstab)
00189     { m_zauberstab->deleteRegion(); }
00190 
00191   if( m_src_buffer && m_draw_buffer )
00192     { memcpy(m_draw_buffer, m_src_buffer, m_img_size); }
00193 
00194   m_signal_update_image();
00195 }
00196 
00197 /** Set the button to reset the selection.
00198  * @param btn the reset selection button
00199  */
00200 void
00201 ColorTrainWidget::set_reset_selection_btn(Gtk::Button* btn)
00202 {
00203   m_btn_reset_selection = btn;
00204   m_btn_reset_selection->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::reset_selection) );
00205 }
00206 
00207 /** Set the button to trigger the generation of the colormap.
00208  * @param btn a Button
00209  */
00210 void
00211 ColorTrainWidget::set_add_to_colormap_btn(Gtk::Button* btn)
00212 {
00213   m_btn_add_to_colormap = btn;
00214   m_btn_add_to_colormap->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::add_to_colormap) );
00215 }
00216 
00217 /** Set the button to reset the colormap.
00218  * @param btn a Button
00219  */
00220 void
00221 ColorTrainWidget::set_reset_colormap_btn(Gtk::Button* btn)
00222 {
00223   m_btn_reset_colormap = btn;
00224   m_btn_reset_colormap->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::reset_colormap) );
00225 }
00226 
00227 /** Set the buffon to open a dialog to load histograms.
00228  * @param btn a Button
00229  */
00230 void
00231 ColorTrainWidget::set_load_histos_btn(Gtk::Button* btn)
00232 {
00233   m_btn_load_histos = btn;
00234   m_btn_load_histos->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::load_histograms) );
00235 }
00236 
00237 /** Set the buffon to open a dialog to save histograms.
00238  * @param btn a Button
00239  */
00240 void
00241 ColorTrainWidget::set_save_histos_btn(Gtk::Button* btn)
00242 {
00243   m_btn_save_histos = btn;
00244   m_btn_save_histos->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::save_histograms) );
00245 }
00246 
00247 /** Set the buffon to open a dialog to load a colormap.
00248  * @param btn a Button
00249  */
00250 void
00251 ColorTrainWidget::set_load_colormap_btn(Gtk::Button* btn)
00252 {
00253   m_btn_load_colormap = btn;
00254   m_btn_load_colormap->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::load_colormap) );
00255 }
00256 
00257 /** Set the buffon to open a dialog to save a colormap.
00258  * @param btn a Button
00259  */
00260 void
00261 ColorTrainWidget::set_save_colormap_btn(Gtk::Button* btn)
00262 {
00263   m_btn_save_colormap = btn;
00264   m_btn_save_colormap->signal_clicked().connect( sigc::mem_fun(*this, &ColorTrainWidget::save_colormap) );
00265 }
00266 
00267 /** Set the image to render the colormap into.
00268  * @param img an Image
00269  */
00270 void
00271 ColorTrainWidget::set_colormap_img(Gtk::Image* img)
00272 {
00273   m_cvw->set_colormap_img(img);
00274 }
00275 
00276 /** Set the image to render the segmented image into.
00277  * @param img an Image
00278  */
00279 void
00280 ColorTrainWidget::set_segmentation_img(Gtk::Image* img)
00281 {
00282   m_img_segmentation = img;
00283   m_seg_img_max_width  = m_img_segmentation->get_width();
00284   m_seg_img_max_height = m_img_segmentation->get_height();
00285   m_img_segmentation->signal_size_allocate().connect( sigc::mem_fun( *this, &ColorTrainWidget::resize_seg_image) );
00286 }
00287 
00288 void
00289 ColorTrainWidget::resize_seg_image(Gtk::Allocation& allocation)
00290 {
00291   unsigned int new_width = (unsigned int) allocation.get_width();
00292   unsigned int new_height = (unsigned int) allocation.get_height();
00293 
00294   if (new_width != m_seg_img_max_width ||  new_height != m_seg_img_max_height)
00295     {
00296       m_seg_img_max_width = new_width;
00297       m_seg_img_max_height = new_height;
00298       draw_segmentation_result();
00299     }
00300 }
00301 
00302 /** Set the scale to control the selection threshold.
00303  * @param scl a Scale
00304  */
00305 void
00306 ColorTrainWidget::set_threshold_scl(Gtk::Scale* scl)
00307 {
00308   m_scl_threshold = scl;
00309   m_scl_threshold->signal_change_value().connect( sigc::mem_fun(*this, &ColorTrainWidget::set_threshold) );
00310 }
00311 
00312 /** Set the scale to control the minimum probability.
00313  * @param scl a Scale
00314  */
00315 void
00316 ColorTrainWidget::set_min_prob_scl(Gtk::Scale* scl)
00317 {
00318   m_scl_min_prob = scl;
00319   m_scl_min_prob->signal_change_value().connect( sigc::mem_fun(*this, &ColorTrainWidget::set_min_prob) );
00320 }
00321 
00322 /** Set the filechooser dialog to be used by this widget.
00323  * @param dlg a FileChooserDialog
00324  */
00325 void
00326 ColorTrainWidget::set_filechooser_dlg(Gtk::FileChooserDialog* dlg)
00327 {
00328   m_fcd_filechooser = dlg;
00329 }
00330 
00331 /** Set the widget to choose the layer of the colormap to display.
00332  * @param scl a Scale
00333  */
00334 void
00335 ColorTrainWidget::set_cm_layer_selector(Gtk::Scale* scl)
00336 {
00337   m_cvw->set_layer_selector(scl);
00338 }
00339 
00340 /** Set the widget to adjust the depth of the colormap.
00341  * @param depth SpinButton to set the Y-resolution of the color map
00342  * @param width SpinButton to set the U-resolution of the color map
00343  * @param height SpinButton to set the V-resolution of the color map
00344  */
00345 void
00346 ColorTrainWidget::set_cm_selector(Gtk::SpinButton* depth, Gtk::SpinButton* width, Gtk::SpinButton* height)
00347 {
00348   m_spbtn_cm_depth = depth;
00349   m_spbtn_cm_width = width;
00350   m_spbtn_cm_height = height;
00351 }
00352 
00353 /** Access the signal that is emitted whenever a redraw of the image is necessary.
00354  * @return reference to a Dispatcher.
00355  */
00356 Glib::Dispatcher&
00357 ColorTrainWidget::update_image()
00358 {
00359   return m_signal_update_image;
00360 }
00361 
00362 /** Access the signal that is emitted whenever the colormap has changed.
00363  * @return reference to a Dispatcher.
00364  */
00365 Glib::Dispatcher&
00366 ColorTrainWidget::colormap_updated()
00367 {
00368   return m_signal_colormap_updated;
00369 }
00370 
00371 /** Open a dialog to load a histogram. */
00372 void
00373 ColorTrainWidget::load_histograms()
00374 {
00375   if ( !m_fcd_filechooser )
00376     { return; }
00377 
00378   m_fcd_filechooser->set_title("Load histograms");
00379   m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
00380 
00381   m_fcd_filechooser->set_transient_for(*m_wnd_parent);
00382 
00383   int result = m_fcd_filechooser->run();
00384 
00385    switch(result)
00386      {
00387      case (Gtk::RESPONSE_OK):
00388        {
00389          std::string filename = m_fcd_filechooser->get_filename();
00390          if (!m_generator)
00391            { m_generator = new BayesColormapGenerator(); }
00392          m_generator->load_histograms( filename.c_str() );
00393          m_generator->calc();
00394          m_signal_colormap_updated();
00395 
00396          YuvColormap *cur = m_generator->get_current();
00397          if (m_spbtn_cm_depth) m_spbtn_cm_depth->set_value(log(cur->depth()) / log(2));
00398          if (m_spbtn_cm_width) m_spbtn_cm_width->set_value(log(cur->width()) / log(2));
00399          if (m_spbtn_cm_height) m_spbtn_cm_height->set_value(log(cur->height()) / log(2));
00400 
00401          m_cvw->set_colormap(cur);
00402          m_cvw->draw();
00403          draw_segmentation_result();
00404         break;
00405        }
00406 
00407      case (Gtk::RESPONSE_CANCEL):
00408        break;
00409 
00410      default:
00411        break;
00412      }
00413 
00414    m_fcd_filechooser->hide();
00415 }
00416 
00417 /** Open a dialog to save a histogram. */
00418 void
00419 ColorTrainWidget::save_histograms()
00420 {
00421   if ( !m_fcd_filechooser )
00422     { return; }
00423 
00424   m_fcd_filechooser->set_title("Save histograms");
00425   m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_SAVE);
00426 
00427   m_fcd_filechooser->set_transient_for(*m_wnd_parent);
00428 
00429   int result = m_fcd_filechooser->run();
00430 
00431    switch(result)
00432      {
00433      case (Gtk::RESPONSE_OK):
00434        {
00435          std::string filename = m_fcd_filechooser->get_filename();
00436          m_generator->save_histograms( filename.c_str() );
00437          break;
00438        }
00439 
00440      case (Gtk::RESPONSE_CANCEL):
00441        break;
00442 
00443      default:
00444        break;
00445      }
00446 
00447    m_fcd_filechooser->hide();
00448 }
00449 
00450 /** Generate a new colormap by adding the current histograms. */
00451 void
00452 ColorTrainWidget::add_to_colormap()
00453 {
00454   if ( !m_src_buffer )
00455     { return; }
00456 
00457   unsigned int cm_depth;
00458   if (m_spbtn_cm_depth)
00459     { cm_depth = (unsigned int) rint( pow(2.0, m_spbtn_cm_depth->get_value()) ); }
00460   else
00461     { cm_depth = 1; }
00462 
00463   unsigned int cm_width;
00464   if (m_spbtn_cm_width)
00465     { cm_width = (unsigned int) rint( pow(2.0, m_spbtn_cm_width->get_value()) ); }
00466   else
00467     { cm_width = 256; }
00468 
00469   unsigned int cm_height;
00470   if (m_spbtn_cm_height)
00471     { cm_height = (unsigned int) rint( pow(2.0, m_spbtn_cm_height->get_value()) ); }
00472   else
00473     { cm_height = 256; }
00474 
00475   if ( !m_generator
00476       || cm_depth  != m_generator->get_current()->depth()
00477       || cm_width  != m_generator->get_current()->width()
00478       || cm_height != m_generator->get_current()->height())
00479     {
00480       delete m_generator;
00481       m_generator = new BayesColormapGenerator(cm_depth, H_UNKNOWN, cm_width, cm_height);
00482       m_cvw->set_colormap( m_generator->get_current() );
00483     }
00484 
00485   if (m_fg_object == H_UNKNOWN)
00486     {
00487       printf("CTW::add_to_colormap(): no fg object set\n");
00488       return;
00489     }
00490 
00491   m_generator->set_fg_object(m_fg_object);
00492   m_generator->reset_undo();
00493   m_generator->set_buffer(m_src_buffer, m_img_width, m_img_height);
00494   m_generator->set_selection( m_zauberstab->getSelection() );
00495   m_generator->consider();
00496   m_generator->calc();
00497   m_signal_colormap_updated();
00498 
00499   // update colormap image
00500   m_cvw->draw(-1);
00501 
00502   // update segmentation image
00503   draw_segmentation_result();
00504 }
00505 
00506 /** Reset the colormap. */
00507 void
00508 ColorTrainWidget::reset_colormap()
00509 {
00510   Gtk::MessageDialog dialog(*m_wnd_parent, "Are you sure you want to reset the colormap?",
00511                             false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL);
00512 
00513   int result = dialog.run();
00514 
00515   if (result != Gtk::RESPONSE_OK) return;
00516 
00517   if (m_generator)
00518     {
00519       m_generator->reset();
00520       m_signal_colormap_updated();
00521 
00522       if (m_cvw)
00523         { m_cvw->draw(); }
00524 
00525       draw_segmentation_result();
00526     }
00527 }
00528 
00529 /** Open a dialog to load a colormap. */
00530 void
00531 ColorTrainWidget::load_colormap()
00532 {
00533   if ( !m_fcd_filechooser )
00534     { return; }
00535 
00536   m_fcd_filechooser->set_title("Load colormap colormap");
00537   m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
00538 
00539   m_fcd_filechooser->set_transient_for(*m_wnd_parent);
00540 
00541   int result = m_fcd_filechooser->run();
00542 
00543    switch(result)
00544      {
00545      case (Gtk::RESPONSE_OK):
00546        {
00547          delete m_generator;
00548 
00549          std::string filename = m_fcd_filechooser->get_filename();
00550          ColormapFile cmf;
00551          cmf.read(filename.c_str());
00552          Colormap *tcm = cmf.get_colormap();
00553          YuvColormap *tycm = dynamic_cast<YuvColormap *>(tcm);
00554          if ( ! tycm ) {
00555            delete tcm;
00556            throw fawkes::TypeMismatchException("File does not contain a YUV colormap");
00557          }
00558          unsigned int cm_depth = tcm->depth();
00559          unsigned int cm_width = tcm->width();
00560          unsigned int cm_height = tcm->height();
00561          m_generator = new BayesColormapGenerator(cm_depth, H_UNKNOWN, cm_width, cm_height);
00562          YuvColormap *current = m_generator->get_current();
00563          *current = *tycm;
00564          delete tcm;
00565 
00566          if (m_spbtn_cm_depth) m_spbtn_cm_depth->set_value(log(cm_depth) / log(2));
00567          if (m_spbtn_cm_width) m_spbtn_cm_width->set_value(log(cm_width) / log(2));
00568          if (m_spbtn_cm_height) m_spbtn_cm_height->set_value(log(cm_height) / log(2));
00569 
00570          m_signal_colormap_updated();
00571          m_cvw->set_colormap( m_generator->get_current() );
00572          m_cvw->draw();
00573          draw_segmentation_result();
00574         break;
00575        }
00576 
00577      case (Gtk::RESPONSE_CANCEL):
00578        break;
00579 
00580      default:
00581        break;
00582      }
00583 
00584    m_fcd_filechooser->hide();
00585 }
00586 
00587 /** Open a dialog to save a colormap. */
00588 void
00589 ColorTrainWidget::save_colormap()
00590 {
00591   if ( !m_fcd_filechooser )
00592     { return; }
00593 
00594   m_fcd_filechooser->set_title("Save colormap colormap");
00595   m_fcd_filechooser->set_action(Gtk::FILE_CHOOSER_ACTION_SAVE);
00596 
00597   m_fcd_filechooser->set_transient_for(*m_wnd_parent);
00598 
00599   int result = m_fcd_filechooser->run();
00600 
00601   switch(result)
00602     {
00603     case(Gtk::RESPONSE_OK):
00604       {
00605         std::string filename = m_fcd_filechooser->get_filename();
00606         YuvColormap *current = m_generator->get_current();
00607         ColormapFile cmf(current->depth(), current->width(), current->height());
00608         cmf.add_colormap(current);
00609         cmf.write( filename.c_str() );
00610         break;
00611       }
00612 
00613     case(Gtk::RESPONSE_CANCEL):
00614       break;
00615 
00616     default:
00617       break;
00618     }
00619 
00620    m_fcd_filechooser->hide();
00621 }
00622 
00623 /** Get the current colormap.
00624  * @return the current colormap
00625  */
00626 YuvColormap *
00627 ColorTrainWidget::get_colormap() const
00628 {
00629   if ( !m_generator )
00630     { return 0; }
00631 
00632   return m_generator->get_current();
00633 }
00634 
00635 bool
00636 ColorTrainWidget::set_threshold(Gtk::ScrollType scroll, double value)
00637 {
00638   unsigned int threshold = (unsigned int) rint(value);
00639   m_zauberstab->setThreshold(threshold);
00640 
00641   return true;
00642 }
00643 
00644 bool
00645 ColorTrainWidget::set_min_prob(Gtk::ScrollType scroll, double value)
00646 {
00647   if ( !m_generator )
00648     { return true; }
00649 
00650   m_generator->set_min_probability(value);
00651 
00652   return true;
00653 }
00654 
00655 void
00656 ColorTrainWidget::reset_gui()
00657 {
00658   m_scl_min_prob->set_value(0.0);
00659 }
00660 
00661 /** Render the result of segmenting the image in the source buffer considering the current
00662  * colormap into the specified Image.
00663  */
00664 void
00665 ColorTrainWidget::draw_segmentation_result()
00666 {
00667   if ( !m_src_buffer || !m_img_segmentation || !m_generator)
00668     { return; }
00669 
00670   unsigned char* seg_buffer = (unsigned char*) malloc(m_img_size);
00671   bzero(seg_buffer, m_img_size);
00672 
00673   Drawer d;
00674   d.set_buffer(seg_buffer, m_img_width, m_img_height);
00675 
00676   YuvColormap* cm = m_generator->get_current();
00677 
00678   for (unsigned int w = 0; w < m_img_width; ++w)
00679     {
00680       for (unsigned int h = 0; h < m_img_height; ++h)
00681         {
00682           unsigned int y = YUV422_PLANAR_Y_AT(m_src_buffer, m_img_width, w, h);
00683           unsigned int u = YUV422_PLANAR_U_AT(m_src_buffer, m_img_width, m_img_height, w, h);
00684           unsigned int v = YUV422_PLANAR_V_AT(m_src_buffer, m_img_width, m_img_height, w, h);
00685 
00686                 d.set_color(ColorObjectMap::get_color(cm->determine(y, u, v)));
00687                 d.color_point(w, h);
00688         }
00689     }
00690 
00691   LossyScaler scaler;
00692   scaler.set_original_buffer(seg_buffer);
00693   scaler.set_original_dimensions(m_img_width, m_img_height);
00694   scaler.set_scaled_dimensions(m_seg_img_max_width, m_seg_img_max_height);
00695   unsigned int width  = scaler.needed_scaled_width();
00696   unsigned int height = scaler.needed_scaled_height();
00697 
00698   unsigned char* scaled_buffer = (unsigned char*) malloc( colorspace_buffer_size( m_img_cs,
00699                                                                                   width,
00700                                                                                   height ) );
00701   scaler.set_scaled_buffer(scaled_buffer);
00702   scaler.scale();
00703 
00704   unsigned char* rgb_buffer = (unsigned char*) malloc( colorspace_buffer_size( RGB,
00705                                                                                width,
00706                                                                                height ) );
00707   convert(m_img_cs, RGB, scaled_buffer, rgb_buffer, width, height);
00708 
00709   Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_data( rgb_buffer,
00710                                                                    Gdk::COLORSPACE_RGB,
00711                                                                    false,
00712                                                                    8,
00713                                                                    width,
00714                                                                    height,
00715                                                                    3 * width,
00716                                                                    Gdk::Pixbuf::SlotDestroyData(&free_rgb_buffer));
00717 
00718   m_img_segmentation->set(image);
00719 
00720   free(scaled_buffer);
00721   free(seg_buffer);
00722 }
00723 
00724 /** Callback to free the rgb buffer
00725  * @param rgb_buffer pointer to the buffer
00726  */
00727 void ColorTrainWidget::free_rgb_buffer(const guint8* rgb_buffer)
00728 {
00729         free(const_cast<guint8 *>(rgb_buffer));
00730 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends