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 cvrKernel2D.h 00043 * Contains the template class cvr::kernel1D<T>. 00044 * \author Pablo Alvarado 00045 * \date 06.04.08 00046 * 00047 * revisions ..: $Id: cvrKernel1D.h,v 1.7 2007/10/14 20:20:00 alvarado Exp $ 00048 */ 00049 00050 #ifndef _CVR_KERNEL_2_D_H_ 00051 #define _CVR_KERNEL_2_D_H_ 00052 00053 #include "cvrLattice2D.h" 00054 #include "cvrTypes.h" 00055 #include "cvrMatrix.h" 00056 #include "cvrTypeInfo.h" 00057 00058 namespace cvr { 00059 00060 /** 00061 * Two-dimensional filter kernel 00062 * 00063 * The template type of this class should coincide with the template 00064 * class of the matrix to be convolved with. For example, if you want 00065 * to convolve a kernel2D with a matrix<double>, you will need a 00066 * kernel2D<double> (@see cvr::convolution). 00067 * 00068 * If you instantiate a kernel2D of a fixed point type, like 00069 * kernel2D<int> or kernel2D<ubyte>, you also need to consider the 00070 * "norm" of the kernel (see cvr::kernel2D<T>::getNorm() and 00071 * cvr::kernel2D<T>::setNorm(const T&)). This "norm" allows the 00072 * representation of numbers less than 1.0. You can see this norm as the 00073 * value to be considered as 1.0, when operating with the kernel. 00074 * For example, if you have a kernel2D<ubyte> with the values [64,128,64] 00075 * and norm=255, the the interpreted values during convolution will be 00076 * [0.25,0.5,0.25]. With floating-point types, the norm will be always 00077 * assumed to be 1.0. For other types the default norms are the following: 00078 * 00079 * For int: 65536 00080 * For ubyte: 255 00081 * Otherwise: 1.0 00082 * 00083 * @see cvr::convolution 00084 */ 00085 template<class T> 00086 class kernel2D : public lattice2D<T> { 00087 public: 00088 /** 00089 * \name Internal types and classes 00090 */ 00091 //@{ 00092 00093 /** 00094 * Type of the lattice2D elements. 00095 */ 00096 typedef typename lattice2D<T>::value_type value_type; 00097 00098 /** 00099 * Return type of the size() member 00100 */ 00101 typedef typename lattice2D<T>::size_type size_type; 00102 00103 /** 00104 * Pointer to value_type 00105 */ 00106 typedef typename lattice2D<T>::pointer pointer; 00107 00108 /** 00109 * Const pointer to value_type 00110 */ 00111 typedef typename lattice2D<T>::const_pointer const_pointer; 00112 00113 /** 00114 * Reference to value_type 00115 */ 00116 typedef typename lattice2D<T>::reference reference; 00117 00118 /** 00119 * Const reference to value_type 00120 */ 00121 typedef typename lattice2D<T>::const_reference const_reference; 00122 00123 /** 00124 * \c iterator type (allows read and write operations). 00125 * 00126 * The use of the iterator classes is similar to the iterators of the STL 00127 * (Standard Template Library). See cvr::lattice2D::begin() and 00128 * cvr::lattice2D::inverseBegin() for examples. 00129 * 00130 * For the debugging version of the iterators, boundary check will be 00131 * done! This explains the low speed of the iterators of the debug 00132 * version. In the release version, no boundary check will be done, 00133 * and the iterators are sometimes a factor 10 faster than the 00134 * debug iterators. 00135 * 00136 * The use of the access operator at() is faster than the iterators in the 00137 * debug version only. If you need to iterate on a lattice2D use 00138 * iterators instead (in the release version iterators are approximately a 00139 * factor 3 faster than at()). 00140 * 00141 * \warning Try to use the prefix incremental operator (i.e. ++it) instead 00142 * of the postfix operator (i.e. it++) to allow efficient code also in 00143 * debug-modus! 00144 * 00145 * @see lattice2D<T>::const_iterator 00146 */ 00147 typedef typename lattice2D<T>::iterator iterator; 00148 00149 /** 00150 * \c const_iterator type (allows read-only operations). 00151 * 00152 * The use of the iterator classes is similar to the iterators of the STL 00153 * (Standard Template Library). See cvr::lattice2D::begin() for an 00154 * example. 00155 * 00156 * For the debugging version of the iterators, boundary check will be 00157 * done! This explains the low speed of the iterators of the debug 00158 * version. In the release version, no boundary check will be done, and 00159 * the iterators are sometimes a factor 10 faster than the debug 00160 * iterators. 00161 * 00162 * The use of the access operator at() is faster than the iterators in the 00163 * debug version only. If you need to iterate on a lattice2D use 00164 * iterators instead (in the release version iterators are approximately a 00165 * factor 3 faster than at()). 00166 * 00167 * \warning Try to use the prefix incremental operator (i.e. ++it) instead 00168 * of the postfix operator (i.e. it++) to allow efficient code also in 00169 * debug-modus! 00170 * 00171 * @see lattice2D<T>::iterator 00172 */ 00173 typedef typename lattice2D<T>::const_iterator const_iterator; 00174 //@} 00175 00176 /** 00177 * Default constructor creates an empty kernel2D 00178 */ 00179 kernel2D(); 00180 00181 /** 00182 * Create a kernel2D with uninitialized elements. 00183 * 00184 * @param fromRow lowest row index 00185 * @param fromCol lowest column index 00186 * @param toRow highest row index (inclusive) 00187 * @param toCol highest column index (inclusive) 00188 */ 00189 kernel2D(const int fromRow, 00190 const int fromCol, 00191 const int toRow, 00192 const int toCol); 00193 00194 /** 00195 * Create a \a rows x \a cols kernel2D with uninitialized elements. 00196 * 00197 * @param from lowest index 00198 * @param to highest index (inclusive) 00199 */ 00200 kernel2D(const size_type& from, 00201 const size_type& to); 00202 00203 /** 00204 * Create a kernel2D with uninitialized elements. 00205 * 00206 * @param rows interval used for the rows 00207 * @param columns interval used for the columns 00208 */ 00209 kernel2D(const iinterval& rows, 00210 const iinterval& columns); 00211 00212 /** 00213 * Create a kernel2D and initialize all elements with the given 00214 * value. 00215 * 00216 * @param fromRow lowest row index 00217 * @param fromCol lowest column index 00218 * @param toRow highest row index (inclusive) 00219 * @param toCol highest column index (inclusive) 00220 * @param value value used for initializing the elements 00221 */ 00222 kernel2D(const int fromRow, 00223 const int fromCol, 00224 const int toRow, 00225 const int toCol, 00226 const T& value); 00227 00228 /** 00229 * Create a kernel2D and initialize all elements with the given 00230 * value. 00231 * 00232 * @param from lowest index 00233 * @param to highest index (inclusive) 00234 * @param value value used for initializing the elements 00235 */ 00236 kernel2D(const size_type& from, 00237 const size_type& to, 00238 const T& value); 00239 00240 /** 00241 * Create a kernel2D and initialize all elements with the given 00242 * value. 00243 * 00244 * @param rows interval used for the rows 00245 * @param columns interval used for the columns 00246 * @param value value used for initializing the elements 00247 */ 00248 kernel2D(const iinterval& rows, 00249 const iinterval& columns, 00250 const T& value); 00251 00252 /** 00253 * Create a kernel2D and initialize all elements with the data 00254 * pointed by \a data. 00255 * 00256 * The first elements of the data will be \b copied on the 00257 * first row, the next ones on the second row and so on. 00258 * 00259 * @param fromRow lowest row index 00260 * @param fromCol lowest column index 00261 * @param toRow highest row index (inclusive) 00262 * @param toCol highest column index (inclusive) 00263 * @param data pointer to the memory block with the data to be initialized 00264 * with. 00265 */ 00266 kernel2D(const int fromRow, 00267 const int fromCol, 00268 const int toRow, 00269 const int toCol, 00270 const T data[]); 00271 00272 /** 00273 * Create a kernel2D and initialize all elements with the data 00274 * pointed by \a data. 00275 * 00276 * The first elements of the data will be \b copied on the 00277 * first row, the next ones on the second row and so on. 00278 * 00279 * @param from lowest index 00280 * @param to highest index (inclusive) 00281 * @param data pointer to the memory block with the data to be initialized 00282 * with. 00283 */ 00284 kernel2D(const size_type& from, 00285 const size_type& to, 00286 const T data[]); 00287 00288 /** 00289 * Create a kernel2D and initialize all elements with the data 00290 * pointed by \a data. 00291 * 00292 * The first elements of the data will be \b copied on the 00293 * first row, the next ones on the second row and so on. 00294 * 00295 * @param rows interval used for the rows 00296 * @param columns interval used for the columns 00297 * @param data pointer to the memory block with the data to be initialized 00298 * with. 00299 */ 00300 kernel2D(const iinterval& rows, 00301 const iinterval& columns, 00302 const T data[]); 00303 00304 /** 00305 * Create a kernel2D and use the given \a data as if it was given 00306 * through the useExternData(). 00307 * 00308 * @see useExternData() 00309 * 00310 * The first elements of the data will be copied on the first row, the next 00311 * ones on the second row and so on. 00312 * 00313 * \note Please observe that the last argument makes a huge difference to 00314 * the constructors that do not have it. Here the data is \b not copied, 00315 * just a reference is kept. Without the last argument, the data is 00316 * always copied. 00317 * 00318 * @param fromRow lowest row index 00319 * @param fromCol lowest column index 00320 * @param toRow highest row index (inclusive) 00321 * @param toCol highest column index (inclusive) 00322 * @param data pointer to the memory block with the data to be initialized 00323 * with. 00324 * @param constRef usually you want this value to be ConstantReference. 00325 */ 00326 kernel2D(const int fromRow, 00327 const int fromCol, 00328 const int toRow, 00329 const int toCol, 00330 T data[], 00331 const eConstantReference constRef); 00332 00333 /** 00334 * Create a kernel2D and use the given \a data as if it was given 00335 * through the useExternData(). 00336 * 00337 * @see useExternData() 00338 * 00339 * The first elements of the data will be copied on the first row, the next 00340 * ones on the second row and so on. 00341 * 00342 * \note Please observe that the last argument makes a huge difference to 00343 * the constructors that do not have it. Here the data is \b not copied, 00344 * just a reference is kept. Without the last argument, the data is 00345 * always copied. 00346 * 00347 * @param from lowest index 00348 * @param to highest index (inclusive) 00349 * @param data pointer to the memory block with the data to be initialized 00350 * with. 00351 * @param constRef usually you want this value to be ConstantReference. 00352 */ 00353 kernel2D(const size_type& from, 00354 const size_type& to, 00355 T data[], 00356 const eConstantReference constRef); 00357 00358 00359 /** 00360 * Create a kernel2D and use the given \a data as if it was given 00361 * through the useExternData(). 00362 * 00363 * @see useExternData() 00364 * 00365 * The first elements of the data will be copied on the first row, the next 00366 * ones on the second row and so on. 00367 * 00368 * \note Please observe that the last argument makes a huge difference to 00369 * the constructors that do not have it. Here the data is \b not copied, 00370 * just a reference is kept. Without the last argument, the data is 00371 * always copied. 00372 * 00373 * @param rows interval for rows 00374 * @param columns interval for columns 00375 * @param data pointer to the memory block with the data to be initialized 00376 * with. 00377 * @param constRef usually you want this value to be ConstantReference. 00378 */ 00379 kernel2D(const iinterval& rows, 00380 const iinterval& columns, 00381 T data[], 00382 const eConstantReference constRef); 00383 00384 /** 00385 * Copy constructor. 00386 * 00387 * Create this kernel2D as a copy of another kernel2D. 00388 * 00389 * @param other the kernel2D to be copied. 00390 */ 00391 kernel2D(const genericLattice2D<T>& other); 00392 00393 /** 00394 * Copy constructor. 00395 * 00396 * Create this kernel2D as a copy of another kernel2D for 00397 * this const version, the data will be always copied! 00398 * 00399 * @param other the genericLattice2D to be copied. 00400 * @param fromRow initial row of the other genericLattice2D to be copied 00401 * @param fromCol initial column of the other genericLattice2D to be copied 00402 * @param toRow last row to be copied of the other genericLattice2D 00403 * @param toCol last column to be copied of the other genericLattice2D 00404 */ 00405 kernel2D(const genericLattice2D<T>& other, 00406 const int fromRow, 00407 const int fromCol, 00408 const int toRow=container::MaxIndex, 00409 const int toCol=container::MaxIndex); 00410 00411 /** 00412 * Copy constructor. 00413 * 00414 * Create this kernel2D as a copy of a section of another kernel2D 00415 * 00416 * @param other the genericLattice2D to be copied. 00417 * @param from initial position in the other genericLattice2D to be copied 00418 * @param to last position to be copied of the other genericLattice2D 00419 */ 00420 kernel2D(const genericLattice2D<T>& other, 00421 const size_type& from, 00422 const size_type& to); 00423 00424 /** 00425 * Copy constructor. 00426 * 00427 * Create this kernel2D as a copy of a sublattice2D of another 00428 * genericLattice2D. 00429 * 00430 * @param other the genericLattice2D to be copied. 00431 * @param rows interval of rows to be copied. 00432 * @param columns interval of columns to be copied. 00433 */ 00434 kernel2D(const genericLattice2D<T>& other, 00435 const iinterval& rows, 00436 const iinterval& columns); 00437 00438 /** 00439 * Copy constructor. 00440 * 00441 * Create this kernel2D as a copy of another genericLattice2D 00442 * taking only the rows indicated by the vector. 00443 * 00444 * The data will be always copied! Multiple occurence of one row index in 00445 * \a rows is allowed. 00446 * 00447 * @param other the genericLattice2D to be copied. 00448 * @param rows indices of the rows to be copied 00449 */ 00450 kernel2D(const genericLattice2D<T>& other, 00451 const genericLattice1D<int>& rows); 00452 00453 00454 00455 /** 00456 * Copy constructor 00457 * @param other the one dimensional kernel to be copied 00458 */ 00459 kernel2D(const kernel2D& other); 00460 00461 /** 00462 * Destructor 00463 */ 00464 virtual ~kernel2D(); 00465 00466 /** 00467 * Copy member 00468 * @param other the one dimensional kernel to be copied 00469 * @return a reference to this instance 00470 */ 00471 kernel2D& copy(const kernel2D& other); 00472 00473 /** 00474 * Returns the name of this type. 00475 */ 00476 virtual const std::string& name() const; 00477 00478 /** 00479 * Clone member 00480 * @return a pointer to a copy of this object 00481 */ 00482 virtual kernel2D<T>* clone() const; 00483 00484 /** 00485 * Create a new instance. 00486 * @return a pointer to a new empty kernel instance 00487 */ 00488 virtual kernel2D<T>* newInstance() const; 00489 00490 /** 00491 * Copy from kernel of different type 00492 * @param other a one dimensional kernel of another type 00493 * @return a reference to this instance 00494 */ 00495 template<class U> 00496 kernel2D& castFrom(const kernel2D<U>& other) { 00497 lattice2D<T>::castFrom(other); 00498 norm_ = T(other.getNorm()); 00499 return (*this); 00500 } 00501 00502 /** 00503 * Get normalization factor 00504 * 00505 * The normalization factor is used by the fixed point types as a 00506 * representation of the value 1. For example, the norm for a 00507 * kernel2D<ubyte> can be 255, if the filter kernel don't need values 00508 * greater than 1.0. 00509 */ 00510 inline const T& getNorm() const { 00511 return norm_; 00512 } 00513 00514 /** 00515 * Set normalization factor 00516 * @see getNorm() 00517 */ 00518 inline void setNorm(const T& n) { 00519 norm_=n; 00520 }; 00521 00522 /** 00523 * Normalize divides all elements by the norm and sets the norm to 1! 00524 */ 00525 void normalize(); 00526 00527 /** 00528 * @name Symmetries 00529 */ 00530 //@{ 00531 /** 00532 * Mirror the other kernel and leave the result here, i.e. 00533 * at(x,y) = other.at(-x,-y); 00534 * @param other the kernel to be copied and then mirrored 00535 * @return a reference to this instance 00536 */ 00537 kernel2D<T>& mirror(const kernel2D<T>& other); 00538 00539 /** 00540 * Mirror this kernel, i.e. 00541 * at(x,y) = at(-x,-y); 00542 * @return a reference to this instance 00543 */ 00544 kernel2D<T>& mirror(); 00545 //@} 00546 00547 /** 00548 * Write the object in the given ioHandler 00549 */ 00550 virtual bool write(ioHandler& handler,const bool complete = true) const; 00551 00552 /** 00553 * Read the object from the given ioHandler 00554 */ 00555 virtual bool read(ioHandler& handler,const bool complete = true); 00556 00557 protected: 00558 /** 00559 * Normalization factor. 00560 * 00561 * This value will be ignored for floating point formats. 00562 * For fixed point formats, this value corresponds to 1.0 00563 */ 00564 T norm_; 00565 }; 00566 00567 00568 // ---------------------------------------------------------- 00569 // Typical used types 00570 // ---------------------------------------------------------- 00571 00572 /** 00573 * One dimensional kernel of integers 00574 */ 00575 typedef kernel2D<int32> ikernel2D; 00576 00577 /** 00578 * One dimensional kernel of floats 00579 */ 00580 typedef kernel2D<float> fkernel2D; 00581 00582 /** 00583 * One dimensional kernel of doubles 00584 */ 00585 typedef kernel2D<double> dkernel2D; 00586 00587 /** 00588 * One dimensional kernel of unsigned bytes 00589 */ 00590 typedef kernel2D<ubyte> bkernel2D; 00591 00592 00593 } 00594 #endif