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__ */