CVR-Lib last update 20 Sep 2009

cvrChainCode.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2004
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 
00042 /**
00043  * \file   cvrChainCode.h
00044  *         Declares chainCode and constants for Canzler code
00045  * \author LTI
00046  * \date   19.08.1998
00047  *
00048  * $Id: cvrChainCode.h,v 1.5 2005/06/06 12:59:56 doerfler Exp $
00049  */
00050 
00051 #ifndef _CVR_CHAIN_CODE_H_
00052 #define _CVR_CHAIN_CODE_H_
00053 
00054 #include "cvrIoHandler.h"
00055 #include "cvrPoint.h"
00056 
00057 namespace cvr {
00058 
00059   /**
00060    * Elements of a Chaincode.
00061    * The used directions follows the next diagram:
00062    *
00063    * \code
00064    * NW   N   NE
00065    *    \ | /
00066    * W -  x - E
00067    *    / | \
00068    * SW   S   SE
00069    * \endcode
00070    *
00071    * The "int" value resulting from casting these chain codes is
00072    * proportional to the angle with a proportionality constant of 45°,
00073    * i.e. if 'c' is a chainCode object, then the equivalent direction
00074    * in degrees is 45*int(c.getDirection()).
00075    *
00076    * @ingroup gShape
00077    */
00078   class chainCode {
00079   public:
00080     /**
00081      * Directions used in chain codes
00082      * The used directions follows the next diagram:
00083      *
00084      * \code
00085      * NW   N   NE
00086      *    \ | /
00087      * W -  x - E
00088      *    / | \
00089      * SW   S   SE
00090      * \endcode
00091      *
00092      * The "int" value resulting from casting these chain codes is
00093      * proportional to the angle with a proportionality constant of 45°,
00094      * i.e. if 'c' is a chainCode object, then the equivalent direction
00095      * in degrees is 45*int(c.getDirection()).
00096      */
00097     enum direction {UNKNOWN=-2, /**< Unknown */
00098                     NOMOVE=-1,  /**< No Move */
00099                     E=0,        /**< East (or Right) */
00100                     NE,         /**< North-East (or Right-Up) */
00101                     N,          /**< North (or Up) */
00102                     NW,         /**< North-West (or North-West) */
00103                     W,          /**< West (or West) */
00104                     SW,         /**< South-West (or Left-Down) */
00105                     S,          /**< South (or Down) */
00106                     SE          /**< South-East (or Right-Down) */
00107     };
00108 
00109     /**
00110      * @name Canzler Codes
00111      *
00112      * Given two chain codes for a sequence of three adjacent pixels,
00113      * the Canzler-Codes give you information about which borders of the middle
00114      * pixel belong to the boundary.  With the getCanzlerCode() you can obtain
00115      * the corresponding coding for the pixel pointed by this chain code, if
00116      * the next chain code is the one given.  They are somehow similar to the
00117      * so called "chain crack codes", but instead of specifying a direction
00118      * of the boundary, they code which "crack codes" belong to the middle
00119      * pixel between two chain codes.
00120      *
00121      * There are 16 Canzler-Codes, that can be obtained by the combination
00122      * of the four values Top, Right, Bottom and Left, which specify that
00123      * the border runs on the top, right, bottom and/or left edge of the
00124      * pixel respectively.
00125      */
00126     //@{
00127     static const ubyte Nothing; /// Nothing has the value 0
00128     static const ubyte Top;     /// Top has value 1 (the first bit)
00129     static const ubyte Right;   /// Right has value 2 (the second bit)
00130     static const ubyte Bottom;  /// Bottom has value 4 (the third bit)
00131     static const ubyte Left;    /// Left has value 8 (the fourth bit)
00132     //@}
00133 
00134     /**
00135      * default constructor
00136      */
00137     chainCode(const direction& v = NOMOVE)
00138       : value(v) {
00139     };
00140 
00141     /**
00142      * constructor to cast an integer
00143      */
00144     chainCode(const int v) : value(direction(v%8)) {};
00145 
00146     /**
00147      * copy constructor
00148      */
00149     chainCode(const chainCode& other)
00150       : value(other.value) {
00151     };
00152 
00153     /** Constrcutor. This constructor creates a chainCode object using the
00154   sign of the parameters to calculate the direction.
00155   Image-coordinates are used, i.e. a positive "y" implies a
00156   change towards "south", and a positive x implies a
00157   change towards "east". */
00158     chainCode(const int x,const int y) : value(UNKNOWN) {
00159       fromDeltas(x,y);
00160     };
00161 
00162     /**
00163      * Constructor.This constructor creates a chainCode object using
00164      * two points
00165      */
00166     chainCode(const ipoint& here,const ipoint& next) : value(UNKNOWN) {
00167       ipoint tmp(next);
00168       tmp.subtract(here);
00169       fromDeltas(tmp.x,tmp.y);
00170     };
00171 
00172     /**
00173      * returns direction of this chain element
00174      */
00175     inline direction getDirection() const;
00176 
00177     /**
00178      * Possible Direction.returns true if this object contains one of
00179      * the eight posible directions, and false otherwise
00180      */
00181     inline bool isDirection() const;
00182 
00183     /**
00184      * returns next point with start point "here" and using this chainCode.
00185      */
00186     inline ipoint getNext(const ipoint& here) const;
00187 
00188     /**
00189      * returns previous point with start point "here" and using this chainCode.
00190      */
00191     inline ipoint getPrevious(const ipoint& here) const;
00192 
00193     /**
00194      * returns change in x.
00195      * For example, if the value is NW, deltaX() returns -1.
00196      */
00197     inline int deltaX() const;
00198 
00199     /**
00200      * returns change in y.
00201      * For example, if the value is NW, deltaY() returns -1.
00202      */
00203     inline int deltaY() const;
00204 
00205     /**
00206      * returns point with changes in both direction, x and y.
00207      */
00208     inline ipoint delta() const;
00209 
00210     /**
00211      * become other object
00212      */
00213     inline chainCode& operator=(const direction& other) {
00214       return copy(other);
00215     };
00216 
00217     /**
00218      * become other object
00219      */
00220     inline chainCode& copy(const direction& other);
00221 
00222     /**
00223      * become other object
00224      */
00225     inline chainCode& copy(const chainCode& other);
00226 
00227     /**
00228      * become other object
00229      */
00230     inline chainCode& operator=(const chainCode& other) {
00231       return(copy(other));
00232     };
00233 
00234     /**
00235      * compare with another object
00236      */
00237     inline bool compare(const chainCode& other);
00238 
00239     /**
00240      * compare with another object
00241      */
00242     inline bool operator==(const chainCode& other) {
00243       return compare(other);
00244     };
00245 
00246     /**
00247      * compare with another object
00248      */
00249     inline bool compare(const direction& other);
00250 
00251     /**
00252      * compare with another object
00253      */
00254     inline bool operator==(const direction& other) {
00255       return compare(other);
00256     };
00257 
00258     /**
00259      * subtract the angles of the first and second chain code elements and
00260      * leave the result here!
00261      */
00262     inline chainCode& subtract(const chainCode& first,
00263                                const chainCode& second);
00264     /**
00265      * subtract the angle equivalent of the <em>other</em> chainCode
00266      * from *this
00267      */
00268     inline chainCode operator-(const chainCode& other) const {
00269       chainCode tmp;
00270       tmp.subtract(*this,other);
00271       return tmp;
00272     };
00273 
00274     /**
00275      * subtract the angle equivalent of the other chain code from this one.
00276      * The result will be left in this instance, and a reference to it will
00277      * be returned.
00278      */
00279     inline chainCode& subtract(const chainCode& other);
00280 
00281     /**
00282      * subtract another chain code
00283      */
00284     inline chainCode& operator-=(const chainCode& other) {
00285       return subtract(other);
00286     };
00287 
00288     /**
00289      * add the angles of the first and second chain codes
00290      */
00291     inline chainCode& add(const chainCode& first,
00292                           const chainCode& second);
00293 
00294     /**
00295      * add the angles of this and the other chain code
00296      */
00297     inline chainCode operator+(const chainCode& other) const {
00298       chainCode tmp;
00299       tmp.add(*this,other);
00300       return tmp;
00301     };
00302 
00303     /**
00304      * add the angles of the other chain code to this chainCode and
00305      * leave the result in this instance.  Returns a reference to the instance
00306      */
00307     inline chainCode& add(const chainCode& other);
00308 
00309     /**
00310      * add another chain code
00311      */
00312     inline chainCode& operator+=(const chainCode& other) {
00313       return add(other);
00314     };
00315 
00316     /**
00317      * divide chain code equivalent angle with an integer.  The result
00318      * will be left in this instance and a reference to it will be returned
00319      */
00320     inline chainCode& divide(const int other) {
00321       value=static_cast<direction>(static_cast<int>(value)/other);
00322       return (*this);
00323     };
00324 
00325     /**
00326      * divide chain code angle with integer.
00327      */
00328     inline chainCode operator/(const int other) {
00329       chainCode tmp(*this);
00330       tmp.divide(other);
00331       return (tmp);
00332     }
00333 
00334     /**
00335      * return the Canzler Code for the pixel pointed by this chainCode
00336      * if the second chainCode is the one given as parameter.
00337      *
00338      * The result a the bitwise OR of some of the codes Top, Bottom, Left and
00339      * Right.
00340      *
00341      * @param nextChainCode the next chain code of this one in the chain
00342      *                      code sequence.
00343      * @return the canzler bit-coding for the edges of the pixel pointed
00344      *         by this chainCode which are part of the boundary.  The values
00345      *         returned are bit or of the constants Left, Top, Right and
00346      *         Bottom.
00347      */
00348     inline ubyte getCanzlerCode(const chainCode& nextChainCode) const;
00349 
00350   protected:
00351     /**
00352      * Attribute containing the chain code
00353      */
00354     direction value;
00355 
00356     /**
00357      * compute chain code from x and y deltas
00358      */
00359     inline void fromDeltas(const int x,const int y);
00360   };
00361 
00362   //***********************************************************
00363   // Global IO functions
00364   //***********************************************************
00365 
00366   /**
00367    * read the matrix from the given ioHandler.  The complete flag indicates
00368    * if the enclosing begin and end should be also be readed
00369    *
00370    * @ingroup gStorable
00371    */
00372   bool read(ioHandler& handler,chainCode& cc,const bool complete=true);
00373 
00374   /**
00375    * write the matrix in the given ioHandler.  The complete flag indicates
00376    * if the enclosing begin and end should be also be written or not
00377    *
00378    * @ingroup gStorable
00379    */
00380   bool write(ioHandler& handler,const chainCode& cc,const bool complete=true);
00381 }
00382 
00383 #include "cvrChainCode_inline.h"
00384 
00385 #endif
00386 
00387 
00388 

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8