last update 20 Sep 2009 |
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