latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiMaskFunctors.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 08.10.99 00030 * revisions ..: $Id: ltiMaskFunctors.h,v 1.6 2007/02/22 00:15:40 hawk78 Exp $ 00031 */ 00032 00033 #ifndef _LTI_MASKFUNCTORS_H_ 00034 #define _LTI_MASKFUNCTORS_H_ 00035 00036 #include "ltiFunctor.h" 00037 #include "ltiMatrix.h" 00038 #include "ltiTypeInfo.h" 00039 00040 namespace lti { 00041 /** 00042 * The mask functor is a colection of boolean operations used in the 00043 * processing of mask images or matrices. All members are used in derived 00044 * classes, which provide the LTI-Lib standard interface. 00045 * The template parameter is the type of the matrices to be operated and NOT 00046 * the whole matrix type. For example: 00047 * \code 00048 * lti::maskFunctor<channel8::value_type> masker; 00049 * channel8 a,b,result; 00050 * ... 00051 * masker.multiply(a,b,result); 00052 * \endcode 00053 * @see lti::maskMultiply, lti::maskAlgebraicSum, lti::maskOr, lti::maskAnd, 00054 * lti::maskNot, lti::maskInvert 00055 */ 00056 template<class T> 00057 class maskFunctor : public functor { 00058 public: 00059 /** 00060 * constructor 00061 */ 00062 maskFunctor(); 00063 00064 /** 00065 * copy constructor 00066 */ 00067 maskFunctor(const maskFunctor<T>& other) : functor() {copy(other);}; 00068 00069 /** 00070 * destructor 00071 */ 00072 virtual ~maskFunctor(); 00073 00074 /** 00075 * returns the name of this type 00076 */ 00077 const char* getTypeName() const {return "maskFunctor";}; 00078 00079 /** 00080 * clones this object 00081 */ 00082 functor* clone() const { 00083 return (new maskFunctor(*this)); 00084 }; 00085 00086 /** 00087 * copy 00088 */ 00089 void copy(const maskFunctor<T>& other); 00090 00091 /** 00092 * multiplies the normalized first mask with the second and leaves 00093 * the result on the second mask. The size of m2 will not be 00094 * modified (i.e. only the common submatrix will be considered!!!) 00095 * 00096 * @param m1 first matrix 00097 * @param m2 second matrix and result container 00098 * @return a reference to m2 00099 */ 00100 matrix<T>& multiply(const matrix<T>& m1,matrix<T>& m2); 00101 00102 /** 00103 * multiplies the normalized first mask with the second and leaves 00104 * the result on the third mask. The size of 'result' is as big as the 00105 * biggest matrix. 00106 * 00107 * @param m1 first matrix 00108 * @param m2 second matrix 00109 * @param result result container 00110 * @return a reference to result 00111 */ 00112 matrix<T>& multiply(const matrix<T>& m1, 00113 const matrix<T>& m2, 00114 matrix<T>& result); 00115 00116 /** 00117 * calculates the algebraic sum for each element of the normalized 00118 * matrixes. The algebraic sum of <em>a</em> and <em>b</em> is 00119 * defined as follows: <pre> s = 1 - (1-a)(1-b). </pre> This is 00120 * some sort of OR operator. The size of m1 will not be 00121 * modified (i.e. only the common submatrix will be considered) 00122 * 00123 * @param m1 first matrix 00124 * @param m2 second matrix and result container 00125 * @return a reference to m2 00126 */ 00127 matrix<T>& algebraicSum(const matrix<T>& m1,matrix<T>& m2); 00128 00129 /** 00130 * calculates the algebraic sum for each element of the matrixes. 00131 * The algebraic sum of a and b is defined as follows: 00132 * <pre> s = 1 - (1-a)(1-b). </pre> 00133 * This is used in the implementation of OR. 00134 * The size of <em>result</em> is as big as the biggest matrix. 00135 * 00136 * @param m1 first matrix 00137 * @param m2 second matrix 00138 * @param result result container 00139 * @return a reference to result 00140 */ 00141 matrix<T>& algebraicSum(const matrix<T>& m1, 00142 const matrix<T>& m2, 00143 matrix<T>& result); 00144 00145 /** 00146 * the m2 pixel will contain the norm value (see suggestedNorm()) if any 00147 * of both mask's pixels is not null 00148 * 00149 * @param m1 first matrix 00150 * @param m2 second matrix and result container 00151 * @return a reference to m2 00152 */ 00153 matrix<T>& maskOr(const matrix<T>& m1,matrix<T>& m2); 00154 00155 /** 00156 * the result pixel will contain the norm value (see 00157 * suggestedNorm()) if any of both mask's pixels is not null 00158 * 00159 * @param m1 first matrix 00160 * @param m2 second matrix 00161 * @param result result container 00162 * @return a reference to result 00163 */ 00164 matrix<T>& maskOr(const matrix<T>& m1, 00165 const matrix<T>& m2, 00166 matrix<T>& result); 00167 00168 /** 00169 * the m2 pixel will contain the norm value (see suggestedNorm()) if both 00170 * mask's pixels are not zero, otherwise the value is zero. 00171 * 00172 * @param m1 first matrix 00173 * @param m2 second matrix and result container 00174 * @return a reference to m2 00175 */ 00176 matrix<T>& maskAnd(const matrix<T>& m1,matrix<T>& m2); 00177 00178 /** 00179 * the result pixel will contain the norm value (see 00180 * suggestedNorm()) if both mask's pixels are not zero, otherwise 00181 * the value is zero. 00182 * 00183 * @param m1 first matrix 00184 * @param m2 second matrix 00185 * @param result result container 00186 * @return a reference to result 00187 */ 00188 matrix<T>& maskAnd(const matrix<T>& m1, 00189 const matrix<T>& m2, 00190 matrix<T>& result); 00191 00192 /** 00193 * the value of the mask will be zero if the original value is not zero and 00194 * viceversa. 00195 * 00196 * @param m matrix to be inverted. The result will be left here too. 00197 * @return a reference to m 00198 */ 00199 matrix<T>& maskNot(matrix<T>& m); 00200 00201 /** 00202 * the result of the mask will be zero if the original value is 00203 * not zero and viceversa. 00204 * 00205 * @param m1 first matrix 00206 * @param result result container 00207 * @return a reference to result 00208 */ 00209 matrix<T>& maskNot(const matrix<T>& m1, 00210 matrix<T>& result); 00211 00212 /** 00213 * inverts the values in the matrix m, where "inversion" means the 00214 * suggestedNorm() minus the original matrix entry value. 00215 * 00216 * @param m matrix to be inverted. The result is left here too. 00217 * @return a reference to the matrix m 00218 */ 00219 matrix<T>& invert(matrix<T>& m); 00220 00221 /** 00222 * inverts the values in the matrix m, where "inversion" means the 00223 * suggestedNorm() minus the original matrix entry value. 00224 * 00225 * @param m1 matrix to be inverted. 00226 * @param result the result is left here. 00227 * @return a reference to the matrix result. 00228 */ 00229 matrix<T>& invert(const matrix<T>& m1, 00230 matrix<T>& result); 00231 00232 /** 00233 * apply the given function at each pixel of m1 and leave the 00234 * result in the <code>result</code> matrix. 00235 * 00236 * @param m1 the first matrix 00237 * @param result the resulting matrix. The size of this matrix will be 00238 * the size of m1 00239 * @param function the function to be applied. The first parameter will 00240 * be the element value of the first matrix, the second 00241 * parameter will be usually a normalization factor. 00242 * @return true if successful, false otherwise. 00243 */ 00244 bool apply(const matrix<T>& m1, 00245 matrix<T>& result, 00246 T (*function)(const T&, 00247 const T&)) const; 00248 00249 /** 00250 * apply the given function at each pixel of srcdest and leave the 00251 * result there too. 00252 * 00253 * @param srcdest the source and destination matrix 00254 * @param function the function to be applied. The first parameter will 00255 * be the element value of the first matrix, the second parameter 00256 * will be usually a normalization factor. 00257 * @return true if successful, false otherwise. 00258 */ 00259 bool apply(matrix<T>& srcdest, 00260 T (*function)(const T&,const T&)) const; 00261 00262 /** 00263 * apply the given function at each element of m1 and m2 and leave the 00264 * result in the <code>result</code> matrix. 00265 * @param m1 the first matrix 00266 * @param m2 the second matrix 00267 * @param result the resulting matrix. The size of this matrix will be 00268 * the smallest matrix which can contain both matrices m1 and m2. 00269 * For those parts covered only by one of the matrices, the assumed 00270 * value for the other one will be zero. 00271 * @param function the function to be applied. The first parameter will 00272 * be the element value of the first matrix, the second 00273 * parameter the element value of the second matrix and the 00274 * third parameter will be usually a normalization factor. 00275 * @return true if successful, false otherwise. 00276 */ 00277 bool apply(const matrix<T>& m1, 00278 const matrix<T>& m2, 00279 matrix<T>& result, 00280 T (*function)(const T&,const T&,const T&)) const; 00281 00282 /** 00283 * apply the given function at each element of m1 and srcdest and 00284 * leave the result in the <code>srcdest</code> matrix. 00285 * @param m1 the first matrix 00286 * @param srcdest the second matrix and also the resulting matrix. 00287 * Its size won't be changed. For those parts covered only 00288 * by one of the matrices, the assumed 00289 * value for the other one will be zero. 00290 * @param function the function to be applied. The first parameter will 00291 * be the element value of the first matrix, the second 00292 * parameter the element value of the second matrix and the 00293 * third parameter will be usually a normalization factor. 00294 * @return true if successful, false otherwise. 00295 */ 00296 bool apply(const matrix<T>& m1, 00297 matrix<T>& srcdest, 00298 T (*function)(const T&,const T&,const T&)) const; 00299 00300 /** 00301 * this "dummy" apply member is just an interface for the subclasses 00302 * which will follow the standard LTI-Lib approach. This doesn't do 00303 * anything at all... 00304 * 00305 * @param m1 the first matrix to operate with 00306 * @param m2 the second matrix to operate with 00307 * @param result the matrix where the result will be left 00308 * @return true if successful, false otherwise. 00309 */ 00310 virtual bool apply(const matrix<T>& m1, 00311 const matrix<T>& m2, 00312 matrix<T>& result) const { 00313 throw functor::invalidMethodException(); 00314 return false; 00315 } 00316 00317 /** 00318 * this "dummy" apply member is just an interface for the subclasses 00319 * which will follow the standard LTI-Lib approach. This doesn't do 00320 * anything at all... 00321 * 00322 * @param m1 the first matrix to operate with 00323 * @param result the matrix where the result will be left 00324 * @return true if successful, false otherwise. 00325 */ 00326 virtual bool apply(const matrix<T>& m1, 00327 matrix<T>& result) const { 00328 throw functor::invalidMethodException(); 00329 return false; 00330 } 00331 00332 protected: 00333 /** 00334 * calculates a*b/norm; 00335 * 00336 * @param a first parameter 00337 * @param b second parameter 00338 * @param norm norm factor used 00339 * @return a*b/norm 00340 */ 00341 static T multiplyNorm(const T& a,const T& b,const T& norm) { 00342 return a*b/norm; 00343 } 00344 00345 /** 00346 * calculates a*b; 00347 * 00348 * @param a first parameter 00349 * @param b second parameter 00350 * @param norm norm factor used 00351 * @return a*b 00352 */ 00353 static T multiplyNoNorm(const T& a,const T& b,const T& norm) { 00354 return a*b; 00355 } 00356 00357 /** 00358 * calculates the algebraic sum = norm - (norm-a)*(norm-b)/norm 00359 * 00360 * @param a first parameter 00361 * @param b second parameter 00362 * @param norm norm factor used 00363 * @return norm - (norm-a)*(norm-b)/norm 00364 */ 00365 static T algebraicSumNorm(const T& a,const T& b,const T& norm) { 00366 return norm - static_cast<T>((norm-a)*(norm-b)/norm); 00367 } 00368 00369 /** 00370 * calculates algebraic sum = norm - (norm-a)*(norm-b)/norm 00371 * 00372 * @param a first parameter 00373 * @param b second parameter 00374 * @param norm norm factor used 00375 * @return norm - (norm-a)*(norm-b)/norm 00376 */ 00377 static T algebraicSumNoNorm(const T& a,const T& b,const T& norm) { 00378 return norm - static_cast<T>((norm-a)*(norm-b)); 00379 } 00380 00381 /** 00382 * calculates (a or b) 00383 * 00384 * @param a first parameter 00385 * @param b second parameter 00386 * @param norm norm factor used 00387 * @return a or b 00388 */ 00389 static T orNorm(const T& a,const T& b,const T& norm) { 00390 return (((a != 0) || (b != 0))) ? norm : static_cast<T>(0); 00391 } 00392 00393 /** 00394 * calculates (a and b) 00395 * 00396 * @param a first parameter 00397 * @param b second parameter 00398 * @param norm norm factor used 00399 * @return a and b 00400 */ 00401 static T andNorm(const T& a,const T& b,const T& norm) { 00402 return (((a != 0) && (b != 0))) ? norm : static_cast<T>(0); 00403 } 00404 00405 /** 00406 * calculates (not a) 00407 * 00408 * @param a first parameter 00409 * @param norm norm factor used 00410 * @return not a 00411 */ 00412 static T notMaskNorm(const T& a,const T& norm) { 00413 return (a == 0) ? norm : static_cast<T>(0); 00414 } 00415 00416 /** 00417 * calculates norm-a; 00418 * 00419 * @param a first parameter 00420 * @param norm norm factor used 00421 * @return norm-a 00422 */ 00423 static T invertNorm(const T& a,const T& norm) { 00424 return norm-a; 00425 } 00426 00427 /** 00428 * a static member can be one of following things 00429 */ 00430 enum eFunctionType { 00431 Black, /**< if a parameter is zero, the result is zero */ 00432 NoEffect, /**< if a parameter is zero, the result will be the 00433 other value */ 00434 White, /**< if the result is zero, the result will be the norm */ 00435 Unknown /**< unknown masking effect!*/ 00436 }; 00437 00438 /** 00439 * check a function. if par==0 the first parameter will be set to zero 00440 * otherwise the second parameters will be set to zero. 00441 * 00442 * @param function the function to be checked 00443 * @param par flag used. 00444 * @return the function type 00445 */ 00446 eFunctionType check(T (*function)(const T&,const T&,const T&), 00447 const int& par) const; 00448 00449 }; 00450 00451 00452 /** 00453 * alias with standard LTI-Lib interface for mask-multiply member of the 00454 * maskFunctor 00455 */ 00456 template<class T> 00457 class maskMultiply : public maskFunctor<T> { 00458 public: 00459 /** 00460 * apply on place (see also lti::maskFunctor::multiply()) 00461 * 00462 * @param m1 first matrix 00463 * @param m2 second matrix and result container 00464 * @return true if successful, false otherwise 00465 */ 00466 bool apply(const matrix<T>& m1, matrix<T>& m2) { 00467 multiply(m1,m2); 00468 return true; 00469 }; 00470 00471 /** 00472 * apply on copy (see also lti::maskFunctor::multiply()) 00473 * 00474 * @param m1 first matrix 00475 * @param m2 second matrix 00476 * @param result result container 00477 * @return true if successful, false otherwise 00478 */ 00479 bool apply(const matrix<T>& m1, 00480 const matrix<T>& m2, 00481 matrix<T>& result) { 00482 multiply(m1,m2,result); 00483 return true; 00484 }; 00485 }; 00486 00487 /** 00488 * alias with standard LTI-Lib interface for mask-algebraicSum member of the 00489 * maskFunctor 00490 */ 00491 template<class T> 00492 class maskAlgebraicSum : public maskFunctor<T> { 00493 public: 00494 /** 00495 * apply on place (see also lti::maskFunctor::algebraicSum()) 00496 * 00497 * @param m1 first matrix 00498 * @param m2 second matrix and result container 00499 * @return true if successful, false otherwise 00500 */ 00501 bool apply(const matrix<T>& m1, matrix<T>& m2) { 00502 algebraicSum(m1,m2); 00503 return true; 00504 }; 00505 00506 /** 00507 * apply on copy (see also lti::maskFunctor::algebraicSum()) 00508 * 00509 * @param m1 first matrix 00510 * @param m2 second matrix 00511 * @param result result container 00512 * @return true if successful, false otherwise 00513 */ 00514 bool apply(const matrix<T>& m1, 00515 const matrix<T>& m2, 00516 matrix<T>& result) { 00517 algebraicSum(m1,m2,result); 00518 return true; 00519 }; 00520 }; 00521 00522 /** 00523 * alias with standard LTI-interface for maskOr member of the 00524 * maskFunctor 00525 */ 00526 template<class T> 00527 class maskOr : public maskFunctor<T> { 00528 public: 00529 /** 00530 * apply on place (see also lti::maskFunctor::maskOr()) 00531 * 00532 * @param m1 first matrix 00533 * @param m2 second matrix and result container 00534 * @return true if successful, false otherwise 00535 */ 00536 bool apply(const matrix<T>& m1, matrix<T>& m2) { 00537 maskFunctor<T>::maskOr(m1,m2); 00538 return true; 00539 }; 00540 00541 /** 00542 * apply on copy (see also lti::maskFunctor::maskOr()) 00543 * 00544 * @param m1 first matrix 00545 * @param m2 second matrix 00546 * @param result result container 00547 * @return true if successful, false otherwise 00548 */ 00549 bool apply(const matrix<T>& m1, 00550 const matrix<T>& m2, 00551 matrix<T>& result) { 00552 maskFunctor<T>::maskOr(m1,m2,result); 00553 return true; 00554 }; 00555 }; 00556 00557 /** 00558 * alias with standard LTI-Lib interface for maskAnd member of the 00559 * maskFunctor 00560 */ 00561 template<class T> 00562 class maskAnd : public maskFunctor<T> { 00563 public: 00564 /** 00565 * apply on place (see also lti::maskFunctor::maskAnd()) 00566 * 00567 * @param m1 first matrix 00568 * @param m2 second matrix and result container 00569 * @return true if successful, false otherwise 00570 */ 00571 bool apply(const matrix<T>& m1, matrix<T>& m2) { 00572 maskFunctor<T>::maskAnd(m1,m2); 00573 return true; 00574 }; 00575 00576 /** 00577 * apply on copy (see also lti::maskFunctor::maskAnd()) 00578 * 00579 * @param m1 first matrix 00580 * @param m2 second matrix 00581 * @param result result container 00582 * @return true if successful, false otherwise 00583 */ 00584 bool apply(const matrix<T>& m1, 00585 const matrix<T>& m2, 00586 matrix<T>& result) { 00587 maskFunctor<T>::maskAnd(m1,m2,result); 00588 return true; 00589 }; 00590 }; 00591 00592 /** 00593 * alias with standard LTI-Lib interface for maskNot member of the 00594 * maskFunctor 00595 */ 00596 template<class T> 00597 class maskNot : public maskFunctor<T> { 00598 public: 00599 /** 00600 * apply on place (see also lti::maskFunctor::maskNot()) 00601 * 00602 * @param m1 source matrix and result 00603 * @return true if successful, false otherwise 00604 */ 00605 bool apply(matrix<T>& m1) { 00606 maskFunctor<T>::maskNot(m1); 00607 return true; 00608 }; 00609 00610 /** 00611 * apply on copy (see also lti::maskFunctor::maskNot()) 00612 * 00613 * @param m1 first matrix 00614 * @param result result container 00615 * @return true if successful, false otherwise 00616 */ 00617 bool apply(const matrix<T>& m1, 00618 matrix<T>& result) { 00619 maskFunctor<T>::maskNot(m1,result); 00620 return true; 00621 }; 00622 }; 00623 00624 /** 00625 * alias with standard LTI-Lib interface for invert member of the 00626 * maskFunctor 00627 */ 00628 template<class T> 00629 class maskInvert : public maskFunctor<T> { 00630 public: 00631 /** 00632 * apply on place 00633 * apply on place (see also lti::maskFunctor::maskNot()) 00634 * 00635 * @param m1 source matrix and result 00636 * @return true if successful, false otherwise 00637 */ 00638 bool apply(matrix<T>& m1) { 00639 invert(m1); 00640 return true; 00641 }; 00642 00643 /** 00644 * apply on copy 00645 * 00646 * @param m1 first matrix 00647 * @param result result container 00648 * @return true if successful, false otherwise 00649 */ 00650 bool apply(const matrix<T>& m1, 00651 matrix<T>& result) { 00652 invert(m1,result); 00653 return true; 00654 }; 00655 }; 00656 00657 } 00658 00659 00660 #endif