last update 20 Sep 2009 |
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