last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 2007 00003 * ITCR, Pablo Alvarado 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 cvrNoise.h 00043 * Contains the class cvr::noise, used to add noise to matrices, images 00044 * channels or vectors in a controlled way. 00045 * \author Pablo Alvarado 00046 * \date 27.09.2007 00047 * 00048 * revisions ..: $Id: cvrNoise.h,v 1.2 2007/09/29 00:37:11 alvarado Exp $ 00049 */ 00050 00051 #ifndef _CVR_NOISE_H_ 00052 #define _CVR_NOISE_H_ 00053 00054 #include "cvrMatrix.h" 00055 #include "cvrMatrixProcessingInterface.h" 00056 #include "cvrUnivariateContinuousDistribution.h" 00057 #include "cvrUniformDiscreteDistribution.h" 00058 #include "cvrFunctor.h" 00059 00060 namespace cvr { 00061 00062 /** 00063 * Class noise. 00064 * 00065 * This class is used to add noise to an image. In its default configuration 00066 * gaussian white noise is added to all pixels of the image. 00067 * 00068 * The random number generators provided to this class have to be continuous 00069 * distributions, which means they generate floating point values. For the 00070 * fixed point types, like \c int and \c ubyte, the normalization constants 00071 * provided by cvr::typeInfo<T>::suggestedNorm() are multiplied to the values 00072 * generated by the distribution, prior to the addition to the actual value 00073 * of each matrix element. 00074 * 00075 * You can indicate with the parameter coverage how much of the pixels do you 00076 * want to be altered with noise, where the specific pixels chosen for 00077 * modification (if less than 100%) are also taken randomly. 00078 * 00079 * The following example uses noise to generate a sample image with different 00080 * degrees of noise. 00081 * 00082 * \code 00083 * #include "cvrViewer2D.h" 00084 * #include "cvrMath.h" 00085 * #include "cvrNoise.h" 00086 * #include "cvrNormalDistribution.h" 00087 * 00088 * // ... 00089 * 00090 * channel chnl,chnl2,nchnl; 00091 * viewer2D view("Original"); 00092 * 00093 * noise noiser; 00094 * 00095 * // create a black background with a grey square on which a 00096 * // white square lies. 00097 * chnl.assign(100,100,0.0f); // 100x100 with black 00098 * chnl.fill(0.5f,20,20,79,79); // leave a border of 20 00099 * chnl.fill(1.0f,40,40,59,59); // the white square 00100 * 00101 * // a large canvas to place 5x5 images like the channel just created 00102 * chnl2.allocate(chnl.rows()*5,chnl.columns()*5); 00103 * 00104 * // use a normal distribution 00105 * normalDistribution nd; 00106 * normalDistribution::parameters ndp; 00107 * 00108 * for (int y=0;y<5;++y) { 00109 * for (int x=0;x<5;++x) { 00110 * ndp.sigma = (y*5 + x)/50.0; // set the standard deviation 00111 * nd.setParameters(ndp); // into the normal distribution 00112 * noiser.setNoiseGenerator(nd); // which has to be used 00113 * 00114 * noiser.apply(chnl,nchnl); // add the noise 00115 * 00116 * // place the new noisy patch on the canvas 00117 * chnl2.fill(nchnl,y*chnl.rows(),x*chnl.columns()); 00118 * } 00119 * } 00120 * 00121 * // show the canvas 00122 * view.show(chnl2); 00123 * \endcode 00124 * 00125 * @see noise::parameters. 00126 * 00127 * @ingroup gNonLinearFilters 00128 */ 00129 class noise : public functor, 00130 public matrixProcessingInterface<float>, 00131 public matrixProcessingInterface<double>, 00132 public matrixProcessingInterface<int>, 00133 public matrixProcessingInterface<ubyte> { 00134 public: 00135 /** 00136 * The parameters for the class noise 00137 */ 00138 class parameters : public functor::parameters { 00139 public: 00140 /** 00141 * Default constructor 00142 */ 00143 parameters(); 00144 00145 /** 00146 * Copy constructor 00147 * @param other the parameters object to be copied 00148 */ 00149 parameters(const parameters& other); 00150 00151 /** 00152 * Destructor 00153 */ 00154 ~parameters(); 00155 00156 /** 00157 * Copy the contents of a parameters object 00158 * @param other the parameters object to be copied 00159 * @return a reference to this parameters object 00160 */ 00161 parameters& copy(const parameters& other); 00162 00163 /** 00164 * Copy the contents of a parameters object 00165 * @param other the parameters object to be copied 00166 * @return a reference to this parameters object 00167 */ 00168 parameters& operator=(const parameters& other); 00169 00170 /** 00171 * Returns the complete name of the parameters class. 00172 */ 00173 virtual const std::string& name() const; 00174 00175 /** 00176 * Returns a pointer to a clone of the parameters. 00177 */ 00178 virtual parameters* clone() const; 00179 00180 /** 00181 * Returns a pointer to a new instance of the parameters. 00182 */ 00183 virtual parameters* newInstance() const; 00184 00185 /** 00186 * Write the parameters in the given ioHandler 00187 * @param handler the ioHandler to be used 00188 * @param complete if true (the default) the enclosing begin/end will 00189 * be also written, otherwise only the data block will be written. 00190 * @return true if write was successful 00191 */ 00192 virtual bool write(ioHandler& handler,const bool complete=true) const; 00193 00194 /** 00195 * Read the parameters from the given ioHandler 00196 * @param handler the ioHandler to be used 00197 * @param complete if true (the default) the enclosing begin/end will 00198 * be also written, otherwise only the data block will be written. 00199 * @return true if write was successful 00200 */ 00201 virtual bool read(ioHandler& handler,const bool complete=true); 00202 00203 // ------------------------------------------------ 00204 // the parameters 00205 // ------------------------------------------------ 00206 00207 /** 00208 * Percentage of the container elements that are selected for 00209 * modification. The value has to be between 0.0f and 100.0f. 00210 * 00211 * If the value is greater than or equal to 100.0f, then all container 00212 * elements are subject to modification. If the value is less than, or 00213 * equal to zero, then nothing is done to the container. 00214 * 00215 * Default value: 100.0f 00216 */ 00217 float coverage; 00218 00219 /** 00220 * Crop values. 00221 * 00222 * If crop is true, then the resulting values below zero are set 00223 * to zero, and the values above 1.0 for float and double, or 00224 * 255 for ubyte, or 65535 for int are set to those values. 00225 * 00226 * Default value: true 00227 */ 00228 bool crop; 00229 00230 00231 /** 00232 * Parameters for the container element selector 00233 * 00234 * If \c coverage is less than 100%, then a uniform random number 00235 * generator is employed to select the container elements to be modified. 00236 * These are the parameters for the uniform discrete distribution class 00237 * employed in the pixel selection. 00238 * 00239 * The \c min and \c max members will be ignored, as they have to be set 00240 * new in each apply method, due to the possible container size change. 00241 * 00242 * Default value: default parameters. 00243 */ 00244 uniformDiscreteDistribution::parameters selectorParameters; 00245 00246 /** 00247 * Set the random number generator to be used. 00248 * 00249 * A copy of the given generator will be done. 00250 * 00251 * The default value is a normalDistribution with zero mean and a 00252 * standard deviation of 0.25. 00253 */ 00254 bool setNoiseGenerator(univariateContinuousDistribution& generator); 00255 00256 /** 00257 * Get the random number generator to be used. 00258 * 00259 * The default value is a normalDistribution with zero mean and a 00260 * standard deviation of 0.25. 00261 */ 00262 univariateContinuousDistribution* getNoiseGenerator(); 00263 00264 protected: 00265 /** 00266 * Pointer to an instance of a continuous distribution instance. 00267 * 00268 * This instance is initialized with a normalDistribution object. 00269 */ 00270 univariateContinuousDistribution* generator_; 00271 00272 }; 00273 00274 /** 00275 * Default constructor 00276 */ 00277 noise(); 00278 00279 /** 00280 * Construct a functor using the given parameters 00281 */ 00282 noise(const parameters& par); 00283 00284 /** 00285 * Copy constructor 00286 * @param other the object to be copied 00287 */ 00288 noise(const noise& other); 00289 00290 /** 00291 * Destructor 00292 */ 00293 virtual ~noise(); 00294 00295 /** 00296 * Operates on the given argument. 00297 * 00298 * @param srcdest fmatrix with the source data. The result 00299 * will be left here too. 00300 * @return true if apply successful or false otherwise. 00301 */ 00302 bool apply(fmatrix& srcdest) const; 00303 00304 /** 00305 * Operates on the given argument. 00306 * 00307 * @param srcdest dmatrix with the source data. The result 00308 * will be left here too. 00309 * @return true if apply successful or false otherwise. 00310 */ 00311 bool apply(dmatrix& srcdest) const; 00312 00313 /** 00314 * Operates on the given argument. 00315 * 00316 * @param srcdest imatrix with the source data. The result 00317 * will be left here too. 00318 * @return true if apply successful or false otherwise. 00319 */ 00320 bool apply(imatrix& srcdest) const; 00321 00322 /** 00323 * Operates on the given argument. 00324 * 00325 * @param srcdest matrix<ubyte> with the source data. The result 00326 * will be left here too. 00327 * @return true if apply successful or false otherwise. 00328 */ 00329 bool apply(matrix<ubyte>& srcdest) const; 00330 00331 /** 00332 * Operates on the given argument. 00333 * 00334 * @param srcdest fvector with the source data. The result 00335 * will be left here too. 00336 * @return true if apply successful or false otherwise. 00337 */ 00338 bool apply(fvector& srcdest) const; 00339 00340 /** 00341 * Operates on the given argument. 00342 * 00343 * @param srcdest dvector with the source data. The result 00344 * will be left here too. 00345 * @return true if apply successful or false otherwise. 00346 */ 00347 bool apply(dvector& srcdest) const; 00348 00349 /** 00350 * Operates on the given argument. 00351 * 00352 * @param srcdest ivector with the source data. The result 00353 * will be left here too. 00354 * @return true if apply successful or false otherwise. 00355 */ 00356 bool apply(ivector& srcdest) const; 00357 00358 /** 00359 * Operates on a copy of the given arguments. 00360 * 00361 * @param src fmatrix with the source data. 00362 * @param dest fmatrix where the result will be left. 00363 * @return true if apply successful or false otherwise. 00364 */ 00365 bool apply(const fmatrix& src, fmatrix& dest) const; 00366 00367 /** 00368 * Operates on a copy of the given arguments. 00369 * 00370 * @param src dmatrix with the source data. 00371 * @param dest dmatrix where the result will be left. 00372 * @return true if apply successful or false otherwise. 00373 */ 00374 bool apply(const dmatrix& src, dmatrix& dest) const; 00375 00376 /** 00377 * Operates on a copy of the given arguments. 00378 * 00379 * @param src imatrix with the source data. 00380 * @param dest imatrix where the result will be left. 00381 * @return true if apply successful or false otherwise. 00382 */ 00383 bool apply(const imatrix& src, imatrix& dest) const; 00384 00385 /** 00386 * Operates on a copy of the given arguments. 00387 * 00388 * @param src matrix<ubyte> with the source data. 00389 * @param dest matrix<ubyte> where the result will be left. 00390 * @return true if apply successful or false otherwise. 00391 */ 00392 bool apply(const matrix<ubyte>& src, matrix<ubyte>& dest) const; 00393 00394 /** 00395 * Operates on a copy of the given arguments. 00396 * 00397 * @param src fvector with the source data. 00398 * @param dest fvector where the result will be left. 00399 * @return true if apply successful or false otherwise. 00400 */ 00401 bool apply(const fvector& src, fvector& dest) const; 00402 00403 /** 00404 * Operates on a copy of the given arguments. 00405 * 00406 * @param src dvector with the source data. 00407 * @param dest dvector where the result will be left. 00408 * @return true if apply successful or false otherwise. 00409 */ 00410 bool apply(const dvector& src, dvector& dest) const; 00411 00412 /** 00413 * Operates on a copy of the given arguments. 00414 * 00415 * @param src ivector with the source data. 00416 * @param dest ivector where the result will be left. 00417 * @return true if apply successful or false otherwise. 00418 */ 00419 bool apply(const ivector& src, ivector& dest) const; 00420 00421 00422 /** 00423 * Copy data of "other" functor. 00424 * @param other the functor to be copied 00425 * @return a reference to this functor object 00426 */ 00427 noise& copy(const noise& other); 00428 00429 /** 00430 * Alias for copy member 00431 * @param other the functor to be copied 00432 * @return a reference to this functor object 00433 */ 00434 noise& operator=(const noise& other); 00435 00436 /** 00437 * Returns the complete name of the functor class 00438 */ 00439 virtual const std::string& name() const; 00440 00441 /** 00442 * Returns a pointer to a clone of this functor. 00443 */ 00444 virtual noise* clone() const; 00445 00446 /** 00447 * Returns a pointer to a new instance of this functor. 00448 */ 00449 virtual noise* newInstance() const; 00450 00451 /** 00452 * Returns used parameters 00453 */ 00454 const parameters& getParameters() const; 00455 00456 /** 00457 * Update parameters when new set is given. 00458 */ 00459 bool updateParameters(); 00460 00461 /** 00462 * Set the random number generator to be used. 00463 */ 00464 bool setNoiseGenerator(univariateContinuousDistribution& generator); 00465 00466 /** 00467 * Get the random number generator to be used. 00468 * 00469 * The default value is a normalDistribution with zero mean and a 00470 * standard deviation of 0.25. 00471 */ 00472 univariateContinuousDistribution* getNoiseGenerator(); 00473 00474 protected: 00475 /** 00476 * Returns used parameters 00477 */ 00478 parameters& getParameters(); 00479 00480 /** 00481 * The noise generator 00482 */ 00483 mutable univariateContinuousDistribution* generator_; 00484 00485 /** 00486 * The generator for the coordinates 00487 */ 00488 mutable uniformDiscreteDistribution uniform_; 00489 00490 private: 00491 /** 00492 * The real thing! 00493 * 00494 * This method is the one used to add noise to all pixels 00495 * 00496 * @param srcdest the input image, on which noise will be added. 00497 */ 00498 template<typename T> 00499 inline bool addNoise(matrix<T>& srcdest) const; 00500 00501 /** 00502 * The real thing! 00503 * 00504 * This method is the one used to add noise to all pixels 00505 * 00506 * @param srcdest the input image, on which noise will be added. 00507 */ 00508 template<typename T> 00509 inline bool addNoise(vector<T>& srcdest) const; 00510 00511 /** 00512 * Crop the given value to the limits given by 00513 * cvr::typeInfo<T>::suggestedNorm() 00514 */ 00515 template<typename T,typename U> 00516 inline T crop(const U val) const; 00517 00518 }; 00519 } 00520 00521 #endif 00522