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 __FREEMANCHAIN_H_INCLUDED__ 00029 #define __FREEMANCHAIN_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file FreemanChain.H 00034 * @brief Header file of class qgar::FreemanChain. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date December 19, 2003 17:30 00038 * @since Qgar 2.1.1 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: FreemanChain.H,v 1.15 2005/07/13 16:29:01 masini Exp $ */ 00044 00045 00046 00047 // STL 00048 #include <list> 00049 // QGAR 00050 #include <qgarlib/AbstractGenPointChain.H> 00051 #include <qgarlib/FreemanCode.H> 00052 namespace qgar 00053 { 00054 // Avoid #include's when not necessary 00055 template <class T> class GenPoint; 00056 } 00057 00058 00059 00060 namespace qgar 00061 { 00062 00063 00064 /** 00065 * @class FreemanChain FreemanChain.H "qgarlib/FreemanChain.H" 00066 * @ingroup DS_POINT 00067 * @brief Chain of Freeman codes. 00068 * 00069 * A Freeman chain represents a series of consecutive points, 00070 * <b>in an integer (<i>i.e.</i> discrete) coordinate system</b>. 00071 * It is coded as a series of <b>integer</b> vectors, 00072 * defined by pairs (direction, length), starting from a point 00073 * of given coordinates: 00074 @verbatim 00075 etc. 00076 * 00077 * 00078 POINT-2 @ ^ 00079 * | 00080 * | 00081 ^ * | 00082 | * | 00083 DIRECTION-2 | * LENGTH-2 00084 | * | 00085 * | 00086 * | 00087 (STARTING) DIRECTION-1 --> * | 00088 POINT-0 @**********************@ V 00089 <------ LENGTH-1 ------> POINT-1 00090 @endverbatim 00091 * 00092 * A direction is coded using predefined enum type qgar::QGEdirection. 00093 * As the origin of the coordinates system in images is at top left 00094 * corner, North and South are upside down for more convenience: 00095 @verbatim 00096 (0,0) +---------------------------------------------> X 00097 | 00098 | QGE_DIRECTION_N 00099 | | 00100 | QGE_DIRECTION_NW \ | / QGE_DIRECTION_NE 00101 | \|/ 00102 | QGE_DIRECTION_W -----+----- QGE_DIRECTION_E 00103 | /|\ 00104 | QGE_DIRECTION_SW / | \ QGE_DIRECTION_SE 00105 | | 00106 | QGE_DIRECTION_S 00107 Y V 00108 @endverbatim 00109 * 00110 * A Freeman chain is implemented using a STL list of Freeman codes, 00111 * instances of class qgar::FreemanCode: 00112 @verbatim 00113 _iter (current point) 00114 | 00115 V 00116 +-----+ +----+ +----+ +----+ 00117 |North| | D1 | | D2 | | Dn | 00118 _chain +-----+<==>+----+<==>+----+<==> ... <==>+----+ 00119 | 0 | | L1 | | L2 | | Ln | 00120 +-----+ +----+ +----+ +----+ 00121 00122 @endverbatim 00123 * The direction of the first code is always North (qgar::QGE_DIRECTION_N, 00124 * the first value of the qgar::QGEdirection predefined enum type) 00125 * and the length of the first code is always <b>0</b>: The first code 00126 * represents the first point of the chain (a null vector from the given 00127 * starting point). In this way, the complete chain of points is 00128 * consistently coded, which allows easier algorithm implementations. 00129 * 00130 * An (internal) iterator, qgar::FreemanChain::_iter, allows bidirectional 00131 * traversal of the chain. The validity of the iterator is preserved by any 00132 * legal operation on the chain, unless the chain is empty. 00133 * 00134 * Three points are permanently available as effective points, <i>i.e.</i> 00135 * instances of class qgar::GenPoint<int>: 00136 * - the starting/first point of the chain (qgar::FreemanChain::_first), 00137 * - the current point of the chain (qgar::FreemanChain::_current), 00138 * that is pointed by iterator qgar::FreemanChain::_iter 00139 * - the last point of the chain (qgar::FreemanChain::_last) 00140 * 00141 * Use cases of a Freeman chain: 00142 * - To set the iterator to the beginning (resp. end) of the chain, 00143 * function qgar::FreemanChain::setToBegin 00144 * (resp. qgar::FreemanChain::setToEnd) 00145 * - To test if the iterator points to the beginning (resp. end) 00146 * of the chain, function qgar::FreemanChain::isAtBegin 00147 * (resp. qgar::FreemanChain::isAtEnd) 00148 * - To test if the chain includes at least one point after (resp. before) 00149 * the current point, function qgar::FreemanChain::hasNext 00150 * (resp. qgar::FreemanChain::hasPrevious) 00151 * - To move to the next (resp. previous) point, function 00152 * qgar::FreemanChain::moveNext (resp. qgar::FreemanChain::movePrevious) 00153 * - To get the current point, functions qgar::FreemanChain::current 00154 * or qgar::FreemanChain::accessCurrent 00155 * - To get the next (resp. previous) point, functions 00156 * qgar::FreemanChain::next or qgar::FreemanChain::accessNext 00157 * (resp. qgar::FreemanChain::previous or qgar::FreemanChain::accessPrevious) 00158 * - To insert a new point at the beginning (resp. end) of the chain, 00159 * function qgar::FreemanChain::push_front 00160 * (resp. qgar::FreemanChain::push_back) 00161 * 00162 * @warning <b>A Freeman chain is not an appropriate way of representing 00163 * a chain of points if efficiency is required for insertions or chain 00164 * traversals.</b> Class qgar::GenPointChain should be better used in this 00165 * case. A STL list of the points coded by a Freeman chain can be also 00166 * obtained using function qgar::FreemanChain::pointList. 00167 * 00168 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>, 00169 * from previous work by Karl Tombre 00170 * @date December 19, 2003 17:30 00171 * @since Qgar 2.1.1 00172 */ 00173 class FreemanChain 00174 00175 : public AbstractGenPointChain<int> 00176 00177 { 00178 // ------------------------------------------------------------------- 00179 // P U B L I C M E M B E R S 00180 // ------------------------------------------------------------------- 00181 public: 00182 00183 /** @name Constructors */ 00184 // ============ 00185 //@{ 00186 00187 ///** 00188 // * @brief Default constructor. 00189 // * 00190 // * @warning No default constructor is defined. 00191 // */ 00192 //FreemanChain(); 00193 00194 /** 00195 * @brief Copy constructor. 00196 * 00197 * @param aFreemanCh a Freeman chain 00198 * 00199 * @warning The iterator points to the beginning of the chain. 00200 */ 00201 FreemanChain(const FreemanChain& aFreemanCh); 00202 00203 /** 00204 * @brief Construct from a point, that becomes the current point. 00205 * @param aPt a point (integer coordinates) 00206 * 00207 * The iterator points to this point. 00208 */ 00209 FreemanChain(const GenPoint<int>& aPt); 00210 00211 /** 00212 * @brief Construct from given point, direction and length. 00213 * 00214 * @param aPt a point (integer coordinates) 00215 * @param aDir direction code of the initial part of chain 00216 * @param aLength length of the initial part of chain 00217 * 00218 * The iterator points to the end of the chain. 00219 * 00220 * @warning The given length is supposed to be different from zero. 00221 * Otherwise, the validity of the resulting chain is absolutely not 00222 * guaranteed. 00223 */ 00224 FreemanChain(const GenPoint<int>& aPt, 00225 QGEdirection aDir, 00226 unsigned int aLength); 00227 00228 //@} 00229 00230 00231 /** @name Destructor */ 00232 // ========== 00233 //@{ 00234 00235 /** 00236 * @brief Virtual destructor. 00237 */ 00238 virtual ~FreemanChain(); 00239 00240 //@} 00241 00242 00243 /** @name Access to chain characteristics */ 00244 // =============================== 00245 //@{ 00246 00247 /** 00248 * @brief Is current chain empty? 00249 */ 00250 virtual bool empty() const; 00251 00252 /** 00253 * @brief Get chain length (number of points). 00254 */ 00255 virtual int size() const; 00256 00257 //@} 00258 00259 00260 /** @name Iterator */ 00261 // ======== 00262 //@{ 00263 00264 /** 00265 * @brief Make the internal iterator point to the beginning 00266 * (first point) of the chain, that becomes the current point. 00267 * 00268 * @warning The chain is supposed not to be empty. 00269 */ 00270 virtual void setToBegin(); 00271 00272 /** 00273 * @brief Make the internal iterator point to the end 00274 * (last point) of the chain, that becomes the current point. 00275 * 00276 * @warning The chain is supposed not to be empty. 00277 */ 00278 virtual void setToEnd(); 00279 00280 /** 00281 * @brief Does internal iterator points to the beginning of the chain? 00282 */ 00283 virtual bool isAtBegin() const; 00284 00285 /** 00286 * @brief Does internal iterator points to the end of the chain? 00287 */ 00288 virtual bool isAtEnd() const; 00289 00290 /** 00291 * @brief Is there a point after the current point? 00292 * 00293 * @warning The chain is supposed not to be empty. 00294 */ 00295 virtual bool hasNext() const; 00296 00297 /** 00298 * @brief Is there a point before the current point? 00299 * 00300 * @warning The chain is supposed not to be empty. 00301 */ 00302 virtual bool hasPrevious() const; 00303 00304 /** 00305 * @brief Move to next point, that becomes the current point. 00306 * 00307 * @warning The chain is supposed not to be empty. 00308 */ 00309 virtual void moveNext(); 00310 00311 /** 00312 * @brief Move to previous point, that becomes the current point. 00313 * 00314 * @warning The chain is supposed not to be empty. 00315 */ 00316 virtual void movePrevious(); 00317 00318 //@} 00319 00320 00321 /** @name Access to points */ 00322 // ================ 00323 //@{ 00324 00325 /** 00326 * @brief Get the first point. 00327 * 00328 * @warning The chain is supposed not to be empty. 00329 */ 00330 virtual const GenPoint<int>& accessFront() const; 00331 00332 /** 00333 * @brief Get a copy of the first point. 00334 * 00335 * @warning The chain is supposed not to be empty. 00336 */ 00337 virtual GenPoint<int> front() const; 00338 00339 /** 00340 * @brief Get the last point. 00341 * 00342 * @warning The chain is supposed not to be empty. 00343 */ 00344 virtual const GenPoint<int>& accessBack() const; 00345 00346 /** 00347 * @brief Get a copy of the last point. 00348 * 00349 * @warning The chain is supposed not to be empty. 00350 */ 00351 virtual GenPoint<int> back() const; 00352 00353 /** 00354 * @brief Get the current point. 00355 * 00356 * @warning The chain is supposed not to be empty. 00357 */ 00358 virtual const GenPoint<int>& accessCurrent() const; 00359 00360 /** 00361 * @brief Get a copy of the current point. 00362 * 00363 * @warning The chain is supposed not to be empty. 00364 */ 00365 virtual GenPoint<int> current() const; 00366 00367 /** 00368 * @brief Get the successor of the current point. 00369 * 00370 * @warning The chain is supposed not to be empty, 00371 * and the iterator is supposed not to point to the last point. 00372 */ 00373 virtual const GenPoint<int>& accessNext(); 00374 00375 /** 00376 * @brief Get a copy of the successor of the current point. 00377 * 00378 * @warning The chain is supposed not to be empty, 00379 * and the iterator is supposed not to point to the last point. 00380 */ 00381 virtual GenPoint<int> next(); 00382 00383 /** 00384 * @brief Get the predecessor of the current point. 00385 * 00386 * @warning The chain is supposed not to be empty, 00387 * and the iterator is supposed not to point to the first point. 00388 */ 00389 virtual const GenPoint<int>& accessPrevious(); 00390 00391 /** 00392 * @brief Get a copy of the predecessor of the current point. 00393 * 00394 * @warning The chain is supposed not to be empty, 00395 * and the iterator is supposed not to point to the first point. 00396 */ 00397 virtual GenPoint<int> previous(); 00398 00399 //@} 00400 00401 00402 /** @name Access to Freeman codes */ 00403 // ======================= 00404 //@{ 00405 00406 /** 00407 * @brief Get the (STL) list of Freeman codes. 00408 * 00409 * The first element is an extra code including <b>qgar::QGE_DIRECTION_N</b> 00410 * as direction and <b>0</b> as length: 00411 @verbatim 00412 +-----+ +----+ +----+ +----+ 00413 |North| | D1 | | D2 | | Dn | 00414 +-----+ <==> +----+ <==> +----+ <==> ... <==> +----+ 00415 | 0 | | L1 | | L2 | | Ln | 00416 +-----+ +----+ +----+ +----+ 00417 @endverbatim 00418 * This implementation allows an easier implementation of algorithms. 00419 * 00420 * Using this function to traverse the chain is much more efficient 00421 * than using appropriate member functions like 00422 * qgar::FreemanChain::setToBegin, qgar::FreemanChain::hasNext, 00423 * qgar::FreemanChain::moveNext, etc. In particular, the points 00424 * represented by the chain may be obtained by applying the successive 00425 * Freeman codes of the chain to a point initialized to the first point 00426 * of the chain, in the following way: 00427 @verbatim 00428 const std::list<FreemanCode>& lFc = myChain.accessCodesList(); 00429 GenPoint<int> p = myChain.first(); 00430 00431 for (std::list<FreemanCode>::const_iterator it = lFc.begin(); 00432 it != lFc.end(); 00433 it++) 00434 { 00435 // Current point 00436 p = (*it).toPoint(p); 00437 // Processing continues... 00438 ... 00439 } 00440 @endverbatim 00441 */ 00442 const std::list<FreemanCode>& accessCodesList() const; 00443 00444 //@} 00445 00446 00447 /** @name Insertion */ 00448 // ========= 00449 //@{ 00450 00451 /** 00452 * @brief Insert a point at the beginning of the chain. 00453 * @param aPt a point 00454 * 00455 * @warning 00456 * - <b>When the chain is not empty, the new point is supposed 00457 * to be consistent with the coding of the chain: All the points 00458 * of the segment joining the first point of the chain to the 00459 * new point must be strictly aligned along one of the 8 Freeman 00460 * directions.</b> 00461 * - <b>A new point is always inserted in the chain, even when 00462 * the given point is the same as the first point of the chain 00463 * or is aligned with the first segment of the chain.</b> 00464 */ 00465 virtual void push_front(const GenPoint<int>& aPt); 00466 00467 /** 00468 * @brief Insert a point whose location is defined by the given 00469 * Freeman code, starting from the first point of the chain. 00470 * @param aCode a Freeman code 00471 * 00472 * @warning 00473 * - <b>The chain is supposed not to be empty.</b> 00474 * - <b>A new point is always inserted in the chain, even when 00475 * the direction of the given Freeman code is the same as 00476 * the direction of the first Freeman code of the chain, or when 00477 * it is the opposite of the direction of the first Freeman code 00478 * of the chain.</b> 00479 */ 00480 void push_front(const FreemanCode& aCode); 00481 00482 /** 00483 * @brief Insert a point at the end of the chain. 00484 * @param aPt a point 00485 * 00486 * @warning 00487 * - <b>When the chain is not empty, the new point is supposed 00488 * to be consistent with the coding of the chain: All the points 00489 * of the segment joining the last point of the chain to the 00490 * new point must be strictly aligned along one of the 8 Freeman 00491 * directions.</b> 00492 * - <b>A new point is always inserted in the chain, even when 00493 * the given point is the same as the last point of the chain 00494 * or is aligned with the last segment of the chain.</b> 00495 */ 00496 virtual void push_back(const GenPoint<int>& aPt); 00497 00498 /** 00499 * @brief Insert a point whose location is defined by the given 00500 * Freeman code, starting from the last point of the chain. 00501 * @param aCode a Freeman code 00502 * 00503 * @warning 00504 * - <b>The chain is supposed not to be empty.</b> 00505 * - <b>A new point is always inserted in the chain, when 00506 * the direction of the given Freeman code is the same as 00507 * the direction of the last Freeman code of the chain, or when 00508 * it is the opposite of the direction of the last Freeman code 00509 * of the chain.</b> 00510 */ 00511 void push_back(const FreemanCode& aCode); 00512 00513 //@} 00514 00515 00516 /** @name Transformations */ 00517 // =============== 00518 //@{ 00519 00520 /** 00521 * @brief Reverse elements order in the list. 00522 * 00523 * @warning The internal iterator points to the same <i>element</i> 00524 * of the chain (but the content of this element has changed) once 00525 * the operation is completed. 00526 */ 00527 virtual void reverse(); 00528 00529 //@} 00530 00531 00532 /** @name Conversions */ 00533 // =========== 00534 //@{ 00535 00536 /** 00537 * @brief Convert into a (STL) list of points having integer coordinates. 00538 */ 00539 virtual std::list< GenPoint<int> > toPointList() const; 00540 00541 /** 00542 * @brief Convert into a (STL) list of points having float coordinates. 00543 */ 00544 virtual std::list< GenPoint<float> > toFPointList() const; 00545 00546 /** 00547 * @brief Convert into a (STL) list of points having double coordinates. 00548 */ 00549 virtual std::list< GenPoint<double> > toDPointList() const; 00550 00551 //@} 00552 00553 00554 /** @name Operators */ 00555 // ========= 00556 //@{ 00557 00558 /** 00559 * @brief Assignment. 00560 * @param aFreemanCh a Freeman chain 00561 * 00562 * @warning The internal iterator points to the beginning of the chain. 00563 */ 00564 FreemanChain& operator=(const FreemanChain& aFreemanCh); 00565 00566 //@} 00567 00568 00569 // ------------------------------------------------------------------- 00570 // P R O T E C T E D M E M B E R S 00571 // ------------------------------------------------------------------- 00572 protected: 00573 00574 00575 /** @name Representation of a Freeman chain */ 00576 // ================================= 00577 //@{ 00578 00579 /** 00580 * @brief The (STL) list of Freeman codes defining the points 00581 * of the chain. 00582 */ 00583 std::list<FreemanCode> _chain; 00584 00585 /** 00586 * @brief Iterator on the list of Freeman codes. 00587 */ 00588 std::list<FreemanCode>::iterator _iter; 00589 00590 //@} 00591 00592 00593 /** @name Pre-computed points */ 00594 // =================== 00595 //@{ 00596 00597 /** 00598 * @brief First point of the chain. 00599 */ 00600 GenPoint<int> _first; 00601 00602 /** 00603 * @brief Current point of the chain. 00604 */ 00605 GenPoint<int> _current; 00606 00607 /** 00608 * @brief Last point of the chain. 00609 */ 00610 GenPoint<int> _last; 00611 00612 //@} 00613 00614 00615 // ------------------------------------------------------------------- 00616 // P R I V A T E M E M B E R S 00617 // ------------------------------------------------------------------- 00618 private: 00619 00620 00621 /** @name Constructors */ 00622 // ============ 00623 //@{ 00624 00625 /** 00626 * @brief Disabled default constructor. 00627 * 00628 * The default constructor belongs to the private section 00629 * so that a client cannot use it. 00630 */ 00631 FreemanChain(); 00632 00633 00634 // ------------------------------------------------------------------- 00635 }; // class FreemanChain 00636 00637 00638 } // namespace qgar 00639 00640 00641 #endif /* __FREEMANCHAIN_H_INCLUDED__ */