00001 /*---------------------------------------------------------------------* 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2004 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 license. | 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 __FREEMANCODE_H_INCLUDED__ 00029 #define __FREEMANCODE_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file FreemanCode.H 00034 * @brief Header file of class qgar::FreemanCode. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date February 3, 2004 17:17 00038 * @since Qgar 2.1.1 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete. 00043 /* $Id: FreemanCode.H,v 1.14 2005/10/14 17:05:46 masini Exp $ */ 00044 00045 00046 00047 // STD 00048 #include <iostream> 00049 #include <string> 00050 // QGAR 00051 #include <qgarlib/image.H> 00052 #include <qgarlib/ISerializable.H> 00053 #include <qgarlib/primitives.H> 00054 #include <qgarlib/QgarErrorInvalidArg.H> 00055 00056 00057 00058 namespace qgar 00059 { 00060 00061 00062 /** 00063 * @class FreemanCode FreemanCode.H "qgarlib/FreemanCode.H" 00064 * @ingroup DS_POINT 00065 * @brief A Freeman code, defined as a pair (direction, length). 00066 * 00067 * A direction is coded using predefined enum type qgar::QGEdirection. 00068 * As the origin of the coordinates system in images is at top left 00069 * corner, North and South are upside down for more convenience: 00070 @verbatim 00071 (0,0) +---------------------------------------------> X 00072 | 00073 | QGE_DIRECTION_N 00074 | | 00075 | QGE_DIRECTION_NW \ | / QGE_DIRECTION_NE 00076 | \|/ 00077 | QGE_DIRECTION_W -----+----- QGE_DIRECTION_E 00078 | /|\ 00079 | QGE_DIRECTION_SW / | \ QGE_DIRECTION_SE 00080 | | 00081 | QGE_DIRECTION_S 00082 Y V 00083 @endverbatim 00084 * 00085 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00086 * @date February 3, 2004 17:17 00087 * @since Qgar 2.1.1 00088 */ 00089 class FreemanCode 00090 00091 : public ISerializable 00092 00093 { 00094 // ------------------------------------------------------------------- 00095 // P U B L I C M E M B E R S 00096 // ------------------------------------------------------------------- 00097 public: 00098 00099 /** @name Constructors */ 00100 // ============ 00101 //@{ 00102 /** 00103 * @brief Default constructor. 00104 * 00105 * Direction is initialized to <b>qgar::QGE_DIRECTION_N</b> 00106 * and length to <b>0</b>. 00107 */ 00108 FreemanCode(); 00109 00110 /** 00111 * @brief Copy constructor. 00112 * @param aCode a Freeman code 00113 */ 00114 FreemanCode(const FreemanCode& aCode); 00115 00116 /** 00117 * @brief Initialize with a direction and a length. 00118 * @param aDir a direction 00119 * @param aLength a length 00120 * 00121 * @warning Length may be initialized to <b>0</b>. 00122 */ 00123 FreemanCode(QGEdirection aDir, unsigned int aLength); 00124 //@} 00125 00126 00127 /** @name Destructor */ 00128 // ========== 00129 //@{ 00130 /** 00131 * @brief Virtual destructor. 00132 */ 00133 virtual ~FreemanCode(); 00134 //@} 00135 00136 00137 /** @name Access */ 00138 // ====== 00139 //@{ 00140 /** 00141 * @brief Get direction. 00142 */ 00143 inline QGEdirection direction() const; 00144 00145 /** 00146 * @brief Get length. 00147 */ 00148 inline int length() const; 00149 //@} 00150 00151 00152 /** @name Transformation */ 00153 // ============== 00154 //@{ 00155 /** 00156 * @brief Set direction. 00157 * @param aDir a direction 00158 */ 00159 inline void setDir(QGEdirection aDir); 00160 00161 /** 00162 * @brief Set length. 00163 * @param aLength a direction 00164 * 00165 * @warning Length may be initialized to <b>0</b>. 00166 */ 00167 inline void setLength(unsigned int aLength); 00168 00169 /** 00170 * @brief Set both direction and length. 00171 * @param aDir a direction 00172 * @param aLength a length 00173 * 00174 * @warning Length may be initialized to <b>0</b>. 00175 */ 00176 inline void setDirLength(QGEdirection aDir, unsigned int aLength); 00177 //@} 00178 00179 00180 /** @name Conversions */ 00181 // =========== 00182 //@{ 00183 /** 00184 * @brief Return the point at the location defined by the current Freeman 00185 * code, starting from the given point. 00186 * @param aPt a point 00187 * 00188 * @exception qgar::QgarErrorInvalidArg (unknown direction) 00189 */ 00190 template <class T> 00191 GenPoint<T> toPoint(const GenPoint<T>& aPt) const; 00192 00193 /** 00194 * @brief Return the point at the location defined by the current Freeman 00195 * code, whose direction is changed into its opposite, starting 00196 * from the given point. 00197 * @param aPt a point 00198 * 00199 * @exception qgar::QgarErrorInvalidArg (unknown direction) 00200 */ 00201 template <class T> 00202 GenPoint<T> toOppositePoint(const GenPoint<T>& aPt) const; 00203 //@} 00204 00205 00206 /** @name Operators */ 00207 // ========= 00208 //@{ 00209 /** 00210 * @brief Assignment operator. 00211 * @param aCode a Freeman code 00212 */ 00213 FreemanCode& operator=(const FreemanCode& aCode); 00214 //@} 00215 00216 00217 /** @name Serialization/deserialization */ 00218 // ============================= 00219 //@{ 00220 /** 00221 * @brief Deserializes the current Freeman code from an input stream. 00222 * @param anInStream the input stream 00223 * 00224 * A serialized Freeman code is represented as: 00225 @verbatim 00226 FreemanCode ( <DIRECTION> ) ( <LENGTH> ) 00227 @endverbatim 00228 * 00229 * @see qgar::qgReadObjName, qgar::qgReadObjData 00230 */ 00231 virtual std::istream& read(std::istream& anInStream); 00232 00233 00234 /** 00235 * @brief Serializes the current Freeman code to an input stream. 00236 * @param anOutStream the output stream 00237 * 00238 * A serialized Freeman code is represented as: 00239 @verbatim 00240 FreemanCode ( <DIRECTION> ) ( <LENGTH> ) 00241 @endverbatim 00242 */ 00243 virtual std::ostream& write(std::ostream& anOutStream) const; 00244 //@} 00245 00246 // ------------------------------------------------------------------- 00247 // P R O T E C T E D M E M B E R S 00248 // ------------------------------------------------------------------- 00249 protected: 00250 00251 /** @name Representation of a Freeman code */ 00252 // ================================ 00253 //@{ 00254 /** 00255 * @brief The direction code. 00256 */ 00257 QGEdirection _direction; 00258 00259 /** 00260 * @brief The length. 00261 */ 00262 int _length; 00263 //@} 00264 00265 // ------------------------------------------------------------------- 00266 // P R I V A T E M E M B E R S 00267 // ------------------------------------------------------------------- 00268 private: 00269 00270 /** @name Auxiliaries */ 00271 // =========== 00272 //@{ 00273 /** 00274 * @brief Return the point located at given length in given direction 00275 * from the given point. 00276 * @param aPt a point 00277 * @param aDir a direction 00278 * @param aLength a length 00279 */ 00280 template <class T> 00281 GenPoint<T> toPointAUX(const GenPoint<T>& aPt, 00282 QGEdirection aDir, 00283 unsigned int aLength) const 00284 throw(QgarErrorInvalidArg); 00285 //@} 00286 00287 // ------------------------------------------------------------------- 00288 }; // class FreemanCode 00289 00290 00291 00292 00293 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00294 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00295 // 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 00296 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00297 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00298 00299 00300 // ====== 00301 // ACCESS 00302 // ====== 00303 00304 // Get direction 00305 00306 QGEdirection 00307 FreemanCode::direction() const 00308 { 00309 return _direction; 00310 } 00311 00312 // Get length 00313 00314 int 00315 FreemanCode::length() const 00316 { 00317 return _length; 00318 } 00319 00320 00321 // ============== 00322 // TRANSFORMATION 00323 // ============== 00324 00325 // Set direction 00326 00327 void 00328 FreemanCode::setDir(QGEdirection aDir) 00329 { 00330 _direction = aDir; 00331 } 00332 00333 // Set length 00334 00335 void 00336 FreemanCode::setLength(unsigned int aLength) 00337 { 00338 _length = aLength; 00339 } 00340 00341 // Set both direction and length 00342 00343 void 00344 FreemanCode::setDirLength(QGEdirection aDir, unsigned int aLength) 00345 { 00346 _direction = aDir; 00347 _length = aLength; 00348 } 00349 00350 00351 // =========== 00352 // CONVERSIONS 00353 // =========== 00354 00355 // Apply the current Freeman code to the given point 00356 00357 template <class T> 00358 GenPoint<T> 00359 FreemanCode::toPoint(const GenPoint<T>& aPt) const 00360 { 00361 return toPointAUX(aPt, _direction, _length); 00362 } 00363 00364 00365 // Apply the current Freeman code to the given point, in the opposite direction 00366 00367 template <class T> 00368 GenPoint<T> 00369 FreemanCode::toOppositePoint(const GenPoint<T>& aPt) const 00370 { 00371 return toPointAUX(aPt, qgOpposite(_direction), _length); 00372 } 00373 00374 00375 // =========== 00376 // AUXILIARIES 00377 // =========== 00378 00379 // RETURN THE POINT LOCATED IN GIVEN DIRECTION AT GIVEN LENGTH 00380 // FROM THE GIVEN POINT. 00381 00382 template <class T> 00383 GenPoint<T> 00384 FreemanCode::toPointAUX(const GenPoint<T>& aPt, 00385 QGEdirection aDir, 00386 unsigned int aLength) const 00387 00388 throw(QgarErrorInvalidArg) 00389 00390 { 00391 switch (aDir) 00392 { 00393 case QGE_DIRECTION_N: 00394 { 00395 return GenPoint<T>(aPt.x(), aPt.y() - aLength); 00396 } 00397 case QGE_DIRECTION_NE: 00398 { 00399 return GenPoint<T>(aPt.x() + aLength, aPt.y() - aLength); 00400 } 00401 case QGE_DIRECTION_E: 00402 { 00403 return GenPoint<T>(aPt.x() + aLength, aPt.y()); 00404 } 00405 case QGE_DIRECTION_SE: 00406 { 00407 return GenPoint<T>(aPt.x() + aLength, aPt.y() + aLength); 00408 } 00409 case QGE_DIRECTION_S: 00410 { 00411 return GenPoint<T>(aPt.x(), aPt.y() + aLength); 00412 } 00413 case QGE_DIRECTION_SW: 00414 { 00415 return GenPoint<T>(aPt.x() - aLength, aPt.y() + aLength); 00416 } 00417 case QGE_DIRECTION_W: 00418 { 00419 return GenPoint<T>(aPt.x() - aLength, aPt.y()); 00420 } 00421 case QGE_DIRECTION_NW: 00422 { 00423 return GenPoint<T>(aPt.x() - aLength, aPt.y() - aLength); 00424 } 00425 default: 00426 { 00427 // ************************************************************* 00428 // CONTROL SHOULD NEVER REACH THIS POINT 00429 // ************************************************************* 00430 std::ostringstream os; 00431 os << "Unknown direction: " 00432 << aDir; 00433 throw QgarErrorInvalidArg(__FILE__, __LINE__, 00434 "template <class T> qgar::GenPoint<T> qgar::FreemanCode::toPointAUX(const qgar::GenPoint<T>&, qgar::QGEdirection, unsigned int) const", 00435 os.str()); 00436 // ************************************************************* 00437 } 00438 } 00439 } 00440 00441 00442 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00443 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00444 // E N D O F F U N C T I O N S I M P L E M E N T A T I O N 00445 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00446 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00447 00448 00449 } // namespace qgar 00450 00451 00452 #endif /* __FREEMANCODE_H_INCLUDED__ */