CVR-Lib last update 20 Sep 2009

cvrViewer2D.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2005
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrViewer2D.h
00043  *         Contains the class cvr::viewer2D used to visualized images and
00044  *         channels.
00045  * \author Pablo Alvarado
00046  * \date   05.01.2005
00047  *
00048  * revisions ..: $Id: cvrViewer2D.h,v 1.4 2006/03/28 13:29:39 doerfler Exp $
00049  */
00050 
00051 #ifndef _CVR_VIEWER_2_D_H_
00052 #define _CVR_VIEWER_2_D_H_
00053 
00054 #include "cvrViewerBase.h"
00055 #include "cvrPoint.h"
00056 #include "cvrRGBAPixel.h"
00057 #include "cvrRGBPixel.h"
00058 #include "cvrMatrix.h"
00059 #include "cvrViewer2DPainter.h"
00060 
00061 
00062 namespace cvr {
00063 
00064   /**
00065    * Class viewer2D.
00066    *
00067    * Viewer class to display images, channels and masks.
00068    *
00069    * It handles the following general matrix types and their corresponding
00070    * derived classes:
00071    *
00072    * - cvr::matrix<cvr::rgbaPixel>: for example, color images.
00073    * - cvr::matrix<float>: for example, cvr::channel.
00074    * - cvr::matrix<int32>: for example, labeled masks.
00075    * - cvr::matrix<ubyte>: for example, cvr::channel8.
00076    *
00077    * As default behaviour you can get the configuration window pressing
00078    * the right button of the mouse, but you can change this behaviour setting
00079    * the parameters accordingly.
00080    *
00081    * If you like the way the viewer displays your data, and you would like
00082    * the images, then you may want to take a look at cvr::viewer2DPainter, the
00083    * class responsible for painting the images you see.
00084    *
00085    * \warning: You may experience some problems while debugging your code if
00086    * you use viewers.  We are looking for the problem, but as a simple
00087    * workaround you just need to give the main loop enough time to initialize.
00088    * Just insert following lines before any forks, or threads or viewers are
00089    * created:
00090    *
00091    * \code
00092    *   guiServer::start();
00093    *   passiveWait(250000); // wait 1/4 of a second
00094    * \endcode
00095    *
00096    * @ingroup gVisualization
00097    */
00098   class viewer2D : public viewerBase {
00099   public:
00100 
00101     /**
00102      * There are parameters related with the GUI, for example
00103      * which interaction configuration starts the config dialog, the
00104      * position of the window, etc.  There are other parameters that
00105      * configure options about the image painting, which depend on the
00106      * lower classes.  The former are inherited from viewerBase::parameters,
00107      * the latter from viewer2DPainter::parameters.
00108      */
00109     class parameters : public viewerBase::parameters,
00110                        public viewer2DPainter::parameters {
00111     public:
00112 
00113       /**
00114        * Default constructor
00115        */
00116       parameters();
00117 
00118       /**
00119        * Copy constructor
00120        */
00121       parameters(const parameters& other);
00122 
00123       /**
00124        * Destructor
00125        */
00126       virtual ~parameters();
00127 
00128       /**
00129        * Copy data of "other" parameters
00130        */
00131       parameters& copy(const parameters& other);
00132 
00133       /**
00134        * Copy data of "other" parameters
00135        */
00136       parameters& operator=(const parameters& other);
00137 
00138       /**
00139        * Returns the name of this class
00140        */
00141       virtual const std::string& name() const;
00142 
00143       /**
00144        * Returns a pointer to a clone of the parameters.
00145        */
00146       virtual parameters* clone() const;
00147 
00148       /**
00149        * Returns a pointer to a clone of the parameters.
00150        */
00151       virtual parameters* newInstance() const;
00152 
00153       /**
00154        * Write the parameters in the given ioHandler
00155        * @param handler the ioHandler to be used
00156        * @param complete if true (the default) the enclosing begin/end will
00157        *        be also written, otherwise only the data block will be written.
00158        * @return true if write was successful
00159        */
00160       virtual bool write(ioHandler& handler,
00161                          const bool complete=true) const;
00162 
00163       /**
00164        * Read the parameters from the given ioHandler
00165        * @param handler the ioHandler to be used
00166        * @param complete if true (the default) the enclosing begin/end will
00167        *        be also written, otherwise only the data block will be written.
00168        * @return true if write was successful
00169        */
00170       virtual bool read(ioHandler& handler,const bool complete=true);
00171 
00172       //
00173       // Attributes
00174       //
00175 
00176       /**
00177        * Filename used to save the images.
00178        *
00179        * Default value: tux.png
00180        */
00181       std::string filename;
00182 
00183     };
00184     // end of parameters class
00185 
00186     /**
00187      * Types of data that can be displayed with the viewer2D
00188      */
00189     enum eDataType {
00190       Unknown,
00191       Image,
00192       Channel,
00193       Channel8,
00194       Channel32
00195     };
00196 
00197     /**
00198      * Information block
00199      *
00200      * This is the parent class for all information blocks used to transmit
00201      * some data to the configuration dialogs, which are to be displayed in a
00202      * read-only manner.
00203      *
00204      * It has a simplified interface if compared with cvr::object
00205      */
00206     class information : public viewerBase::information {
00207     public:
00208       /**
00209        * Default constructor
00210        */
00211       information();
00212 
00213       /**
00214        * Copy constructor
00215        */
00216       information(const information& other);
00217 
00218       /**
00219        * Virtual destructor
00220        */
00221       virtual ~information();
00222 
00223       /**
00224        * Copy method
00225        */
00226       information& copy(const information& other);
00227 
00228       /**
00229        * Clone
00230        */
00231       virtual information* clone() const;
00232 
00233 
00234       /**
00235        * Initialize all attributes from the given channel
00236        */
00237       void compute(const matrix<rgbaPixel>& mat);
00238 
00239       /**
00240        * Initialize all attributes from the given channel
00241        */
00242       void compute(const matrix<ubyte>& mat);
00243 
00244       /**
00245        * Initialize all attributes from the given channel
00246        */
00247       void compute(const matrix<float>& mat);
00248 
00249       /**
00250        * Initialize all attributes from the given channel
00251        */
00252       void compute(const matrix<int32>& mat);
00253 
00254       /**
00255        * Data type being displayed.
00256        *
00257        * It indicates if it is a color image a channel8, a channel or a label
00258        * mask.
00259        */
00260       eDataType type;
00261 
00262       /**
00263        * Size of the displayed image
00264        */
00265       ipoint size;
00266 
00267       /**
00268        * Minimum intensity value
00269        */
00270       float minI;
00271 
00272       /**
00273        * Maximum intensity value
00274        */
00275       float maxI;
00276 
00277       /**
00278        * Intensity average
00279        */
00280       float averageI;
00281 
00282       /**
00283        * Standard deviation of intensity
00284        */
00285       float stdDeviation;
00286 
00287       /**
00288        * Minimum RGB components
00289        */
00290       rgbaPixel minRGB;
00291 
00292       /**
00293        * Maximum RGB components
00294        */
00295       rgbaPixel maxRGB;
00296 
00297       /**
00298        * RGB average
00299        */
00300       frgbPixel averageRGB;
00301 
00302       /**
00303        * RGB covariance matrix
00304        */
00305       fmatrix covarianceRGB;
00306 
00307     protected:
00308       template <typename T>
00309       void computeScalars(const matrix<T>& mat);
00310 
00311     };
00312     // end of class information
00313 
00314     // ----------------------------------------------------------------------
00315     // viewer2D
00316     // ----------------------------------------------------------------------
00317 
00318     /**
00319      * Constructor
00320      */
00321     viewer2D(const std::string& title="Unknown");
00322 
00323     /**
00324      * Copy constructor.
00325      *
00326      * Create a new viewer, with its own window and configuration dialog, with
00327      * the same content as the other viewer.  If that viewer is still inactive,
00328      * this viewer will also be.
00329      */
00330     viewer2D(const viewer2D& other);
00331 
00332     /**
00333      * Constructor. Sets the given \p params
00334      */
00335     viewer2D(const parameters& params);
00336 
00337     /**
00338      * Destructor
00339      */
00340     ~viewer2D();
00341 
00342     /**
00343      * Returns a copy of this object
00344      */
00345     virtual viewer2D* clone() const;
00346 
00347     /**
00348      * Returns a copy of this object
00349      */
00350     virtual viewer2D* newInstance() const;
00351 
00352     /**
00353      * Returns a copy of this object
00354      */
00355     viewer2D& copy(const viewer2D& other);
00356 
00357     /**
00358      * Return a read-only copy of the parameters
00359      */
00360     const parameters& getParameters() const;
00361 
00362     /**
00363      * @name Show images or matrices
00364      */
00365     //@{
00366 
00367     /**
00368      * Show a two dimensional color image.
00369      * @param img the color image to be displayed.
00370      * @return true if successful, false otherwise
00371      */
00372     bool show(const matrix<rgbaPixel>& img);
00373 
00374     /**
00375      * Show a two dimensional channel with float values
00376      * @param chnl the channel to be displayed.
00377      * @return true if successful, false otherwise
00378      */
00379     bool show(const matrix<float>& chnl);
00380 
00381     /**
00382      * Show a two dimensional image mask with integer values
00383      * @param mask the mask to be displayed.
00384      * @return true if successful, false otherwise
00385      */
00386     bool show(const matrix<int32>& mask);
00387 
00388     /**
00389      * Show a two dimensional channel with 8 bit pixels.
00390      * @param chnl8 the fixed point channel to be displayed.
00391      * @return true if successful, false otherwise
00392      */
00393     bool show(const matrix<ubyte>& chnl8);
00394 
00395     //@}
00396 
00397     /**
00398      * The user can specify a viewer2DPainter object.
00399      *
00400      * Usually you will only use this method if you want to completely change
00401      * the way 2D data is displayed, beyond the configuration posibilities
00402      * through parameters, which is only possible if you create your own
00403      * cvr::viewer2DPainter derived class.
00404      *
00405      * A clone of the given painter will be done.
00406      *
00407      * If you derive a class of cvr::viewer2D and want to always set your own
00408      * painter, then you should only overload the method newDefaultPainter()
00409      */
00410     virtual bool setPainter(const viewer2DPainter& painter);
00411 
00412     /**
00413      * Save button pressed.
00414      *
00415      * Method called when the user pressed the save button.
00416      * Usually this method just call the viewer2D::saveButtonPressed();
00417      *
00418      * Note that if you call this method you can force from the code that the
00419      * displayed image is saved at the location specified in the parameters.
00420      */
00421     virtual bool saveButtonPressed(const std::string& filename);
00422 
00423     /**
00424      * Get a read-only reference to the internal information block.
00425      *
00426      * This can return a wrong reference.  You should check validInformation()
00427      * first.
00428      */
00429     const information& getInformation() const;
00430 
00431   protected:
00432 
00433     /**
00434      * Return a pointer to a new instance of the default painter you want
00435      * to use.
00436      */
00437     virtual viewer2DPainter* newDefaultPainter() const;
00438 
00439     /**
00440      * Get a writable reference to the internal information block
00441      *
00442      * This can return a wrong reference.  You should check validInformation()
00443      * first.
00444      */
00445     information& getInformation();
00446 
00447 
00448     /**
00449      * Ensure that the current information block has the given type and
00450      * the correct data size.  This saves time getting the information and
00451      * allows the viewer more speed if a sort of video-out use is planned.
00452      *
00453      * Returns false if it already had the given type or true if it was
00454      * changed.  This is important to know in order to setup the configuration
00455      * dialog accordingly.
00456      */
00457     bool ensureInformationType(const eDataType& type,
00458                                const ipoint& matrixSize);
00459 
00460     /**
00461      * This virtual method is called just before the configuration dialog
00462      * is to be displayed, in order to update the information block to the
00463      * data being processed.
00464      */
00465     virtual bool updateInformation();
00466 
00467     /**
00468      * Determine if the given position is valid
00469      */
00470     virtual bool validPosition(const ipoint& position) const;
00471 
00472     /**
00473      * Mouse/Keyboard interaction handler.
00474      *
00475      * This virtual function can be completely overriden and is called each
00476      * time some interaction with the main window occurs.  The default
00477      * behaviour is to display the position of the mouse pointer within the
00478      * window in the status bar.
00479      *
00480      * Usually, derived classes override this method to intercept the
00481      * interaction used to display some information under the mouse pointer.
00482      */
00483     virtual bool onKMInteraction(const interaction& action,
00484                                  const ipoint& position);
00485 
00486     /**
00487      * Protect access to critical data
00488      */
00489     mutex lock_;
00490 
00491     //
00492     // ----------------------------------------------------------------------
00493     //
00494 
00495     /**
00496      * Main window of the 2D viewer
00497      *
00498      * The only task for this class is to show a 2D color cvr::image in the
00499      * window taking care of the scrollbars.  The corresponding painter
00500      * (cvr::viewer2DPainter) is the one in charge of painting anything into
00501      * the cvr::image.
00502      */
00503     class mainWindow : public viewerBase::mainWindow {
00504     public:
00505       /**
00506        * Main window constructor
00507        */
00508       mainWindow(viewer2D& parent);
00509 
00510       /**
00511        * Get information block of the parent class
00512        */
00513       const information& getInformation() const;
00514 
00515       /**
00516        * Get data as an image for the window indicated by area
00517        */
00518       bool getFormattedData(const irectangle& area,
00519                             image& img);
00520 
00521       /**
00522        * Compute the new canvas size.
00523        *
00524        * Nothing but the computation has to be done here.  If it is applied or
00525        * not will be a decision of the setCanvasSize() method.
00526        *
00527        * The viewer2D computes the size as the product of zoom time the image
00528        * size.
00529        */
00530       virtual ipoint computeCanvasSize() const;
00531 
00532       /**
00533        * Method called when the user pressed the save button.
00534        *
00535        * (Implemented in toolkit dependent files, as it needs some
00536        * collaboration with the GUI to detect the current window configuration)
00537        */
00538       virtual bool saveButtonPressed(const std::string& filename);
00539 
00540     protected:
00541       /**
00542        * Private class used to contain all internals based on each specific
00543        * widget toolkit
00544        */
00545       class tk;
00546 
00547       /**
00548        * Initialize toolkit dependent class
00549        *
00550        * This is called at construction time but is implemented by the
00551        * toolkit being used.
00552        */
00553       virtual void initToolkit();
00554 
00555       /**
00556        * Destroy toolkit dependent class
00557        *
00558        * This is called at destruction time and is implemented by the
00559        * toolkit being used.
00560        */
00561       virtual void destroyToolkit();
00562 
00563     };
00564 
00565 
00566     /**
00567      * Ensure that a main window of the proper type has been created.
00568      *
00569      * @return true if a new mainWindow instance was created or false if
00570      *         it already existed.
00571      */
00572     virtual bool ensureMainWindow();
00573 
00574     /**
00575      * Return the main window as read-only reference.
00576      *
00577      * This will throw an assertion if the mainWindow has not been set yet.
00578      */
00579     const mainWindow& getMainWindow() const;
00580 
00581     /**
00582      * Return the main window as reference.
00583      *
00584      * This will throw an assertion if the mainWindow has not been set yet.
00585      */
00586     mainWindow& getMainWindow();
00587 
00588     /**
00589      * Configuration dialog for 2D data
00590      */
00591     class configDialog : public viewerBase::configDialog {
00592     public:
00593       /**
00594        * Construction
00595        */
00596       configDialog(viewer2D& parent);
00597       /**
00598        * Sort of copy constructor but with a new parent
00599        */
00600       configDialog(const configDialog& other,viewerBase& parent);
00601 
00602       /**
00603        * Destruction
00604        */
00605       virtual ~configDialog();
00606 
00607       /**
00608        * Use the given information block.
00609        *
00610        * This method does not copy the information block, it just stores a
00611        * reference to the given instance.
00612        *
00613        * Inherited methods should call this one and transfer all data in the
00614        * information block to the GUI elements.
00615        */
00616       virtual bool useInformation(const viewerBase::information* dataInfo);
00617 
00618       /**
00619        * Get a read-only reference to the data block
00620        */
00621       const information& getInformation() const;
00622 
00623       /**
00624        * Set a copy of the given parameters.
00625        *
00626        * This method just calls for the base class one and then indicates
00627        * the toolkit instance to update its GUI elements.
00628        */
00629       virtual bool setParameters(const parameters& par);
00630 
00631 
00632       /**
00633        * @name Toolkit dependent functions
00634        */
00635       //@{
00636       /**
00637        * Constructs the main window.
00638        *
00639        * You usually don't need to call this method directly, as
00640        * it is called by show() if necessary.
00641        *
00642        * This is called just once for the configuration dialog at its
00643        * construction time.
00644        *
00645        * In inherited classes it is usually employed to build the basic
00646        * structure of the configuration dialog
00647        */
00648       virtual bool build();
00649 
00650       /**
00651        * Show the configuration dialog
00652        */
00653       virtual bool show();
00654 
00655       /**
00656        * Hides the configuration dialog
00657        */
00658       virtual bool hide();
00659 
00660       /**
00661        * Destroys the widget completely.
00662        *
00663        * Before the widget is destroyed, the window is hidden, and the
00664        * parent viewer is signalized accordingly in order to destroy
00665        * the configuration dialog.
00666        */
00667       virtual bool destroy();
00668       //@}
00669 
00670       /**
00671        * Save button pressed.
00672        *
00673        * Method called when the user pressed the save button.
00674        * Usually this method just call the viewer2D::saveButtonPressed();
00675        */
00676       virtual bool saveButtonPressed(const std::string& filename);
00677 
00678       /**
00679        * Copy method.
00680        *
00681        * Copies everything, but the parent main window
00682        */
00683       configDialog& copy(const configDialog& other);
00684 
00685       /**
00686        * This clone requires the parent window
00687        */
00688       virtual configDialog* clone(viewerBase& parent) const;
00689 
00690     protected:
00691       /**
00692        * Private class used to contain all internals based on each specific
00693        * widget toolkit
00694        */
00695       class tk;
00696 
00697       /**
00698        * Get the toolkit with the proper type
00699        */
00700       tk* getToolkit();
00701 
00702     private:
00703 
00704       /**
00705        * Initialize toolkit dependent class
00706        *
00707        * This is called at construction time but is implemented by the
00708        * toolkit being used.
00709        */
00710       virtual void initToolkit();
00711 
00712       /**
00713        * Destroy toolkit dependent class
00714        *
00715        * This is called at destruction time and is implemented by the
00716        * toolkit being used.
00717        */
00718       virtual void destroyToolkit();
00719 
00720       /**
00721        * Disable operator=
00722        */
00723       configDialog& operator=(const configDialog& other);
00724     };
00725 
00726     /**
00727      * Return a read-only reference to the configuration dialog
00728      */
00729     const configDialog& getConfigDialog() const;
00730 
00731     /**
00732      * Return a writable reference to the configuration dialog
00733      */
00734     configDialog& getConfigDialog();
00735 
00736   protected:
00737 
00738     // TODO: may be eliminated if we use the other way around:
00739     // drawingAreaExposed can call a virtual function of the viewer2D, which
00740     // creates the image and then calls something of mainWindow which calls
00741     // something of tk which does the real job
00742 
00743     friend class mainWindow; // it has to get silent access to the data_
00744 
00745     /**
00746      * Pointer to the last object shown
00747      */
00748     const container* data_;
00749 
00750     /**
00751      * The painter
00752      */
00753     viewer2DPainter* painter_;
00754 
00755     /**
00756      * Get data as an image for the window indicated by area
00757      *
00758      *
00759      */
00760     virtual bool getFormattedData(const irectangle& area,
00761                                   image& img);
00762 
00763 
00764     /**
00765      * Cast data_ as image
00766      */
00767     inline const matrix<rgbaPixel>* getDataAsImage() const;
00768 
00769     /**
00770      * Cast data_ as channel
00771      */
00772     inline const matrix<float>* getDataAsChannel() const;
00773 
00774     /**
00775      * Cast data_ as channel8
00776      */
00777     inline const matrix<ubyte>* getDataAsChannel8() const;
00778 
00779     /**
00780      * Cast data_ as channel32
00781      */
00782     inline const matrix<int32>* getDataAsChannel32() const;
00783 
00784   };
00785 
00786 }
00787 
00788 #endif

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8