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