1 /*#****************************************************************************** 2 ** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 3 ** 4 ** By downloading, copying, installing or using the software you agree to this license. 5 ** If you do not agree to this license, do not download, install, 6 ** copy or use the software. 7 ** 8 ** 9 ** bioinspired : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab. 10 ** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping. 11 ** 12 ** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications) 13 ** 14 ** Creation - enhancement process 2007-2011 15 ** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France 16 ** 17 ** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr). 18 ** Refer to the following research paper for more information: 19 ** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011 20 ** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book: 21 ** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891. 22 ** 23 ** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author : 24 ** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper: 25 ** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007 26 ** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions. 27 ** ====> more informations in the above cited Jeanny Heraults's book. 28 ** 29 ** License Agreement 30 ** For Open Source Computer Vision Library 31 ** 32 ** Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 33 ** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. 34 ** 35 ** For Human Visual System tools (bioinspired) 36 ** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved. 37 ** 38 ** Third party copyrights are property of their respective owners. 39 ** 40 ** Redistribution and use in source and binary forms, with or without modification, 41 ** are permitted provided that the following conditions are met: 42 ** 43 ** * Redistributions of source code must retain the above copyright notice, 44 ** this list of conditions and the following disclaimer. 45 ** 46 ** * Redistributions in binary form must reproduce the above copyright notice, 47 ** this list of conditions and the following disclaimer in the documentation 48 ** and/or other materials provided with the distribution. 49 ** 50 ** * The name of the copyright holders may not be used to endorse or promote products 51 ** derived from this software without specific prior written permission. 52 ** 53 ** This software is provided by the copyright holders and contributors "as is" and 54 ** any express or implied warranties, including, but not limited to, the implied 55 ** warranties of merchantability and fitness for a particular purpose are disclaimed. 56 ** In no event shall the Intel Corporation or contributors be liable for any direct, 57 ** indirect, incidental, special, exemplary, or consequential damages 58 ** (including, but not limited to, procurement of substitute goods or services; 59 ** loss of use, data, or profits; or business interruption) however caused 60 ** and on any theory of liability, whether in contract, strict liability, 61 ** or tort (including negligence or otherwise) arising in any way out of 62 ** the use of this software, even if advised of the possibility of such damage. 63 *******************************************************************************/ 64 65 #ifndef __TEMPLATEBUFFER_HPP__ 66 #define __TEMPLATEBUFFER_HPP__ 67 68 #include <valarray> 69 #include <cstdlib> 70 #include <iostream> 71 #include <cmath> 72 73 74 //#define __TEMPLATEBUFFERDEBUG //define TEMPLATEBUFFERDEBUG in order to display debug information 75 76 namespace cv 77 { 78 namespace bioinspired 79 { 80 //// If a parallelization method is available then, you should define MAKE_PARALLEL, in the other case, the classical serial code will be used 81 #define MAKE_PARALLEL 82 // ==> then include required includes 83 #ifdef MAKE_PARALLEL 84 85 // ==> declare usefull generic tools 86 template <class type> 87 class Parallel_clipBufferValues: public cv::ParallelLoopBody 88 { 89 private: 90 type *bufferToClip; 91 type minValue, maxValue; 92 93 public: Parallel_clipBufferValues(type * bufferToProcess,const type min,const type max)94 Parallel_clipBufferValues(type* bufferToProcess, const type min, const type max) 95 : bufferToClip(bufferToProcess), minValue(min), maxValue(max) { } 96 operator ()(const cv::Range & r) const97 virtual void operator()( const cv::Range &r ) const CV_OVERRIDE { 98 type *inputOutputBufferPTR=bufferToClip+r.start; 99 for (int jf = r.start; jf != r.end; ++jf, ++inputOutputBufferPTR) 100 { 101 if (*inputOutputBufferPTR>maxValue) 102 *inputOutputBufferPTR=maxValue; 103 else if (*inputOutputBufferPTR<minValue) 104 *inputOutputBufferPTR=minValue; 105 } 106 } 107 }; 108 #endif 109 110 /** 111 * @class TemplateBuffer 112 * @brief this class is a simple template memory buffer which contains basic functions to get information on or normalize the buffer content 113 * note that thanks to the parent STL template class "valarray", it is possible to perform easily operations on the full array such as addition, product etc. 114 * @author Alexandre BENOIT (benoit.alexandre.vision@gmail.com), helped by Gelu IONESCU (gelu.ionescu@lis.inpg.fr) 115 * creation date: september 2007 116 */ 117 template <class type> class TemplateBuffer : public std::valarray<type> 118 { 119 public: 120 121 /** 122 * constructor for monodimensional array 123 * @param dim: the size of the vector 124 */ TemplateBuffer(const size_t dim=0)125 TemplateBuffer(const size_t dim=0) 126 : std::valarray<type>((type)0, dim) 127 { 128 _NBrows=1; 129 _NBcolumns=dim; 130 _NBdepths=1; 131 _NBpixels=dim; 132 _doubleNBpixels=2*dim; 133 } 134 135 /** 136 * constructor by copy for monodimensional array 137 * @param pVal: the pointer to a buffer to copy 138 * @param dim: the size of the vector 139 */ TemplateBuffer(const type * pVal,const size_t dim)140 TemplateBuffer(const type* pVal, const size_t dim) 141 : std::valarray<type>(pVal, dim) 142 { 143 _NBrows=1; 144 _NBcolumns=dim; 145 _NBdepths=1; 146 _NBpixels=dim; 147 _doubleNBpixels=2*dim; 148 } 149 150 /** 151 * constructor for bidimensional array 152 * @param dimRows: the size of the vector 153 * @param dimColumns: the size of the vector 154 * @param depth: the number of layers of the buffer in its third dimension (3 of color images, 1 for gray images. 155 */ TemplateBuffer(const size_t dimRows,const size_t dimColumns,const size_t depth=1)156 TemplateBuffer(const size_t dimRows, const size_t dimColumns, const size_t depth=1) 157 : std::valarray<type>((type)0, dimRows*dimColumns*depth) 158 { 159 #ifdef TEMPLATEBUFFERDEBUG 160 std::cout<<"TemplateBuffer::TemplateBuffer: new buffer, size="<<dimRows<<", "<<dimColumns<<", "<<depth<<"valarraySize="<<this->size()<<std::endl; 161 #endif 162 _NBrows=dimRows; 163 _NBcolumns=dimColumns; 164 _NBdepths=depth; 165 _NBpixels=dimRows*dimColumns; 166 _doubleNBpixels=2*dimRows*dimColumns; 167 //_createTableIndex(); 168 #ifdef TEMPLATEBUFFERDEBUG 169 std::cout<<"TemplateBuffer::TemplateBuffer: construction successful"<<std::endl; 170 #endif 171 172 } 173 174 /** 175 * copy constructor 176 * @param toCopy 177 * @return thenconstructed instance 178 *emplateBuffer(const TemplateBuffer &toCopy) 179 :_NBrows(toCopy.getNBrows()),_NBcolumns(toCopy.getNBcolumns()),_NBdepths(toCopy.getNBdephs()), _NBpixels(toCopy.getNBpixels()), _doubleNBpixels(toCopy.getNBpixels()*2) 180 //std::valarray<type>(toCopy) 181 { 182 memcpy(Buffer(), toCopy.Buffer(), this->size()); 183 }*/ 184 /** 185 * destructor 186 */ ~TemplateBuffer()187 virtual ~TemplateBuffer() 188 { 189 #ifdef TEMPLATEBUFFERDEBUG 190 std::cout<<"~TemplateBuffer"<<std::endl; 191 #endif 192 } 193 194 /** 195 * delete the buffer content (set zeros) 196 */ setZero()197 inline void setZero() { std::valarray<type>::operator=(0); } //memset(Buffer(), 0, sizeof(type)*_NBpixels); } 198 199 /** 200 * @return the numbers of rows (height) of the images used by the object 201 */ getNBrows()202 inline unsigned int getNBrows() { return (unsigned int)_NBrows; } 203 204 /** 205 * @return the numbers of columns (width) of the images used by the object 206 */ getNBcolumns()207 inline unsigned int getNBcolumns() { return (unsigned int)_NBcolumns; } 208 209 /** 210 * @return the numbers of pixels (width*height) of the images used by the object 211 */ getNBpixels()212 inline unsigned int getNBpixels() { return (unsigned int)_NBpixels; } 213 214 /** 215 * @return the numbers of pixels (width*height) of the images used by the object 216 */ getDoubleNBpixels()217 inline unsigned int getDoubleNBpixels() { return (unsigned int)_doubleNBpixels; } 218 219 /** 220 * @return the numbers of depths (3rd dimension: 1 for gray images, 3 for rgb images) of the images used by the object 221 */ getDepthSize()222 inline unsigned int getDepthSize() { return (unsigned int)_NBdepths; } 223 224 /** 225 * resize the buffer and recompute table index etc. 226 */ resizeBuffer(const size_t dimRows,const size_t dimColumns,const size_t depth=1)227 void resizeBuffer(const size_t dimRows, const size_t dimColumns, const size_t depth=1) 228 { 229 this->resize(dimRows*dimColumns*depth); 230 _NBrows=dimRows; 231 _NBcolumns=dimColumns; 232 _NBdepths=depth; 233 _NBpixels=dimRows*dimColumns; 234 _doubleNBpixels=2*dimRows*dimColumns; 235 } 236 operator =(const std::valarray<type> & b)237 inline TemplateBuffer<type> & operator=(const std::valarray<type> &b) 238 { 239 //std::cout<<"TemplateBuffer<type> & operator= affect vector: "<<std::endl; 240 std::valarray<type>::operator=(b); 241 return *this; 242 } 243 operator =(const type & b)244 inline TemplateBuffer<type> & operator=(const type &b) 245 { 246 //std::cout<<"TemplateBuffer<type> & operator= affect value: "<<b<<std::endl; 247 std::valarray<type>::operator=(b); 248 return *this; 249 } 250 251 /* inline const type &operator[](const unsigned int &b) 252 { 253 return (*this)[b]; 254 } 255 */ 256 /** 257 * @return the buffer adress in non const mode 258 */ Buffer()259 inline type* Buffer() { return &(*this)[0]; } 260 261 /////////////////////////////////////////////////////// 262 // Standard Image manipulation functions 263 264 /** 265 * standard 0 to 255 image normalization function 266 * @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized 267 * @param nbPixels: specifies the number of pixel on which the normalization should be performed, if 0, then all pixels specified in the constructor are processed 268 * @param maxOutputValue: the maximum output value 269 */ 270 static void normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t nbPixels, const type maxOutputValue=(type)255.0); 271 272 /** 273 * standard 0 to 255 image normalization function 274 * @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized 275 * @param nbPixels: specifies the number of pixel on which the normalization should be performed, if 0, then all pixels specified in the constructor are processed 276 * @param maxOutputValue: the maximum output value 277 */ normalizeGrayOutput_0_maxOutputValue(const type maxOutputValue=(type)255.0)278 void normalizeGrayOutput_0_maxOutputValue(const type maxOutputValue=(type)255.0) { normalizeGrayOutput_0_maxOutputValue(this->Buffer(), this->size(), maxOutputValue); } 279 280 /** 281 * sigmoide image normalization function (saturates min and max values) 282 * @param meanValue: specifies the mean value of th pixels to be processed 283 * @param sensitivity: strength of the sigmoide 284 * @param inputPicture: the image to be normalized if no parameter, then, the built in buffer reachable by getOutput() function is normalized 285 * @param outputBuffer: the ouput buffer on which the result is writed, if no parameter, then, the built in buffer reachable by getOutput() function is normalized 286 * @param maxOutputValue: the maximum output value 287 */ 288 static void normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputPicture, type *outputBuffer, const unsigned int nbPixels); 289 290 /** 291 * sigmoide image normalization function on the current buffer (saturates min and max values) 292 * @param meanValue: specifies the mean value of th pixels to be processed 293 * @param sensitivity: strength of the sigmoide 294 * @param maxOutputValue: the maximum output value 295 */ normalizeGrayOutputCentredSigmoide(const type meanValue=(type)0.0,const type sensitivity=(type)2.0,const type maxOutputValue=(type)255.0)296 inline void normalizeGrayOutputCentredSigmoide(const type meanValue=(type)0.0, const type sensitivity=(type)2.0, const type maxOutputValue=(type)255.0) { CV_UNUSED(maxOutputValue); normalizeGrayOutputCentredSigmoide(meanValue, sensitivity, 255.0, this->Buffer(), this->Buffer(), this->getNBpixels()); } 297 298 /** 299 * sigmoide image normalization function (saturates min and max values), in this function, the sigmoide is centered on low values (high saturation of the medium and high values 300 * @param inputPicture: the image to be normalized if no parameter, then, the built in buffer reachable by getOutput() function is normalized 301 * @param outputBuffer: the ouput buffer on which the result is writed, if no parameter, then, the built in buffer reachable by getOutput() function is normalized 302 * @param sensitivity: strength of the sigmoide 303 * @param maxOutputValue: the maximum output value 304 */ 305 void normalizeGrayOutputNearZeroCentreredSigmoide(type *inputPicture=(type*)NULL, type *outputBuffer=(type*)NULL, const type sensitivity=(type)40, const type maxOutputValue=(type)255.0); 306 307 /** 308 * center and reduct the image (image-mean)/std 309 * @param inputOutputBuffer: the image to be normalized if no parameter, the result is rewrited on it 310 */ 311 void centerReductImageLuminance(type *inputOutputBuffer=(type*)NULL); 312 313 /** 314 * @return standard deviation of the buffer 315 */ getStandardDeviation()316 double getStandardDeviation() 317 { 318 double standardDeviation=0; 319 double meanValue=getMean(); 320 321 type *bufferPTR=Buffer(); 322 for (unsigned int i=0;i<this->size();++i) 323 { 324 double diff=(*(bufferPTR++)-meanValue); 325 standardDeviation+=diff*diff; 326 } 327 return std::sqrt(standardDeviation/this->size()); 328 } 329 330 /** 331 * Clip buffer histogram 332 * @param minRatio: the minimum ratio of the lower pixel values, range=[0,1] and lower than maxRatio 333 * @param maxRatio: the aximum ratio of the higher pixel values, range=[0,1] and higher than minRatio 334 */ clipHistogram(double minRatio,double maxRatio,double maxOutputValue)335 void clipHistogram(double minRatio, double maxRatio, double maxOutputValue) 336 { 337 338 if (minRatio>=maxRatio) 339 { 340 std::cerr<<"TemplateBuffer::clipHistogram: minRatio must be inferior to maxRatio, buffer unchanged"<<std::endl; 341 return; 342 } 343 344 /* minRatio=min(max(minRatio, 1.0),0.0); 345 maxRatio=max(max(maxRatio, 0.0),1.0); 346 */ 347 348 // find the pixel value just above the threshold 349 const double maxThreshold=this->max()*maxRatio; 350 const double minThreshold=(this->max()-this->min())*minRatio+this->min(); 351 352 type *bufferPTR=this->Buffer(); 353 354 double deltaH=maxThreshold; 355 double deltaL=maxThreshold; 356 357 double updatedHighValue=maxThreshold; 358 double updatedLowValue=maxThreshold; 359 360 for (unsigned int i=0;i<this->size();++i) 361 { 362 double curentValue=(double)*(bufferPTR++); 363 364 // updating "closest to the high threshold" pixel value 365 double highValueTest=maxThreshold-curentValue; 366 if (highValueTest>0) 367 { 368 if (deltaH>highValueTest) 369 { 370 deltaH=highValueTest; 371 updatedHighValue=curentValue; 372 } 373 } 374 375 // updating "closest to the low threshold" pixel value 376 double lowValueTest=curentValue-minThreshold; 377 if (lowValueTest>0) 378 { 379 if (deltaL>lowValueTest) 380 { 381 deltaL=lowValueTest; 382 updatedLowValue=curentValue; 383 } 384 } 385 } 386 387 std::cout<<"Tdebug"<<std::endl; 388 std::cout<<"deltaL="<<deltaL<<", deltaH="<<deltaH<<std::endl; 389 std::cout<<"this->max()"<<this->max()<<"maxThreshold="<<maxThreshold<<"updatedHighValue="<<updatedHighValue<<std::endl; 390 std::cout<<"this->min()"<<this->min()<<"minThreshold="<<minThreshold<<"updatedLowValue="<<updatedLowValue<<std::endl; 391 // clipping values outside than the updated thresholds 392 bufferPTR=this->Buffer(); 393 #ifdef MAKE_PARALLEL // call the TemplateBuffer multitreaded clipping method 394 parallel_for_(cv::Range(0,this->size()), Parallel_clipBufferValues<type>(bufferPTR, updatedLowValue, updatedHighValue)); 395 #else 396 397 for (unsigned int i=0;i<this->size();++i, ++bufferPTR) 398 { 399 if (*bufferPTR<updatedLowValue) 400 *bufferPTR=updatedLowValue; 401 else if (*bufferPTR>updatedHighValue) 402 *bufferPTR=updatedHighValue; 403 } 404 #endif 405 normalizeGrayOutput_0_maxOutputValue(this->Buffer(), this->size(), maxOutputValue); 406 407 } 408 409 /** 410 * @return the mean value of the vector 411 */ getMean()412 inline double getMean() { return this->sum()/this->size(); } 413 414 protected: 415 size_t _NBrows; 416 size_t _NBcolumns; 417 size_t _NBdepths; 418 size_t _NBpixels; 419 size_t _doubleNBpixels; 420 // utilities 421 static type _abs(const type x); 422 423 }; 424 425 /////////////////////////////////////////////////////////////////////// 426 /// normalize output between 0 and 255, can be applied on images of different size that the declared size if nbPixels parameters is setted up; 427 template <class type> normalizeGrayOutput_0_maxOutputValue(type * inputOutputBuffer,const size_t processedPixels,const type maxOutputValue)428 void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t processedPixels, const type maxOutputValue) 429 { 430 type maxValue=inputOutputBuffer[0], minValue=inputOutputBuffer[0]; 431 432 // get the min and max value 433 type *inputOutputBufferPTR=inputOutputBuffer; 434 for (size_t j = 0; j<processedPixels; ++j) 435 { 436 type pixValue = *(inputOutputBufferPTR++); 437 if (maxValue < pixValue) 438 maxValue = pixValue; 439 else if (minValue > pixValue) 440 minValue = pixValue; 441 } 442 // change the range of the data to 0->255 443 444 type factor = maxOutputValue/(maxValue-minValue); 445 type offset = (type)(-minValue*factor); 446 447 inputOutputBufferPTR=inputOutputBuffer; 448 for (size_t j = 0; j < processedPixels; ++j, ++inputOutputBufferPTR) 449 *inputOutputBufferPTR=*(inputOutputBufferPTR)*factor+offset; 450 451 } 452 // normalize data with a sigmoide close to 0 (saturates values for those superior to 0) 453 template <class type> normalizeGrayOutputNearZeroCentreredSigmoide(type * inputBuffer,type * outputBuffer,const type sensitivity,const type maxOutputValue)454 void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *inputBuffer, type *outputBuffer, const type sensitivity, const type maxOutputValue) 455 { 456 if (inputBuffer==NULL) 457 inputBuffer=Buffer(); 458 if (outputBuffer==NULL) 459 outputBuffer=Buffer(); 460 461 type X0cube=sensitivity*sensitivity*sensitivity; 462 463 type *inputBufferPTR=inputBuffer; 464 type *outputBufferPTR=outputBuffer; 465 466 for (size_t j = 0; j < _NBpixels; ++j, ++inputBufferPTR) 467 { 468 469 type currentCubeLuminance=*inputBufferPTR**inputBufferPTR**inputBufferPTR; 470 *(outputBufferPTR++)=maxOutputValue*currentCubeLuminance/(currentCubeLuminance+X0cube); 471 } 472 } 473 474 // normalize and adjust luminance with a centered to 128 sigmode 475 template <class type> normalizeGrayOutputCentredSigmoide(const type meanValue,const type sensitivity,const type maxOutputValue,type * inputBuffer,type * outputBuffer,const unsigned int nbPixels)476 void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputBuffer, type *outputBuffer, const unsigned int nbPixels) 477 { 478 479 if (sensitivity==1.0) 480 { 481 std::cerr<<"TemplateBuffer::TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide error: 2nd parameter (sensitivity) must not equal 0, copying original data..."<<std::endl; 482 memcpy(outputBuffer, inputBuffer, sizeof(type)*nbPixels); 483 return; 484 } 485 486 type X0=maxOutputValue/(sensitivity-(type)1.0); 487 488 type *inputBufferPTR=inputBuffer; 489 type *outputBufferPTR=outputBuffer; 490 491 for (size_t j = 0; j < nbPixels; ++j, ++inputBufferPTR) 492 *(outputBufferPTR++)=(meanValue+(meanValue+X0)*(*(inputBufferPTR)-meanValue)/(_abs(*(inputBufferPTR)-meanValue)+X0)); 493 494 } 495 496 // center and reduct the image (image-mean)/std 497 template <class type> centerReductImageLuminance(type * inputOutputBuffer)498 void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer) 499 { 500 // if outputBuffer unsassigned, the rewrite the buffer 501 if (inputOutputBuffer==NULL) 502 inputOutputBuffer=Buffer(); 503 type meanValue=0, stdValue=0; 504 505 // compute mean value 506 for (size_t j = 0; j < _NBpixels; ++j) 507 meanValue+=inputOutputBuffer[j]; 508 meanValue/=((type)_NBpixels); 509 510 // compute std value 511 type *inputOutputBufferPTR=inputOutputBuffer; 512 for (size_t index=0;index<_NBpixels;++index) 513 { 514 type inputMinusMean=*(inputOutputBufferPTR++)-meanValue; 515 stdValue+=inputMinusMean*inputMinusMean; 516 } 517 518 stdValue=std::sqrt(stdValue/((type)_NBpixels)); 519 // adjust luminance in regard of mean and std value; 520 inputOutputBufferPTR=inputOutputBuffer; 521 for (size_t index=0;index<_NBpixels;++index, ++inputOutputBufferPTR) 522 *inputOutputBufferPTR=(*(inputOutputBufferPTR)-meanValue)/stdValue; 523 } 524 525 526 template <class type> _abs(const type x)527 type TemplateBuffer<type>::_abs(const type x) 528 { 529 530 if (x>0) 531 return x; 532 else 533 return -x; 534 } 535 536 template < > _abs(const int x)537 inline int TemplateBuffer<int>::_abs(const int x) 538 { 539 return std::abs(x); 540 } 541 template < > _abs(const double x)542 inline double TemplateBuffer<double>::_abs(const double x) 543 { 544 return std::fabs(x); 545 } 546 547 template < > _abs(const float x)548 inline float TemplateBuffer<float>::_abs(const float x) 549 { 550 return std::fabs(x); 551 } 552 553 }// end of namespace bioinspired 554 }// end of namespace cv 555 #endif 556