Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ConnectedComponents.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 #ifndef __CONNECTEDCOMPONENTS_H_INCLUDED__
00029 #define __CONNECTEDCOMPONENTS_H_INCLUDED__
00030 
00031 /**
00032  * @file   ConnectedComponents.H
00033  * @brief  Header file of class qgar::ConnectedComponents.
00034  *
00035  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00036  * @date   April 21, 2004  12:58
00037  * @since  Qgar 2.1.1
00038  */
00039 
00040 
00041 // For RCS/CVS use: Do not delete
00042 /* $Id: ConnectedComponents.H,v 1.13 2005/10/14 17:05:45 masini Exp $ */
00043 
00044 
00045 // STL
00046 #include <vector>
00047 // QGAR
00048 #include <qgarlib/Component.H>
00049 #include <qgarlib/GenImage.H>
00050 #include <qgarlib/GenTree.H>
00051 
00052 
00053 
00054 namespace qgar
00055 {
00056 
00057 
00058 /**
00059  * @ingroup GRAPHPROC_CC
00060  *
00061  * @class ConnectedComponents ConnectedComponents.H "qgarlib/ConnectedComponents.H"
00062  *
00063  * @brief Connected components extracted from a binary image.
00064  *
00065  * A (connected) component is a region defined by a set of connected
00066  * pixels having the same color:
00067 @verbatim
00068       b b b                    . w .
00069       b B b                    w W w
00070       b b b                    . w .
00071 
00072    8-connexity              4-connexity
00073     for BLACK                for WHITE
00074 @endverbatim
00075  * <ul>
00076  * <li>
00077  * Black components are constructed using 8-connexity: When black,
00078  * the central point ('B' on the figure) is connex to its 8 black
00079  * neighbors marked 'b'.
00080  * </li>
00081  * <li>
00082  * White components are constructed using 4-connexity: When white,
00083  * the central point ('W' on the figure) is connex to its 4 white
00084  * neighbors marked <b>w</b> and is not connex to the 4 white
00085  * neighbors marked '.'.
00086  * </li>
00087  * </ul>
00088  *
00089  * Each component is associated with a label, which is
00090  * an <i>integer</i> number of type <b>qgar::Component::label_type</b>.
00091  * See class qgar::Component for the way a component is represented.
00092  *
00093 @verbatim
00094                  _componentTree
00095                 ________________
00096                |                |    0     j     k
00097 +----------+   |      +--+      |   +--+--+--+--+--+- -+--+
00098 |COMPONENT |<----------C0|<----------- |  |  |  |  |   |  |  _componentTab
00099 |LABELLED 0|   |      +--+      |   +--+--+|-+--+|-+- -+--+
00100 +----------+   |       /\       |          |     |
00101                |      /  \      |          |     |
00102 +----------+   |  +--+    +--+  |          |     |
00103 |COMPONENT |<------Ci|    |Cj|<------------+     |
00104 |LABELLED i|   |  +--+    +--+  |                |
00105 +----------+   |    |     /||\  |                |
00106 +----------+   |  +--+          |                |
00107 |COMPONENT |<------Ck|<--------------------------+
00108 |LABELLED k|   |  +--+          |
00109 +----------+   |________________|
00110 @endverbatim
00111  *
00112  * The set of components is hierarchically organized as a tree,
00113  * the so-called <i>component tree</i> (see functions
00114  * qgar::ConnectedComponents::accessComponentTree
00115  * and qgar::ConnectedComponents::componentTree).
00116  * Each node represents a component (in fact, the data associated
00117  * with the node is a pointer to the component, <b>Ci</b> in the
00118  * figure above), and its children represent the components which
00119  * are directly included into (i.e. has a common border with) the
00120  * component.
00121  *
00122  * The root of the tree is always a <b>white</b> component
00123  * labelled <b>0</b>. It represents the background of the given
00124  * binary image, in which all the other components are
00125  * (transitively) included.
00126  *
00127  * To be sure to get a component representing the background,
00128  * the first and last rows of the given binary image, as well as
00129  * its first and last columns, are considered as being <b>white</b>.
00130  *
00131  * The so-called <i>component table</i>
00132  * (see functions qgar::ConnectedComponents::accessComponentTab
00133  * and qgar::ConnectedComponents::componentTab).
00134  * provides a direct access to the nodes representing the
00135  * components, using their labels to index the table
00136  * In other words, an element of this table is a pointer
00137  * to the node of the tree representing the component
00138  * having the same label as the table index of the element.
00139  * Operator qgar::ConnectedComponents::operator[] gives a direct
00140  * access to a component using its label.
00141  *
00142  * The location of the components is given by the so-called
00143  * <i>component image</i> (see qgar::ConnectedComponents::_componentImg):
00144  * The value of a pixel is the label of the component to which
00145  * the pixel belongs.
00146  *  
00147  * @todo
00148  * Give the user the choice between implementing components as
00149  * labelled regions in an image (like now) and implementing
00150  * components through tables of runs and labels (presently,
00151  * these tables are deleted once components are constructed)
00152  *
00153  * @todo qgar::ConnectedComponents::PRIVATEcopyCC perfoms a deep
00154  * copy of a tree. This method should be moved to class qgar::GenTree.
00155  *
00156  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00157  * @date   April 21, 2004  12:58
00158  * @since  Qgar 2.1.1
00159  */
00160 class ConnectedComponents
00161 {
00162 // -------------------------------------------------------------------
00163 // T Y P E   D E F I N I T I O N S
00164 // -------------------------------------------------------------------
00165 public:
00166 
00167   /** @name Types related to connected components */
00168   //        =====================================
00169   //@{
00170 
00171   /**
00172    * @brief Type of the pixels of the component image.
00173    */
00174   typedef GenImage<Component::label_type> image_type;
00175 
00176   /**
00177    * @brief Reference to qgar::ConnectedComponents::image_type.
00178    */
00179   typedef image_type& reference;
00180 
00181   /**
00182    * @brief Constant reference to qgar::ConnectedComponents::image_type.
00183    */
00184   typedef const image_type& const_reference;
00185 
00186   /**
00187    * @brief Pointer to qgar::ConnectedComponents::image_type.
00188    */
00189   typedef image_type* pointer;
00190 
00191   /**
00192    * @brief Constant pointer to qgar::ConnectedComponents::image_type.
00193    */
00194   typedef const image_type* const_pointer;
00195 
00196   /**
00197    * @brief Type of the component tree.
00198    */
00199   typedef GenTree<Component*> tree_type;
00200 
00201   /**
00202    * @brief Type of a node of the component tree.
00203    */
00204   typedef GenTreeNode<Component*> node_type;
00205 
00206   //@}
00207 
00208 
00209 // -------------------------------------------------------------------
00210 // P U B L I C    M E M B E R S
00211 // -------------------------------------------------------------------
00212 public:
00213 
00214   /** @name Constructors */
00215   //        ============
00216   //@{
00217 
00218   /**
00219    * @brief Construct from given binary image.
00220    */
00221   ConnectedComponents(const BinaryImage& aBinImg);
00222 
00223   ///**
00224   // * @brief No default constructor provided.
00225   // */
00226   //ConnectedComponents();
00227 
00228   /**
00229    * @brief Copy constructor.
00230    *
00231    * @param aCC  connected components to be copied
00232    *
00233    * @warning Perform a <b>deep copy</b>:
00234    * The component image (including its pixel map), the component
00235    * tree and all the components are duplicated.
00236    */
00237   ConnectedComponents(const ConnectedComponents& aCC);
00238 
00239   //@}
00240 
00241 
00242   /** @name Destructor */
00243   //        ==========
00244   //@{
00245 
00246   /**
00247    * @brief Non-virtual destructor.
00248    */
00249   ~ConnectedComponents();
00250 
00251   //@}
00252 
00253 
00254   /** @name Access to the component image */
00255   //        =============================
00256   //@{
00257 
00258   /**
00259    * @brief Get the component image.
00260    */
00261   inline const image_type& accessComponentImage() const;
00262 
00263   /**
00264    * @brief Get a copy of the component image.
00265    */
00266   inline image_type componentImage() const;
00267 
00268   //@}
00269 
00270 
00271   /** @name Access to the component tree */
00272   //        ============================
00273   //@{
00274 
00275   /**
00276    * @brief Get the component tree.
00277    */
00278   inline const tree_type& accessComponentTree() const;
00279 
00280   /**
00281    * @brief Get a copy of the component tree.
00282    */
00283   inline tree_type componentTree() const;
00284 
00285   /**
00286    * @brief Get a pointer to the root of the component tree.
00287    */
00288   inline node_type* pRoot() const;
00289 
00290   /**
00291    * @brief Get a pointer to the node of the component tree
00292    * representing the component of given label.
00293    *
00294    * @param aLabel  a component label
00295    *
00296    * @warning If the label is out of the range of current labels,
00297    * the function behavior is undefined.
00298    */
00299   inline node_type* pNode(Component::label_type aLabel) const;
00300 
00301   //@}
00302 
00303 
00304   /** @name Access to components */
00305   //        ====================
00306   //@{
00307 
00308   /**
00309    * @brief Get number of components.
00310    */
00311   inline int componentCnt() const;
00312 
00313   /**
00314    * @brief Get the component table.
00315    */
00316   inline const std::vector<node_type*>& accessComponentTab() const;
00317 
00318   /**
00319    * @brief Get a copy of the component table.
00320    */
00321   inline std::vector<node_type*> componentTab() const;
00322 
00323   /**
00324    * @brief Get a pointer to the component of given label.
00325    *
00326    * @param aLabel  a component label
00327    *
00328    * @warning If the label is out of the range of current labels,
00329    * the function behavior is undefined.
00330    */
00331   inline Component* pComponent(Component::label_type aLabel) const;
00332 
00333   //@}
00334 
00335 
00336   /** @name Reconstruct a binary image from components */
00337   //        ==========================================
00338   //@{
00339 
00340   /**
00341    * @brief Return a pointer to a binary image reconstructed from
00342    * components corresponding to given labels.
00343    *
00344    * @param aLabSet  a vector of component labels
00345    * 
00346    * A pixel of the resulting image is black (see qgar::QGEbw)
00347    * if it belongs to a black component whose label is in the set
00348    * of given labels. Otherwise, the pixel is white.
00349    *
00350    * @warning
00351    * - Given labels out of the range of current labels are ignored.
00352    * - The client is responsible for the deletion of the provided image.
00353    */
00354   BinaryImage*
00355   makeBinaryImg(const std::vector<Component::label_type>& aLabSet);
00356 
00357   //@}
00358 
00359 
00360   /** @name Operators */
00361   //        =========
00362   //@{
00363 
00364   /**
00365    * @brief Assignment.
00366    *
00367    * @param aCC  connected components to be assigned
00368    *
00369    * @warning Perform a <b>deep copy</b>:
00370    * The component image (including its pixel map), the component
00371    * tree and all the components are duplicated.
00372    */
00373   ConnectedComponents&
00374   operator=(const ConnectedComponents& aCC);
00375 
00376   /**
00377    * @brief Get component of given label.
00378    *
00379    * @param aLabel  a component label
00380    *
00381    * @warning If the label is out of the range of current labels,
00382    * the operator behavior is undefined.
00383     */
00384   inline Component& operator[](Component::label_type aLabel);
00385 
00386   /**
00387    * @brief Get component of given label
00388    *  (to be applied to a constant object).
00389    *
00390    * @param aLabel  a component label
00391    *
00392    * @warning If the label is out of the range of current labels,
00393    * the operator behavior is undefined.
00394     */
00395   inline const Component& operator[](Component::label_type aLabel) const;
00396 
00397    //@}
00398 
00399 
00400 // -------------------------------------------------------------------
00401 // P R O T E C T E D    M E M B E R S
00402 // -------------------------------------------------------------------
00403 protected:
00404 
00405   /** @name Representation of the components */
00406   //        ================================
00407   //@{
00408 
00409   /**
00410    * @brief Component image.
00411    *
00412    * It gives the location of the components: The value of a pixel
00413    * is the label of the component to which the pixel belongs.
00414    */
00415   image_type _componentImg;
00416 
00417   /**
00418    * @brief Tree of the components.
00419    *
00420    * The root component is always labelled <b>0</b> and represents
00421    * the (WHITE) background of the image. The children of a given
00422    * component represent the components which are directly included
00423    * in the given component, i.e. which have a common border with
00424    * the given component.
00425    */
00426   tree_type _componentTree;
00427 
00428   /**
00429    * @brief Table of the components.
00430    *
00431    * Vector of pointers to the nodes (in the component tree)
00432    * representing the components labelled by the corresponding indexes
00433    * in the vector. In other words, <b>_componentTab[i]</b> points
00434    * to the node representing the component labelled <b>i</b>.
00435    */
00436   std::vector<node_type*> _componentTab;
00437 
00438   //@}
00439 
00440 
00441 // -------------------------------------------------------------------
00442 // P R I V A T E    M E M B E R S
00443 // -------------------------------------------------------------------
00444 private:
00445 
00446   /** @name Auxiliaries */
00447   //        ===========
00448   //@{
00449 
00450   /**
00451    * @brief Copy components stored in tree whose root is node
00452    * <b>in</b> and store them in corresponding nodes of tree whose
00453    * root is node <b>out</b> (in fact, the current component tree).
00454    *
00455    * The component table of the current tree is subsequently updated.
00456    *
00457    * @param aPNodeIn   pointer to the root of the tree including
00458    *                   component to be copied
00459    * @param aPNodeOut  pointer to the root of the tree where to store
00460    *                   copied components
00461    *
00462    * @warning
00463    * Both trees must have the same structure: The tree
00464    * including node <b>out</b> (the current tree) is supposed to be
00465    * a copy of the tree including node <b>in</b>.
00466    */
00467   void PRIVATEcopyCC(node_type* aPNodeIn, node_type* aPNodeOut);
00468 
00469   //@}
00470 
00471 // -------------------------------------------------------------------
00472 }; // class ConnectedComponents
00473 
00474 
00475 
00476 
00477 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00478 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00479 // F U N C T I O N    M E M B E R S    I M P L E M E N T A T I O N
00480 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00481 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00482 
00483 
00484 // =============================
00485 // ACCESS TO THE COMPONENT IMAGE
00486 // =============================
00487 
00488 
00489 // GET THE COMPONENT IMAGE
00490 
00491 inline const ConnectedComponents::image_type&
00492 ConnectedComponents::accessComponentImage() const
00493 {
00494   return _componentImg;
00495 }
00496 
00497 
00498 // GET A COPY OF THE COMPONENT IMAGE
00499 
00500 inline ConnectedComponents::image_type
00501 ConnectedComponents::componentImage() const
00502 {
00503   return _componentImg;
00504 }
00505 
00506 
00507 // ============================
00508 // ACCESS TO THE COMPONENT TREE
00509 // ============================
00510 
00511 
00512 // GET THE COMPONENT TREE
00513 
00514 inline const ConnectedComponents::tree_type&
00515 ConnectedComponents::accessComponentTree() const
00516 {
00517   return _componentTree;
00518 }
00519 
00520 // GET A COPY OF THE COMPONENT TREE
00521 
00522 inline ConnectedComponents::tree_type
00523 ConnectedComponents::componentTree() const
00524 {
00525   return _componentTree;
00526 }
00527 
00528 
00529 // GET A POINTER TO THE ROOT OF THE COMPONENT TREE
00530 
00531 inline ConnectedComponents::node_type*
00532 ConnectedComponents::pRoot() const
00533 {
00534   return _componentTree.pRoot();
00535 }
00536 
00537 
00538 // GET A POINTER TO THE NODE OF THE COMPONENT TREE
00539 // REPRESENTING THE COMPONENT OF GIVEN LABEL
00540 
00541 inline ConnectedComponents::node_type*
00542 ConnectedComponents::pNode(Component::label_type aLabel) const
00543 {
00544   return _componentTab[aLabel];
00545 }
00546 
00547 
00548 // ====================
00549 // ACCESS TO COMPONENTS
00550 // ====================
00551 
00552 
00553 // GET NUMBER OF COMPONENTS
00554 
00555 inline int
00556 ConnectedComponents::componentCnt() const
00557 {
00558   return (int) _componentTab.size();
00559 }
00560 
00561 // GET THE COMPONENT TABLE
00562 
00563 inline const std::vector<ConnectedComponents::node_type*>&
00564 ConnectedComponents::accessComponentTab() const
00565 {
00566   return _componentTab;
00567 }
00568 
00569 // GET A COPY OF THE COMPONENT TABLE
00570 
00571 inline std::vector<ConnectedComponents::node_type*>
00572 ConnectedComponents::componentTab() const
00573 {
00574   return _componentTab;
00575 }
00576 
00577 // GET A POINTER TO THE COMPONENT OF GIVEN LABEL
00578 
00579 inline Component*
00580 ConnectedComponents::pComponent(Component::label_type aLabel) const
00581 {
00582   return _componentTab[aLabel]->data();
00583 }
00584 
00585 
00586 // =========
00587 // OPERATORS
00588 // =========
00589 
00590 
00591 // GET COMPONENT OF GIVEN LABEL
00592 
00593 inline Component&
00594 ConnectedComponents::operator[](Component::label_type aLabel)
00595 {
00596   return *(_componentTab[aLabel]->data());
00597 }
00598 
00599 
00600 // GET COMPONENT OF GIVEN LABEL
00601 
00602 inline const Component&
00603 ConnectedComponents::operator[](Component::label_type aLabel) const
00604 {
00605   return *(_componentTab[aLabel]->data());
00606 }
00607 
00608 
00609 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00610 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00611 
00612 
00613 } // namespace qgar
00614 
00615 
00616 #endif /* __CONNECTEDCOMPONENTS_H_INCLUDED__ */