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 __COMPONENT_H_INCLUDED__ 00029 #define __COMPONENT_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file Component.H 00034 * @brief Header file of classes qgar::Component. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date March 17, 2004 17:17 00038 * @since Qgar 2.1 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: Component.H,v 1.28 2005/07/29 16:28:09 gerald Exp $ */ 00044 00045 00046 // STL 00047 #include <list> 00048 // QGAR 00049 #include <qgarlib/GenImage.H> 00050 namespace qgar 00051 { 00052 // Avoid #include's when not necessary 00053 class BoundingBox; 00054 template <class T> class GenPoint; 00055 class Maer; 00056 } 00057 00058 00059 00060 namespace qgar 00061 { 00062 00063 00064 /** 00065 * @class Component Component.H "qgarlib/Component.H" 00066 * @ingroup GRAPHPROC_CC 00067 * @brief A (connected) component. 00068 * 00069 * Representation of a component: 00070 * 00071 * - a pointer to the corresponding component image, 00072 * - a label, 00073 * - the label of the component in which the current component is included, 00074 * - a color, black or white (see qgar::QGEbw), 00075 * - the coordinates of the top left pixel of the component, 00076 * - the bounding box of the component, 00077 * - the MAER (see class qgar::Maer) of the component, 00078 * which is computed when first accessed, 00079 * - the contour points of the component (each point corresponds 00080 * to a change in the current contour direction, based on 8-connexity), 00081 * which are computed when first accessed or when the MAER is accessed, 00082 * - the area (in pixels) of the component. 00083 * 00084 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00085 * @date Mar 17, 2004 17:17 00086 * @since Qgar 2.1 00087 */ 00088 class Component 00089 { 00090 // ------------------------------------------------------------------- 00091 // T Y P E D E F I N I T I O N 00092 // ------------------------------------------------------------------- 00093 public: 00094 00095 /** @name Types related to a component */ 00096 // ============================ 00097 //@{ 00098 00099 /** 00100 * @brief Type of a component label. 00101 */ 00102 typedef short label_type; 00103 00104 //@} 00105 00106 // ------------------------------------------------------------------- 00107 // P U B L I C M E M B E R S 00108 // ------------------------------------------------------------------- 00109 public: 00110 00111 /** @name Constructors */ 00112 // ============ 00113 //@{ 00114 00115 /** 00116 * @brief Default constructor. 00117 */ 00118 Component(); 00119 00120 /** 00121 * @brief Create from full data. 00122 * 00123 * @param aPCompImg pointer to the corresponding component image 00124 * @param aLabel label 00125 * @param anInLabel label of comprising component 00126 * @param aBW color (black or white) 00127 * @param aXTopLeftPix X coordinate of the top left pixel 00128 * @param aYTopLeftPix Y coordinate of the top left pixel 00129 * @param aXTopLeft top left X coordinate of the bounding box 00130 * @param aYTopLeft top left Y coordinate of the bounding box 00131 * @param aXBottomRight bottom right X coordinate of the bounding box 00132 * @param aYBottomRight bottom right Y coordinate of the bounding box 00133 * @param anAreaPixels area (in pixels) 00134 */ 00135 Component(GenImage<label_type>* aPCompImg, 00136 int aLabel, 00137 int anInLabel, 00138 QGEbw aBW, 00139 int aXTopLeftPix, 00140 int aYTopLeftPix, 00141 int aXTopLeft, 00142 int aYTopLeft, 00143 int aXBottomRight, 00144 int aYBottomRight, 00145 int anAreaPixels); 00146 00147 /** 00148 * @brief Copy constructor. 00149 * @param aCComp a connected component 00150 * 00151 * @warning Perform a deep copy: The whole data 00152 * of the given connected component is duplicated. 00153 */ 00154 Component(const Component& aCComp); 00155 00156 //@} 00157 00158 00159 /** @name Destructor */ 00160 // ========== 00161 //@{ 00162 00163 /** 00164 * @brief Virtual destructor. 00165 */ 00166 virtual ~Component(); 00167 00168 //@} 00169 00170 00171 /** @name Labels */ 00172 // ====== 00173 //@{ 00174 00175 /** 00176 * @brief Maximum label. 00177 * 00178 * @warning This is a <b>static</b> data member. 00179 */ 00180 static const label_type _MAX_LABEL; 00181 00182 /** 00183 * @brief Label to express that an object is not yet labelled. 00184 * 00185 * @warning This is a <b>static</b> data member. 00186 */ 00187 static const label_type _NO_LABEL; 00188 00189 /** 00190 * @brief Get component label. 00191 */ 00192 inline label_type label() const; 00193 00194 /** 00195 * @brief Get label of comprising component. 00196 */ 00197 inline label_type inLabel() const; 00198 00199 //@} 00200 00201 00202 /** @name Color */ 00203 // ====== 00204 //@{ 00205 00206 /** 00207 * @brief Get color. 00208 */ 00209 inline QGEbw color() const; 00210 00211 //@} 00212 00213 00214 /** @name Coordinates */ 00215 // =========== 00216 //@{ 00217 00218 /** 00219 * @brief Get X coordinate of the top left pixel of the component. 00220 */ 00221 inline int xTopLeftPix() const; 00222 00223 /** 00224 * @brief Get Y coordinate of the top left pixel of the component. 00225 */ 00226 inline int yTopLeftPix() const; 00227 00228 /** 00229 * @brief Get bounding box. 00230 */ 00231 const BoundingBox& accessBoundingBox() const; 00232 00233 /** 00234 * @brief Get a copy of the bounding box. 00235 */ 00236 BoundingBox boundingBox() const; 00237 00238 /** 00239 * @brief Get density with regard to the bounding box. 00240 * 00241 * The density is the ratio between the area (number of pixels) 00242 * of the component and the area of its bounding box. 00243 */ 00244 double densityBox() const; 00245 00246 //@} 00247 00248 00249 /** @name Area */ 00250 // ==== 00251 //@{ 00252 00253 /** 00254 * @brief Get component area (in pixels). 00255 */ 00256 inline int areaPixels() const; 00257 00258 //@} 00259 00260 00261 /** @name Access to the MAER (Minimum-Area Encasing Rectangle) */ 00262 // ==================================================== 00263 //@{ 00264 00265 /** 00266 * @brief Get the MAER. 00267 * 00268 * @warning The MAER is computed and <b>stored</b> 00269 * when first accessed. 00270 */ 00271 const Maer& accessMaer(); 00272 00273 /** 00274 * @brief Get a copy of the MAER. 00275 * 00276 * @warning The MAER is computed and <b>stored</b> 00277 * when first accessed. 00278 */ 00279 Maer maer(); 00280 00281 /** 00282 * @brief Get MAER area in pixels. 00283 * 00284 * @warning 00285 * - The MAER is computed and <b>stored</b> when first accessed. 00286 * - The area of the MAER is calculated in the <b>continuous</b> 00287 * 2D space and is provided by the corresponding data of the 00288 * object representing the MAER: 00289 * <b>(aComponent.accessMaer())->area()</b>, for example. 00290 * As connected components are constructed in the 2D 00291 * <b>discrete</b> space, an <b>approximated value</b> of 00292 * the MAER area is also available in pixels. 00293 */ 00294 int maerAreaPixels(); 00295 00296 /** 00297 * @brief Get density with regard to the MAER. 00298 * 00299 * The density is the ratio between the area (number of pixels) 00300 * of the component and the area of its MAER. 00301 * 00302 * @warning The MAER is computed and <b>stored</b> 00303 * when first accessed. 00304 */ 00305 double densityMaer(); 00306 00307 //@} 00308 00309 00310 /** @name Contour */ 00311 // ======= 00312 //@{ 00313 00314 /** 00315 * @brief Get a pointer to the component contour. 00316 * 00317 * @warning 00318 * - The component contour is computed and <b>stored</b> 00319 * when first accessed 00320 * - The coordinates of the contour points are 00321 * <b>double</b> numbers 00322 */ 00323 const std::list<DPoint>& accessContour(); 00324 00325 /** 00326 * @brief Get a copy of the component contour. 00327 * 00328 * @warning 00329 * - The component contour is computed and <b>stored</b> 00330 * when first accessed 00331 * - The coordinates of the contour points are 00332 * <b>double</b> numbers 00333 */ 00334 std::list<DPoint> contour(); 00335 00336 //@} 00337 00338 00339 /** @name Operators */ 00340 // ========= 00341 //@{ 00342 00343 /** 00344 * @brief Assignment. 00345 * @param aCComp connected component to be assigned 00346 */ 00347 Component& operator=(const Component& aCComp); 00348 00349 //@} 00350 00351 00352 // ------------------------------------------------------------------- 00353 // P R O T E C T E D M E M B E R S 00354 // ------------------------------------------------------------------- 00355 protected: 00356 00357 /** @name Pixel map of the corresponding component image */ 00358 // ============================================== 00359 //@{ 00360 00361 /** 00362 * @brief Pointer to the corresponding component image. 00363 */ 00364 GenImage<label_type>* _pCompImg; 00365 00366 //@} 00367 00368 00369 /** @name Labels */ 00370 // ====== 00371 //@{ 00372 00373 /** 00374 * @brief Label of the component. 00375 * 00376 * @warning <b>It must be an integer number: long, short...</b> 00377 */ 00378 label_type _label; 00379 00380 /** 00381 * @brief Label of the comprising component. 00382 */ 00383 label_type _inLabel; 00384 00385 //@} 00386 00387 00388 /** @name Color */ 00389 // ===== 00390 //@{ 00391 00392 /** 00393 * @brief Color. 00394 */ 00395 QGEbw _color; 00396 00397 //@} 00398 00399 00400 /** @name Coordinates */ 00401 // =========== 00402 //@{ 00403 00404 /** 00405 * @brief X coordinate of the top left pixel of the component. 00406 */ 00407 int _xTopLeftPix; 00408 00409 /** 00410 * @brief Y coordinate of the top left pixel of the component. 00411 */ 00412 int _yTopLeftPix; 00413 00414 /** 00415 * @brief Bounding box. 00416 */ 00417 BoundingBox _boundingBox; 00418 00419 //@} 00420 00421 00422 /** @name Area */ 00423 // ==== 00424 //@{ 00425 00426 /** 00427 * @brief Component effective area (in pixels). 00428 */ 00429 int _areaPixels; 00430 00431 //@} 00432 00433 00434 /** @name MAER (Minimum-Area Encasing Rectangle) */ 00435 // ====================================== 00436 //@{ 00437 00438 /** 00439 * @brief Minimum-Area Enclosing Rectangle (MAER). 00440 */ 00441 Maer* _maer; 00442 00443 /** 00444 * @brief Minimum-Area Enclosing Rectangle (MAER). 00445 */ 00446 int _maerAreaPixels; 00447 00448 //@} 00449 00450 00451 /** @name Contour */ 00452 // ======= 00453 //@{ 00454 00455 /** 00456 * @brief List of the points of the contour component. 00457 * 00458 * Each point corresponds to a change in the current contour 00459 * direction, based on 8-connexity. 00460 */ 00461 std::list<DPoint> _contour; 00462 00463 //@} 00464 00465 00466 // ------------------------------------------------------------------- 00467 // P R I V A T E M E M B E R S 00468 // ------------------------------------------------------------------- 00469 private: 00470 00471 // ================================================================= 00472 /** @name Tables to compute coordinates during contour following 00473 00474 @verbatim 00475 +---+---+---+ 00476 | | 1 | 2 | 00477 +---+---+---+ 00478 | 7 | *-->3 | 00479 +---+---+---+ 00480 | 6 | 5 | 4 | 00481 +---+---+---+ 00482 @endverbatim 00483 00484 The outside of the component is always on the left when moving 00485 along the contour direction. The figure above gives an example: 00486 when following a contour in the EAST direction, the first new 00487 possible contour point (1) is at NORTH of the current point (*), 00488 the second (2) at NORTH-EAST, and so on. 00489 00490 @verbatim 00491 new contour directions (see table _s_new_dir) 00492 W NW N NE E SE S SW W NW N NE E SE 00493 00494 indexes 0 1 2 3 4 5 6 7 8 9 10 11 12 13 00495 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00496 _s_incr_x | -1| -1| 0 | 1 | 1 | 1 | 0 | -1| -1| -1| 0 | 1 | 1 | 1 | 00497 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00498 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00499 _s_incr_y | 0 | -1| -1| -1| 0 | 1 | 1 | 1 | 0 | -1| -1| -1| 0 | 1 | 00500 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00501 N NE E SE S SW W NW 00502 entries corresponding to current contour directions 00503 @endverbatim 00504 00505 The _s_incr_x (resp. y) table (see figure above) contains the X 00506 (resp. Y) increment to get the X (resp. Y) coordinates of the 7 00507 possible next contour points (points 1 to 7 on 1st figure) from 00508 the X (resp. Y) coordinate of the current point (*). The current 00509 contour direction (EAST on 1st figure) determines the first index 00510 to enter the tables. 00511 00512 @verbatim 00513 new contour directions 00514 W NW N NE E SE S SW W NW N NE E SE 00515 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00516 _s_new_dir | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 00517 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00518 @endverbatim 00519 00520 Once a new contour point is found, table _s_new_dir gives the 00521 corresponding new contour direction, using the index corresponding 00522 to the new contour point in table _s_incr_x or _s_incr_y. 00523 */ 00524 // ================================================================= 00525 //@{ 00526 00527 /** 00528 * @brief Table for X coordinates increments. 00529 */ 00530 static const int _s_incr_x[14]; 00531 00532 /** 00533 * @brief Table for Y coordinates increments. 00534 */ 00535 static const int _s_incr_y[14]; 00536 00537 /** 00538 * @brief Table for new contour directions. 00539 */ 00540 static const int _s_new_dir[14]; 00541 00542 //@} 00543 00544 00545 /** @name Auxiliary functions */ 00546 // =================== 00547 //@{ 00548 00549 /** 00550 * @brief Compute the external contour (hull) of the component. 00551 * 00552 @verbatim 00553 . . . . . . . . . . . . . . . . . . 00554 . . . . * . . . . . . . . C . . . . 00555 . . . * . * . . . . . . C . C . . . 00556 . . * . * . * . . . . C . * . C . . 00557 . * . * * * . * . . C . * * * . C . 00558 . . * . * . * . . . . C . * . C . . 00559 . . . * . * . . . . . . C . C . . . 00560 . . . . * . . . . . . . . C . . . . 00561 . . . . . . . . . . . . . . . . . . 00562 @endverbatim 00563 * 00564 * In the example above, '*' is a black pixel, '.' is a white 00565 * pixel, and 'C' is a pixel of the resulting contour. 00566 */ 00567 void PRIVATEcomputeContour(); 00568 00569 /** 00570 * @brief Compute the MAER (Minimum-Area Encasing Rectangle). 00571 */ 00572 void PRIVATEcomputeMaer(); 00573 00574 //@} 00575 00576 // ------------------------------------------------------------------- 00577 }; // class Component 00578 00579 00580 00581 00582 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00583 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00584 // I N L I N E F U N C T I O N S I M P L E M E N T A T I O N 00585 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00586 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00587 00588 00589 // ===== 00590 // LABEL 00591 // ===== 00592 00593 // GET COMPONENT LABEL 00594 inline Component::label_type 00595 Component::label() const 00596 { 00597 return _label; 00598 } 00599 00600 // GET COMPRISING COMPONENT LABEL 00601 inline Component::label_type 00602 Component::inLabel() const 00603 { 00604 return _inLabel; 00605 } 00606 00607 00608 // ====== 00609 // COLOR 00610 // ====== 00611 00612 // GET COLOR. 00613 inline QGEbw 00614 Component::color() const 00615 { 00616 return _color; 00617 } 00618 00619 // =========== 00620 // COORDINATES 00621 // =========== 00622 00623 // GET X COORDINATE OF THE TOP LEFT PIXEL 00624 inline int 00625 Component::xTopLeftPix() const 00626 { 00627 return _xTopLeftPix; 00628 } 00629 00630 // GET Y COORDINATE OF THE TOP LEFT PIXEL 00631 inline int 00632 Component::yTopLeftPix() const 00633 { 00634 return _yTopLeftPix; 00635 } 00636 00637 00638 // ==== 00639 // AREA 00640 // ==== 00641 00642 // GET COMPONENT AREA. 00643 inline int 00644 Component::areaPixels() const 00645 { 00646 return _areaPixels; 00647 } 00648 00649 00650 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00651 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00652 // END OF INLINE FUNCTIONS IMPLEMENTATION 00653 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00654 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00655 00656 00657 } // namespace qgar 00658 00659 00660 #endif /* __COMPONENT_H_INCLUDED__ */