CVR-Lib last update 20 Sep 2009

cvrKernel1D.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  * \file   cvrKernel1D.h
00043  *         Contains the template class cvr::kernel1D<T>.
00044  * \author Pablo Alavarado
00045  * \date   28.04.00
00046  *
00047  * revisions ..: $Id: cvrKernel1D.h,v 1.7 2007/10/14 20:20:00 alvarado Exp $
00048  */
00049 
00050 #ifndef _CVR_KERNEL_1_D_H_
00051 #define _CVR_KERNEL_1_D_H_
00052 
00053 #include <vector>
00054 #include "cvrLattice1D.h"
00055 #include "cvrTypes.h"
00056 #include "cvrMatrix.h"
00057 #include "cvrTypeInfo.h"
00058 
00059 namespace cvr {
00060 
00061   /**
00062    * One-dimensional filter kernel
00063    *
00064    * The template type of this class should coincide with the template
00065    * class of the vector be convolved with.  For example, if you want
00066    * to convolve a kernel1D with a vector<double>, you will need a
00067    * kernel1D<double> (@see cvr::convolution).
00068    *
00069    * If you instantiate a kernel1D of a fixed point type, like
00070    * kernel1D<int> or kernel1D<ubyte>, you also need to consider the
00071    * "norm" of the kernel (see cvr::kernel1D<T>::getNorm() and
00072    * cvr::kernel1D<T>::setNorm(const T&)). This "norm" allows the
00073    * representation of numbers less than 1.0.  You can see this norm as the
00074    * value to be considered as 1.0, when operating with the kernel.
00075    * For example, if you have a kernel1D<ubyte> with the values [64,128,64]
00076    * and norm=255, the the interpreted values during convolution will be
00077    * [0.25,0.5,0.25].  With floating-point types, the norm will be always
00078    * assumed to be 1.0.  For other types the default norms are the following:
00079    *
00080    * For int:              65536
00081    * For ubyte:              255
00082    * Otherwise:                1.0
00083    *
00084    * @see cvr::convolution
00085    */
00086   template<class T>
00087   class kernel1D : public lattice1D<T> {
00088   public:
00089     /**
00090      * \name Internal types and classes
00091      */
00092     //@{
00093 
00094     /**
00095      * Type of the lattice1D elements.
00096      */
00097     typedef typename lattice1D<T>::value_type value_type;
00098 
00099     /**
00100      * Return type of the size() member
00101      */
00102     typedef typename lattice1D<T>::size_type size_type;
00103 
00104     /**
00105      * Pointer to value_type
00106      */
00107     typedef typename lattice1D<T>::pointer pointer;
00108 
00109     /**
00110      * Const pointer to value_type
00111      */
00112     typedef typename lattice1D<T>::const_pointer const_pointer;
00113     
00114     /**
00115      * Reference to value_type
00116      */
00117     typedef typename lattice1D<T>::reference reference;
00118 
00119     /**
00120      * Const reference to value_type
00121      */
00122     typedef typename lattice1D<T>::const_reference const_reference;
00123 
00124     /**
00125      * \c iterator type (allows read and write operations).
00126      *
00127      * The use of the iterator classes is similar to the iterators of the STL
00128      * (Standard Template Library). See cvr::lattice1D::begin() and
00129      * cvr::lattice1D::inverseBegin() for examples.
00130      *
00131      * For the debugging version of the iterators, boundary check will be
00132      * done!  This explains the low speed of the iterators of the debug
00133      * version.  In the release version, no boundary check will be done,
00134      * and the iterators are sometimes a factor 10 faster than the
00135      * debug iterators.
00136      *
00137      * The use of the access operator at() is faster than the iterators in the
00138      * debug version only.  If you need to iterate on a lattice1D use
00139      * iterators instead (in the release version iterators are approximately a
00140      * factor 3 faster than at()).
00141      *
00142      * \warning Try to use the prefix incremental operator (i.e. ++it) instead
00143      * of the postfix operator (i.e. it++) to allow efficient code also in
00144      * debug-modus!
00145      *
00146      * @see lattice1D<T>::const_iterator
00147      */
00148     typedef typename lattice1D<T>::iterator iterator;
00149 
00150     /**
00151      * \c const_iterator type (allows read-only operations).
00152      *
00153      * The use of the iterator classes is similar to the iterators of the STL
00154      * (Standard Template Library). See cvr::lattice1D::begin() for an
00155      * example.
00156      *
00157      * For the debugging version of the iterators, boundary check will be
00158      * done!  This explains the low speed of the iterators of the debug
00159      * version.  In the release version, no boundary check will be done, and
00160      * the iterators are sometimes a factor 10 faster than the debug
00161      * iterators.
00162      *
00163      * The use of the access operator at() is faster than the iterators in the
00164      * debug version only.  If you need to iterate on a lattice1D use
00165      * iterators instead (in the release version iterators are approximately a
00166      * factor 3 faster than at()).
00167      *
00168      * \warning Try to use the prefix incremental operator (i.e. ++it) instead
00169      * of the postfix operator (i.e. it++) to allow efficient code also in
00170      * debug-modus!
00171      *
00172      * @see lattice1D<T>::iterator
00173      */
00174     typedef typename lattice1D<T>::const_iterator const_iterator;
00175     //@}
00176 
00177     /**
00178      * Default constructor
00179      */
00180     kernel1D();
00181 
00182     /**
00183      * Construct a filter kernel indexed from <em>from</em> to
00184      * <em>to</em> and initialized with the value <em>init</em>
00185      */
00186     kernel1D(const int from,
00187        const int to,
00188        const T& init);
00189 
00190     /**
00191      * Construct a uninitialization filter kernel indexed from
00192      * <em>from</em> to <em>to</em>
00193      *
00194      * \warning This is an interface change with the previous library.  It has
00195      * been done to be consistent with the more basic features of the C++
00196      * language.  If you write for example "int c;", the content of \c c is
00197      * not defined, and in the same way, if you want a kernel1D with
00198      * initialized data, you have to specify explicitely the value with
00199      * which the elements have to be initialized.
00200      */
00201     kernel1D(const int from,
00202        const int to);
00203 
00204     /**
00205      * Construct a kernel from a one dimensional vector
00206      * @param other the source vector
00207      * @param theOffset this is the index in the vector that corresponds to
00208      *                  the index '0' in the filter kernel
00209      */
00210     kernel1D(const vector<T>& other,const int theOffset);
00211 
00212     /**
00213      * Copy constructor
00214      * @param other the one dimensional kernel to be copied
00215      */
00216     kernel1D(const kernel1D& other);
00217 
00218     /**
00219      * Destructor
00220      */
00221     virtual ~kernel1D();
00222 
00223     /**
00224      * Copy member
00225      * @param other the one dimensional kernel to be copied
00226      * @return a reference to this instance
00227      */
00228     kernel1D& copy(const kernel1D& other);
00229 
00230     /**
00231      * Returns the name of this type.
00232      */
00233     virtual const std::string& name() const;
00234 
00235     /**
00236      * Clone member
00237      * @return a pointer to a copy of this object
00238      */
00239     virtual kernel1D<T>* clone() const;
00240 
00241     /**
00242      * Create a new instance.
00243      * @return a pointer to a new empty kernel instance
00244      */
00245     virtual kernel1D<T>* newInstance() const;
00246 
00247     /**
00248      * Copy from kernel of different type
00249      * @param other a one dimensional kernel of another type
00250      * @return a reference to this instance
00251      */
00252     template<class U>
00253     kernel1D& castFrom(const kernel1D<U>& other) {
00254       lattice1D<T>::castFrom(other);
00255       norm_ = T(other.getNorm());
00256       return (*this);
00257     }
00258 
00259     /**
00260      * Copy the content of the other vector in this kernel and assign
00261      * the index (firstElement) to the first element of the vector.
00262      * For example if <code>other</code> is a 3 dimensional vector, then
00263      * <code>castFrom(other,-1)</code> is a 3-elements-kernel which indices
00264      * lay inside [-1,1].
00265      * @param other the vector with the data to be copied
00266      * @param firstElement index for the first element of the vector
00267      * @return a reference to this instance
00268      */
00269     kernel1D<T>& castFrom(const vector<T>& other,
00270                           const int firstElement = 0);
00271 
00272 
00273     /**
00274      * Get normalization factor
00275      *
00276      * The normalization factor is used by the fixed point types as a
00277      * representation of the value 1.  For example, the norm for a
00278      * kernel1D<ubyte> can be 255, if the filter kernel don't need values
00279      * greater than 1.0.
00280      */
00281     inline const T& getNorm() const {
00282       return norm_;
00283     }
00284 
00285     /**
00286      * Set normalization factor
00287      * @see getNorm()
00288      */
00289     inline void setNorm(const T& n) {
00290       norm_=n;
00291     };
00292 
00293     /**
00294      * Normalize divides all elements by the norm and sets the norm to 1!
00295      */
00296     void normalize();
00297 
00298     /**
00299      * @name Symmetries
00300      */
00301     //@{
00302     /**
00303      * Mirror the other kernel and leave the result here, i.e.
00304      * at(x) = other.at(-x);
00305      * @param other the kernel to be copied and then mirrored
00306      * @return a reference to this instance
00307      */
00308     kernel1D<T>& mirror(const kernel1D<T>& other);
00309 
00310     /**
00311      * Mirror this kernel, i.e.
00312      * at(x) = at(-x);
00313      * @return a reference to this instance
00314      */
00315     kernel1D<T>& mirror();
00316 
00317     /**
00318      * Check if this kernel is symmetric, i.e. if it is valid
00319      * at(x)==at(-x) and firstIdx() == -lastIdx()
00320      */
00321     bool isSymmetric() const;
00322 
00323     /**
00324      * Check if this kernel is asymmetric, i.e. if it is valid
00325      * at(x)==-at(-x) and firstIdx() == -lastIdx()
00326      */
00327     bool isAsymmetric() const;
00328 
00329     /**
00330      * Get kernel symmetric component
00331      *
00332      * Each discrete function (including kernels like this one) can be
00333      * decomposed into a symmetric component \f$x_e(n)\f$$ and an asymmetric
00334      * component \f$x_e(n)\f$ following the equation
00335      *
00336      * \f[
00337      *   \begin{aligned}
00338      *     x_e &= \frac{x(t)+x(-t)}{2} \\
00339      *     x_o &= \frac{x(t)-x(-t)}{2} \\
00340      *   \end{aligned}
00341      * \f]
00342      *
00343      * This method extracts the symmetric component only
00344      */
00345     void computeSymmetricComponent();
00346 
00347     /**
00348      * Get kernel symmetric component of other kernel.
00349      *
00350      * Each discrete function (including kernels like this one) can be
00351      * decomposed into a symmetric component \f$x_e(n)\f$$ and an asymmetric
00352      * component \f$x_e(n)\f$ following the equation
00353      *
00354      * \f[
00355      *   \begin{aligned}
00356      *     x_e &= \frac{x(t)+x(-t)}{2} \\
00357      *     x_o &= \frac{x(t)-x(-t)}{2} \\
00358      *   \end{aligned}
00359      * \f]
00360      *
00361      * This method extracts the symmetric component of the other kernel.
00362      *
00363      * @param other the kernel which will be decomposed.
00364      */
00365     void computeSymmetricComponent(const kernel1D<T>& other);
00366 
00367     /**
00368      * Get kernel asymmetric component
00369      *
00370      * Each discrete function (including kernels like this one) can be
00371      * decomposed into a symmetric component \f$x_e(n)\f$$ and an asymmetric
00372      * component \f$x_e(n)\f$ following the equation
00373      *
00374      * \f[
00375      *   \begin{aligned}
00376      *     x_e &= \frac{x(t)+x(-t)}{2} \\
00377      *     x_o &= \frac{x(t)-x(-t)}{2} \\
00378      *   \end{aligned}
00379      * \f]
00380      *
00381      * This method extracts the asymmetric component only
00382      */
00383     void computeAsymmetricComponent();
00384 
00385     /**
00386      * Get kernel asymmetric component of other kernel.
00387      *
00388      * Each discrete function (including kernels like this one) can be
00389      * decomposed into a symmetric component \f$x_e(n)\f$$ and an asymmetric
00390      * component \f$x_e(n)\f$ following the equation
00391      *
00392      * \f[
00393      *   \begin{aligned}
00394      *     x_e &= \frac{x(t)+x(-t)}{2} \\
00395      *     x_o &= \frac{x(t)-x(-t)}{2} \\
00396      *   \end{aligned}
00397      * \f]
00398      *
00399      * This method extracts the asymmetric component of the other kernel.
00400      *
00401      * @param other the kernel which will be decomposed.
00402      */
00403     void computeAsymmetricComponent(const kernel1D<T>& other);
00404     //@}
00405 
00406     /**
00407      * Write the object in the given ioHandler
00408      */
00409     virtual bool write(ioHandler& handler,const bool complete = true) const;
00410 
00411     /**
00412      * Read the object from the given ioHandler
00413      */
00414     virtual bool read(ioHandler& handler,const bool complete = true);
00415 
00416   protected:
00417     /**
00418      * Normalization factor.
00419      *
00420      * This value will be ignored for floating point formats.
00421      * For fixed point formats, this value corresponds to 1.0
00422      */
00423     T norm_;
00424   };
00425 
00426 
00427   // ----------------------------------------------------------
00428   //   Typical used types
00429   // ----------------------------------------------------------
00430 
00431   /**
00432    * One dimensional kernel of integers
00433    */
00434   typedef kernel1D<int32>  ikernel1D;
00435 
00436   /**
00437    * One dimensional kernel of floats
00438    */
00439   typedef kernel1D<float>  fkernel1D;
00440 
00441   /**
00442    * One dimensional kernel of doubles
00443    */
00444   typedef kernel1D<double> dkernel1D;
00445 
00446   /**
00447    * One dimensional kernel of unsigned bytes
00448    */
00449   typedef kernel1D<ubyte>  bkernel1D;
00450 
00451 
00452 }
00453 #endif

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