updated retina modules : minor misakes correction & changed pixel format to float instead of double to keep some memory, precision is almost sufficient, check for residual mistakes

This commit is contained in:
Alexandre Benoit 2011-08-21 11:01:53 +00:00
parent eb9401d353
commit 66ee335ca9
13 changed files with 486 additions and 483 deletions

View File

@ -159,10 +159,10 @@ void BasicRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBc
} }
// Change coefficients table // Change coefficients table
void BasicRetinaFilter::setLPfilterParameters(const double beta, const double tau, const double desired_k, const unsigned int filterIndex) void BasicRetinaFilter::setLPfilterParameters(const float beta, const float tau, const float desired_k, const unsigned int filterIndex)
{ {
double _beta = beta+tau; float _beta = beta+tau;
double k=desired_k; float k=desired_k;
// check if the spatial constant is correct (avoid 0 value to avoid division by 0) // check if the spatial constant is correct (avoid 0 value to avoid division by 0)
if (desired_k<=0) if (desired_k<=0)
{ {
@ -170,8 +170,8 @@ void BasicRetinaFilter::setLPfilterParameters(const double beta, const double ta
std::cerr<<"BasicRetinaFilter::spatial constant of the low pass filter must be superior to zero !!! correcting parameter setting to 0,001"<<std::endl; std::cerr<<"BasicRetinaFilter::spatial constant of the low pass filter must be superior to zero !!! correcting parameter setting to 0,001"<<std::endl;
} }
double _alpha = k*k; float _alpha = k*k;
double _mu = 0.8; float _mu = 0.8;
unsigned int tableOffset=filterIndex*3; unsigned int tableOffset=filterIndex*3;
if (k<=0) if (k<=0)
{ {
@ -179,8 +179,8 @@ void BasicRetinaFilter::setLPfilterParameters(const double beta, const double ta
_alpha=0.0001; _alpha=0.0001;
} }
double _temp = (1.0+_beta)/(2.0*_mu*_alpha); float _temp = (1.0+_beta)/(2.0*_mu*_alpha);
double _a = _filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0); float _a = _filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0);
_filteringCoeficientsTable[1+tableOffset]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta); _filteringCoeficientsTable[1+tableOffset]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta);
_filteringCoeficientsTable[2+tableOffset] =tau; _filteringCoeficientsTable[2+tableOffset] =tau;
@ -189,7 +189,7 @@ void BasicRetinaFilter::setLPfilterParameters(const double beta, const double ta
//std::cout<<"BasicRetinaFilter::_a="<<_a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl; //std::cout<<"BasicRetinaFilter::_a="<<_a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl;
} }
void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const double beta, const double tau, const double alpha0, const unsigned int filterIndex) void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex)
{ {
// check if dedicated buffers are already allocated, if not create them // check if dedicated buffers are already allocated, if not create them
if (_progressiveSpatialConstant.size()!=_filterOutput.size()) if (_progressiveSpatialConstant.size()!=_filterOutput.size())
@ -198,8 +198,8 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const doub
_progressiveGain.resize(_filterOutput.size()); _progressiveGain.resize(_filterOutput.size());
} }
double _beta = beta+tau; float _beta = beta+tau;
double _mu=0.8; float _mu=0.8;
if (alpha0<=0) if (alpha0<=0)
{ {
std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl; std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl;
@ -208,19 +208,19 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const doub
unsigned int tableOffset=filterIndex*3; unsigned int tableOffset=filterIndex*3;
double _alpha=0.8; float _alpha=0.8;
double _temp = (1.0+_beta)/(2.0*_mu*_alpha); float _temp = (1.0+_beta)/(2.0*_mu*_alpha);
double _a=_filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0); float _a=_filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0);
_filteringCoeficientsTable[tableOffset+1]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta); _filteringCoeficientsTable[tableOffset+1]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau; _filteringCoeficientsTable[tableOffset+2] =tau;
double commonFactor=alpha0/sqrt((double)(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows)+1.0); float commonFactor=alpha0/sqrt((float)(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows)+1.0);
//memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels()); //memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels());
for (unsigned int idColumn=0;idColumn<_halfNBcolumns; ++idColumn) for (unsigned int idColumn=0;idColumn<_halfNBcolumns; ++idColumn)
for (unsigned int idRow=0;idRow<_halfNBrows; ++idRow) for (unsigned int idRow=0;idRow<_halfNBrows; ++idRow)
{ {
// computing local spatial constant // computing local spatial constant
double localSpatialConstantValue=commonFactor*sqrt((double)(idColumn*idColumn)+(double)(idRow*idRow)); float localSpatialConstantValue=commonFactor*sqrt((float)(idColumn*idColumn)+(float)(idRow*idRow));
if (localSpatialConstantValue>1) if (localSpatialConstantValue>1)
localSpatialConstantValue=1; localSpatialConstantValue=1;
@ -230,7 +230,7 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const doub
_progressiveSpatialConstant[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localSpatialConstantValue; _progressiveSpatialConstant[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localSpatialConstantValue;
// computing local gain // computing local gain
double localGain=(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)/(1+_beta); float localGain=(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)/(1+_beta);
_progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain; _progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain;
_progressiveGain[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain; _progressiveGain[_halfNBcolumns-1-idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1+idRow)]=localGain;
_progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localGain; _progressiveGain[_halfNBcolumns-1+idColumn+_filterOutput.getNBcolumns()*(_halfNBrows-1-idRow)]=localGain;
@ -240,7 +240,7 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const doub
} }
} }
void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const double beta, const double tau, const double k, const std::valarray<double> &accuracyMap, const unsigned int filterIndex) void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const float beta, const float tau, const float k, const std::valarray<float> &accuracyMap, const unsigned int filterIndex)
{ {
if (accuracyMap.size()!=_filterOutput.size()) if (accuracyMap.size()!=_filterOutput.size())
@ -256,17 +256,17 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const doubl
_progressiveGain.resize(accuracyMap.size()); _progressiveGain.resize(accuracyMap.size());
} }
double _beta = beta+tau; float _beta = beta+tau;
double _alpha=k*k; float _alpha=k*k;
double _mu=0.8; float _mu=0.8;
if (k<=0) if (k<=0)
{ {
std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl; std::cerr<<"BasicRetinaFilter::spatial filtering coefficient must be superior to zero, correcting value to 0.01"<<std::endl;
//alpha0=0.0001; //alpha0=0.0001;
} }
unsigned int tableOffset=filterIndex*3; unsigned int tableOffset=filterIndex*3;
double _temp = (1.0+_beta)/(2.0*_mu*_alpha); float _temp = (1.0+_beta)/(2.0*_mu*_alpha);
double _a=_filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0); float _a=_filteringCoeficientsTable[tableOffset] = 1.0 + _temp - sqrt( (1.0+_temp)*(1.0+_temp) - 1.0);
_filteringCoeficientsTable[tableOffset+1]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta); _filteringCoeficientsTable[tableOffset+1]=(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau; _filteringCoeficientsTable[tableOffset+2] =tau;
@ -276,14 +276,14 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const doubl
{ {
// computing local spatial constant // computing local spatial constant
unsigned int index=idColumn+idRow*_filterOutput.getNBcolumns(); unsigned int index=idColumn+idRow*_filterOutput.getNBcolumns();
double localSpatialConstantValue=_a*accuracyMap[index]; float localSpatialConstantValue=_a*accuracyMap[index];
if (localSpatialConstantValue>1) if (localSpatialConstantValue>1)
localSpatialConstantValue=1; localSpatialConstantValue=1;
_progressiveSpatialConstant[index]=localSpatialConstantValue; _progressiveSpatialConstant[index]=localSpatialConstantValue;
// computing local gain // computing local gain
double localGain=(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)/(1+_beta); float localGain=(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)*(1-localSpatialConstantValue)/(1+_beta);
_progressiveGain[index]=localGain; _progressiveGain[index]=localGain;
//std::cout<<commonFactor<<", "<<sqrt((_halfNBcolumns-1-idColumn)+(_halfNBrows-idRow-1))<<", "<<(_halfNBcolumns-1-idColumn)<<", "<<(_halfNBrows-idRow-1)<<", "<<localSpatialConstantValue<<std::endl; //std::cout<<commonFactor<<", "<<sqrt((_halfNBcolumns-1-idColumn)+(_halfNBrows-idRow-1))<<", "<<(_halfNBcolumns-1-idColumn)<<", "<<(_halfNBrows-idRow-1)<<", "<<localSpatialConstantValue<<std::endl;
@ -293,105 +293,105 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const doubl
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
/// Local luminance adaptation functions /// Local luminance adaptation functions
// run local adaptation filter and save result in _filterOutput // run local adaptation filter and save result in _filterOutput
const std::valarray<double> &BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<double> &inputFrame, const std::valarray<double> &localLuminance) const std::valarray<float> &BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance)
{ {
_localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &_filterOutput[0]); _localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &_filterOutput[0]);
return _filterOutput; return _filterOutput;
} }
// run local adaptation filter at a specific output adress // run local adaptation filter at a specific output adress
void BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<double> &inputFrame, const std::valarray<double> &localLuminance, std::valarray<double> &outputFrame) void BasicRetinaFilter::runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance, std::valarray<float> &outputFrame)
{ {
_localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &outputFrame[0]); _localLuminanceAdaptation(get_data(inputFrame), get_data(localLuminance), &outputFrame[0]);
} }
// run local adaptation filter and save result in _filterOutput with autonomous low pass filtering before adaptation // run local adaptation filter and save result in _filterOutput with autonomous low pass filtering before adaptation
const std::valarray<double> &BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<double> &inputFrame) const std::valarray<float> &BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame)
{ {
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]); _spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]);
_localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &_filterOutput[0]); _localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &_filterOutput[0]);
return _filterOutput; return _filterOutput;
} }
// run local adaptation filter at a specific output adress with autonomous low pass filtering before adaptation // run local adaptation filter at a specific output adress with autonomous low pass filtering before adaptation
void BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<double> &inputFrame, std::valarray<double> &outputFrame) void BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame)
{ {
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]); _spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]);
_localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &outputFrame[0]); _localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &outputFrame[0]);
} }
// local luminance adaptation of the input in regard of localLuminance buffer // local luminance adaptation of the input in regard of localLuminance buffer
void BasicRetinaFilter::_localLuminanceAdaptation(const double *inputFrame, const double *localLuminance, double *outputFrame) void BasicRetinaFilter::_localLuminanceAdaptation(const float *inputFrame, const float *localLuminance, float *outputFrame)
{ {
double meanLuminance=0; float meanLuminance=0;
const double *luminancePTR=inputFrame; const float *luminancePTR=inputFrame;
for (unsigned int i=0;i<_filterOutput.getNBpixels();++i) for (unsigned int i=0;i<_filterOutput.getNBpixels();++i)
meanLuminance+=*(luminancePTR++); meanLuminance+=*(luminancePTR++);
meanLuminance/=_filterOutput.getNBpixels(); meanLuminance/=_filterOutput.getNBpixels();
//double tempMeanValue=meanLuminance+_meanInputValue*_tau; //float tempMeanValue=meanLuminance+_meanInputValue*_tau;
updateCompressionParameter(meanLuminance); updateCompressionParameter(meanLuminance);
//std::cout<<meanLuminance<<std::endl; //std::cout<<meanLuminance<<std::endl;
const double *localLuminancePTR=localLuminance; const float *localLuminancePTR=localLuminance;
const double *inputFramePTR=inputFrame; const float *inputFramePTR=inputFrame;
double *outputFramePTR=outputFrame; float *outputFramePTR=outputFrame;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR)
{ {
double X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon; float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
*(outputFramePTR++) = (_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0); *(outputFramePTR++) = (_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]); //std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
} }
} }
// local adaptation applied on a range of values which can be positive and negative // local adaptation applied on a range of values which can be positive and negative
void BasicRetinaFilter::_localLuminanceAdaptationPosNegValues(const double *inputFrame, const double *localLuminance, double *outputFrame) void BasicRetinaFilter::_localLuminanceAdaptationPosNegValues(const float *inputFrame, const float *localLuminance, float *outputFrame)
{ {
const double *localLuminancePTR=localLuminance; const float *localLuminancePTR=localLuminance;
const double *inputFramePTR=inputFrame; const float *inputFramePTR=inputFrame;
double *outputFramePTR=outputFrame; float *outputFramePTR=outputFrame;
double factor=_maxInputValue*2/CV_PI; float factor=_maxInputValue*2/CV_PI;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputFramePTR)
{ {
double X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon; float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
*(outputFramePTR++) = factor*atan(*inputFramePTR/X0);//(_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0); *(outputFramePTR++) = factor*atan(*inputFramePTR/X0);//(_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]); //std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
} }
} }
// local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output // local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output
void BasicRetinaFilter::_localLuminanceAdaptation(double *inputOutputFrame, const double *localLuminance) void BasicRetinaFilter::_localLuminanceAdaptation(float *inputOutputFrame, const float *localLuminance)
{ {
/*double meanLuminance=0; /*float meanLuminance=0;
const double *luminancePTR=inputOutputFrame; const float *luminancePTR=inputOutputFrame;
for (unsigned int i=0;i<_filterOutput.getNBpixels();++i) for (unsigned int i=0;i<_filterOutput.getNBpixels();++i)
meanLuminance+=*(luminancePTR++); meanLuminance+=*(luminancePTR++);
meanLuminance/=_filterOutput.getNBpixels(); meanLuminance/=_filterOutput.getNBpixels();
//double tempMeanValue=meanLuminance+_meanInputValue*_tau; //float tempMeanValue=meanLuminance+_meanInputValue*_tau;
updateCompressionParameter(meanLuminance); updateCompressionParameter(meanLuminance);
*/ */
const double *localLuminancePTR=localLuminance; const float *localLuminancePTR=localLuminance;
double *inputOutputFramePTR=inputOutputFrame; float *inputOutputFramePTR=inputOutputFrame;
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputOutputFramePTR) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel, ++inputOutputFramePTR)
{ {
double X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon; float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
*(inputOutputFramePTR) = (_maxInputValue+X0)**inputOutputFramePTR/(*inputOutputFramePTR +X0); *(inputOutputFramePTR) = (_maxInputValue+X0)**inputOutputFramePTR/(*inputOutputFramePTR +X0);
} }
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
/// Spatio temporal Low Pass filter functions /// Spatio temporal Low Pass filter functions
// run LP filter and save result in the basic retina element buffer // run LP filter and save result in the basic retina element buffer
const std::valarray<double> &BasicRetinaFilter::runFilter_LPfilter(const std::valarray<double> &inputFrame, const unsigned int filterIndex) const std::valarray<float> &BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, const unsigned int filterIndex)
{ {
_spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0], filterIndex); _spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0], filterIndex);
return _filterOutput; return _filterOutput;
} }
// run LP filter for a new frame input and save result at a specific output adress // run LP filter for a new frame input and save result at a specific output adress
void BasicRetinaFilter::runFilter_LPfilter(const std::valarray<double> &inputFrame, std::valarray<double> &outputFrame, const unsigned int filterIndex) void BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const unsigned int filterIndex)
{ {
_spatiotemporalLPfilter(get_data(inputFrame), &outputFrame[0], filterIndex); _spatiotemporalLPfilter(get_data(inputFrame), &outputFrame[0], filterIndex);
} }
// run LP filter on the input data and rewrite it // run LP filter on the input data and rewrite it
void BasicRetinaFilter::runFilter_LPfilter_Autonomous(std::valarray<double> &inputOutputFrame, const unsigned int filterIndex) void BasicRetinaFilter::runFilter_LPfilter_Autonomous(std::valarray<float> &inputOutputFrame, const unsigned int filterIndex)
{ {
unsigned int coefTableOffset=filterIndex*3; unsigned int coefTableOffset=filterIndex*3;
@ -408,7 +408,7 @@ void BasicRetinaFilter::runFilter_LPfilter_Autonomous(std::valarray<double> &inp
} }
// run LP filter for a new frame input and save result at a specific output adress // run LP filter for a new frame input and save result at a specific output adress
void BasicRetinaFilter::_spatiotemporalLPfilter(const double *inputFrame, double *outputFrame, const unsigned int filterIndex) void BasicRetinaFilter::_spatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{ {
unsigned int coefTableOffset=filterIndex*3; unsigned int coefTableOffset=filterIndex*3;
/**********/ /**********/
@ -425,7 +425,7 @@ void BasicRetinaFilter::_spatiotemporalLPfilter(const double *inputFrame, double
} }
// run SQUARING LP filter for a new frame input and save result at a specific output adress // run SQUARING LP filter for a new frame input and save result at a specific output adress
const double BasicRetinaFilter::_squaringSpatiotemporalLPfilter(const double *inputFrame, double *outputFrame, const unsigned int filterIndex) const float BasicRetinaFilter::_squaringSpatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{ {
unsigned int coefTableOffset=filterIndex*3; unsigned int coefTableOffset=filterIndex*3;
/**********/ /**********/
@ -445,15 +445,15 @@ const double BasicRetinaFilter::_squaringSpatiotemporalLPfilter(const double *in
// standard version of the 1D low pass filters // standard version of the 1D low pass filters
// horizontal causal filter which adds the input inside // horizontal causal filter which adds the input inside
void BasicRetinaFilter::_horizontalCausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalCausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ _a* result; result = *(outputPTR)+ _a* result;
@ -462,14 +462,14 @@ void BasicRetinaFilter::_horizontalCausalFilter(double *outputFrame, unsigned in
} }
} }
// horizontal causal filter which adds the input inside // horizontal causal filter which adds the input inside
void BasicRetinaFilter::_horizontalCausalFilter_addInput(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register const double* inputPTR=inputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns(); register const float* inputPTR=inputFrame+(IDrowStart+IDrow)*_filterOutput.getNBcolumns();
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(inputPTR++) + _tau**(outputPTR)+ _a* result; result = *(inputPTR++) + _tau**(outputPTR)+ _a* result;
@ -480,14 +480,14 @@ void BasicRetinaFilter::_horizontalCausalFilter_addInput(const double *inputFram
} }
// horizontal anticausal filter (basic way, no add on) // horizontal anticausal filter (basic way, no add on)
void BasicRetinaFilter::_horizontalAnticausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1; register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1;
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ _a* result; result = *(outputPTR)+ _a* result;
@ -498,14 +498,14 @@ void BasicRetinaFilter::_horizontalAnticausalFilter(double *outputFrame, unsigne
} }
// horizontal anticausal filter which multiplies the output by _gain // horizontal anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_horizontalAnticausalFilter_multGain(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalAnticausalFilter_multGain(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1; register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(_filterOutput.getNBcolumns())-1;
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ _a* result; result = *(outputPTR)+ _a* result;
@ -515,13 +515,13 @@ void BasicRetinaFilter::_horizontalAnticausalFilter_multGain(double *outputFrame
} }
// vertical anticausal filter // vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void BasicRetinaFilter::_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputFrame+IDcolumn; register float *outputPTR=outputFrame+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -535,14 +535,14 @@ void BasicRetinaFilter::_verticalCausalFilter(double *outputFrame, unsigned int
// vertical anticausal filter (basic way, no add on) // vertical anticausal filter (basic way, no add on)
void BasicRetinaFilter::_verticalAnticausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void BasicRetinaFilter::_verticalAnticausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
double* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=offset+IDcolumn; register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -555,14 +555,14 @@ void BasicRetinaFilter::_verticalAnticausalFilter(double *outputFrame, unsigned
} }
// vertical anticausal filter which multiplies the output by _gain // vertical anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_verticalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void BasicRetinaFilter::_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
double* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
//#pragma omp parallel for //#pragma omp parallel for
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=offset+IDcolumn; register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -579,13 +579,13 @@ void BasicRetinaFilter::_verticalAnticausalFilter_multGain(double *outputFrame,
// specific modifications of 1D filters // specific modifications of 1D filters
// -> squaring horizontal causal filter // -> squaring horizontal causal filter
void BasicRetinaFilter::_squaringHorizontalCausalFilter(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns(); register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(inputPTR)**(inputPTR) + _tau**(outputPTR)+ _a* result; result = *(inputPTR)**(inputPTR) + _tau**(outputPTR)+ _a* result;
@ -596,14 +596,14 @@ void BasicRetinaFilter::_squaringHorizontalCausalFilter(const double *inputFrame
} }
// vertical anticausal filter that returns the mean value of its result // vertical anticausal filter that returns the mean value of its result
const double BasicRetinaFilter::_verticalAnticausalFilter_returnMeanValue(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) const float BasicRetinaFilter::_verticalAnticausalFilter_returnMeanValue(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
register double meanValue=0; register float meanValue=0;
double* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=offset+IDcolumn; register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -615,11 +615,11 @@ const double BasicRetinaFilter::_verticalAnticausalFilter_returnMeanValue(double
} }
} }
return meanValue/(double)_filterOutput.getNBpixels(); return meanValue/(float)_filterOutput.getNBpixels();
} }
// LP filter with integration in specific areas (regarding true values of a binary parameters image) // LP filter with integration in specific areas (regarding true values of a binary parameters image)
void BasicRetinaFilter::_localSquaringSpatioTemporalLPfilter(const double *inputFrame, double *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex) void BasicRetinaFilter::_localSquaringSpatioTemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex)
{ {
unsigned int coefTableOffset=filterIndex*3; unsigned int coefTableOffset=filterIndex*3;
_a=_filteringCoeficientsTable[coefTableOffset+0]; _a=_filteringCoeficientsTable[coefTableOffset+0];
@ -638,14 +638,14 @@ void BasicRetinaFilter::_localSquaringSpatioTemporalLPfilter(const double *input
// same functions (some of them) but take a binary flag to allow integration, false flag means, no data change at the output... // same functions (some of them) but take a binary flag to allow integration, false flag means, no data change at the output...
// this function take an image in input and squares it befor computing // this function take an image in input and squares it befor computing
void BasicRetinaFilter::_local_squaringHorizontalCausalFilter(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas) void BasicRetinaFilter::_local_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas)
{ {
register double* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns(); register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
const unsigned int *integrationAreasPTR=integrationAreas; const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
if (*(integrationAreasPTR++)) if (*(integrationAreasPTR++))
@ -659,15 +659,15 @@ void BasicRetinaFilter::_local_squaringHorizontalCausalFilter(const double *inpu
} }
} }
void BasicRetinaFilter::_local_horizontalAnticausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas) void BasicRetinaFilter::_local_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas)
{ {
register double* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1; register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
const unsigned int *integrationAreasPTR=integrationAreas; const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
if (*(integrationAreasPTR++)) if (*(integrationAreasPTR++))
@ -680,14 +680,14 @@ void BasicRetinaFilter::_local_horizontalAnticausalFilter(double *outputFrame, u
} }
void BasicRetinaFilter::_local_verticalCausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas) void BasicRetinaFilter::_local_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas)
{ {
const unsigned int *integrationAreasPTR=integrationAreas; const unsigned int *integrationAreasPTR=integrationAreas;
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputFrame+IDcolumn; register float *outputPTR=outputFrame+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -702,15 +702,15 @@ void BasicRetinaFilter::_local_verticalCausalFilter(double *outputFrame, unsigne
} }
} }
// this functions affects _gain at the output // this functions affects _gain at the output
void BasicRetinaFilter::_local_verticalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas) void BasicRetinaFilter::_local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas)
{ {
const unsigned int *integrationAreasPTR=integrationAreas; const unsigned int *integrationAreasPTR=integrationAreas;
double* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=offset+IDcolumn; register float *outputPTR=offset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -730,7 +730,7 @@ void BasicRetinaFilter::_local_verticalAnticausalFilter_multGain(double *outputF
// -> USE IRREGULAR SPATIAL CONSTANT // -> USE IRREGULAR SPATIAL CONSTANT
// irregular filter computed from a buffer and rewrites it // irregular filter computed from a buffer and rewrites it
void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(double *inputOutputFrame, const unsigned int filterIndex) void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(float *inputOutputFrame, const unsigned int filterIndex)
{ {
if (_progressiveGain.size()==0) if (_progressiveGain.size()==0)
{ {
@ -750,7 +750,7 @@ void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(double *inputOutputFra
} }
// irregular filter computed from a buffer and puts result on another // irregular filter computed from a buffer and puts result on another
void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(const double *inputFrame, double *outputFrame, const unsigned int filterIndex) void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(const float *inputFrame, float *outputFrame, const unsigned int filterIndex)
{ {
if (_progressiveGain.size()==0) if (_progressiveGain.size()==0)
{ {
@ -771,13 +771,13 @@ void BasicRetinaFilter::_spatiotemporalLPfilter_Irregular(const double *inputFra
} }
// 1D filters with irregular spatial constant // 1D filters with irregular spatial constant
// horizontal causal filter wich runs on its input buffer // horizontal causal filter wich runs on its input buffer
void BasicRetinaFilter::_horizontalCausalFilter_Irregular(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalCausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns(); register const float* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ *(spatialConstantPTR++)* result; result = *(outputPTR)+ *(spatialConstantPTR++)* result;
@ -787,14 +787,14 @@ void BasicRetinaFilter::_horizontalCausalFilter_Irregular(double *outputFrame, u
} }
// horizontal causal filter with add input // horizontal causal filter with add input
void BasicRetinaFilter::_horizontalCausalFilter_Irregular_addInput(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalCausalFilter_Irregular_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns(); register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns(); register const float* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(inputPTR++) + _tau**(outputPTR)+ *(spatialConstantPTR++)* result; result = *(inputPTR++) + _tau**(outputPTR)+ *(spatialConstantPTR++)* result;
@ -805,14 +805,14 @@ void BasicRetinaFilter::_horizontalCausalFilter_Irregular_addInput(const double
} }
// horizontal anticausal filter (basic way, no add on) // horizontal anticausal filter (basic way, no add on)
void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1; register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
register const double* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowEnd*(_filterOutput.getNBcolumns())-1; register const float* spatialConstantPTR=&_progressiveSpatialConstant[0]+IDrowEnd*(_filterOutput.getNBcolumns())-1;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ *(spatialConstantPTR--)* result; result = *(outputPTR)+ *(spatialConstantPTR--)* result;
@ -824,13 +824,13 @@ void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(double *outputFram
} }
// vertical anticausal filter // vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter_Irregular(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void BasicRetinaFilter::_verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputFrame+IDcolumn; register float *outputPTR=outputFrame+IDcolumn;
register const double *spatialConstantPTR=&_progressiveSpatialConstant[0]+IDcolumn; register const float *spatialConstantPTR=&_progressiveSpatialConstant[0]+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
result = *(outputPTR) + *(spatialConstantPTR) * result; result = *(outputPTR) + *(spatialConstantPTR) * result;
@ -842,17 +842,17 @@ void BasicRetinaFilter::_verticalCausalFilter_Irregular(double *outputFrame, uns
} }
// vertical anticausal filter which multiplies the output by _gain // vertical anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_verticalAnticausalFilter_Irregular_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void BasicRetinaFilter::_verticalAnticausalFilter_Irregular_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
double* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
const double* constantOffset=&_progressiveSpatialConstant[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); const float* constantOffset=&_progressiveSpatialConstant[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
const double* gainOffset=&_progressiveGain[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); const float* gainOffset=&_progressiveGain[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputOffset+IDcolumn; register float *outputPTR=outputOffset+IDcolumn;
register const double *spatialConstantPTR=constantOffset+IDcolumn; register const float *spatialConstantPTR=constantOffset+IDcolumn;
register const double *progressiveGainPTR=gainOffset+IDcolumn; register const float *progressiveGainPTR=gainOffset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
result = *(outputPTR) + *(spatialConstantPTR) * result; result = *(outputPTR) + *(spatialConstantPTR) * result;

View File

@ -77,6 +77,10 @@
* -> progressive low pass filter filtering (higher filtering on the borders than on the center) * -> progressive low pass filter filtering (higher filtering on the borders than on the center)
* -> image data between 0 and 255 resampling with different options, linear rescaling, sigmoide) * -> image data between 0 and 255 resampling with different options, linear rescaling, sigmoide)
* *
* NOTE : initially the retina model was based on double format scalar values but
* a good memory/precision compromise is float...
* also the double format precision does not make so much sense from a biological point of view (neurons value coding is not so precise)
*
* TYPICAL USE: * TYPICAL USE:
* *
* // create object at a specified picture size * // create object at a specified picture size
@ -112,8 +116,7 @@
namespace cv namespace cv
{ {
class BasicRetinaFilter class BasicRetinaFilter
{ {
public: public:
/** /**
@ -164,7 +167,7 @@ public:
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering * @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
* @return the processed image, the output is reachable later by using function getOutput() * @return the processed image, the output is reachable later by using function getOutput()
*/ */
const std::valarray<double> &runFilter_LPfilter(const std::valarray<double> &inputFrame, const unsigned int filterIndex=0); // run the LP filter for a new frame input and save result in _filterOutput const std::valarray<float> &runFilter_LPfilter(const std::valarray<float> &inputFrame, const unsigned int filterIndex=0); // run the LP filter for a new frame input and save result in _filterOutput
/** /**
* low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors) * low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors)
@ -172,14 +175,14 @@ public:
* @param outputFrame: the output buffer in which the result is writed * @param outputFrame: the output buffer in which the result is writed
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering * @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
*/ */
void runFilter_LPfilter(const std::valarray<double> &inputFrame, std::valarray<double> &outputFrame, const unsigned int filterIndex=0); // run LP filter on a specific output adress void runFilter_LPfilter(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const unsigned int filterIndex=0); // run LP filter on a specific output adress
/** /**
* low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors) * low pass filter call and run (models the homogeneous cells network at the retina level, for example horizontal cells or photoreceptors)
* @param inputOutputFrame: the input image to be processed on which the result is rewrited * @param inputOutputFrame: the input image to be processed on which the result is rewrited
* @param filterIndex: the offset which specifies the parameter set that should be used for the filtering * @param filterIndex: the offset which specifies the parameter set that should be used for the filtering
*/ */
void runFilter_LPfilter_Autonomous(std::valarray<double> &inputOutputFrame, const unsigned int filterIndex=0);// run LP filter on the input data and rewrite it void runFilter_LPfilter_Autonomous(std::valarray<float> &inputOutputFrame, const unsigned int filterIndex=0);// run LP filter on the input data and rewrite it
/** /**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors) * local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
@ -187,7 +190,7 @@ public:
* @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering * @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering
* @return the processed image, the output is reachable later by using function getOutput() * @return the processed image, the output is reachable later by using function getOutput()
*/ */
const std::valarray<double> &runFilter_LocalAdapdation(const std::valarray<double> &inputOutputFrame, const std::valarray<double> &localLuminance);// run local adaptation filter and save result in _filterOutput const std::valarray<float> &runFilter_LocalAdapdation(const std::valarray<float> &inputOutputFrame, const std::valarray<float> &localLuminance);// run local adaptation filter and save result in _filterOutput
/** /**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors) * local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
@ -195,21 +198,21 @@ public:
* @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering * @param localLuminance: an image which represents the local luminance of the inputFrame parameter, in general, it is its low pass spatial filtering
* @param outputFrame: the output buffer in which the result is writed * @param outputFrame: the output buffer in which the result is writed
*/ */
void runFilter_LocalAdapdation(const std::valarray<double> &inputFrame, const std::valarray<double> &localLuminance, std::valarray<double> &outputFrame); // run local adaptation filter on a specific output adress void runFilter_LocalAdapdation(const std::valarray<float> &inputFrame, const std::valarray<float> &localLuminance, std::valarray<float> &outputFrame); // run local adaptation filter on a specific output adress
/** /**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors) * local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputFrame: the input image to be processed * @param inputFrame: the input image to be processed
* @return the processed image, the output is reachable later by using function getOutput() * @return the processed image, the output is reachable later by using function getOutput()
*/ */
const std::valarray<double> &runFilter_LocalAdapdation_autonomous(const std::valarray<double> &inputFrame);// run local adaptation filter and save result in _filterOutput const std::valarray<float> &runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame);// run local adaptation filter and save result in _filterOutput
/** /**
* local luminance adaptation call and run (contrast enhancement property of the photoreceptors) * local luminance adaptation call and run (contrast enhancement property of the photoreceptors)
* @param inputFrame: the input image to be processed * @param inputFrame: the input image to be processed
* @param outputFrame: the output buffer in which the result is writen * @param outputFrame: the output buffer in which the result is writen
*/ */
void runFilter_LocalAdapdation_autonomous(const std::valarray<double> &inputFrame, std::valarray<double> &outputFrame); // run local adaptation filter on a specific output adress void runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame); // run local adaptation filter on a specific output adress
/** /**
* run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners) * run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners)
@ -217,7 +220,7 @@ public:
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering * @param filterIndex: the index which specifies the parameter set that should be used for the filtering
* @return the processed image, the output is reachable later by using function getOutput() if outputFrame is NULL * @return the processed image, the output is reachable later by using function getOutput() if outputFrame is NULL
*/ */
inline void runProgressiveFilter(std::valarray<double> &inputFrame, const unsigned int filterIndex=0){_spatiotemporalLPfilter_Irregular(&inputFrame[0], filterIndex);}; inline void runProgressiveFilter(std::valarray<float> &inputFrame, const unsigned int filterIndex=0){_spatiotemporalLPfilter_Irregular(&inputFrame[0], filterIndex);};
/** /**
* run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners) * run low pass filtering with progressive parameters (models the retina log sampling of the photoreceptors and its low pass filtering effect consequence: more powerfull low pass filtering effect on the corners)
@ -225,8 +228,8 @@ public:
* @param outputFrame: the output buffer in which the result is writen * @param outputFrame: the output buffer in which the result is writen
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering * @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/ */
inline void runProgressiveFilter(const std::valarray<double> &inputFrame, inline void runProgressiveFilter(const std::valarray<float> &inputFrame,
std::valarray<double> &outputFrame, std::valarray<float> &outputFrame,
const unsigned int filterIndex=0) const unsigned int filterIndex=0)
{_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &outputFrame[0], filterIndex);}; {_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &outputFrame[0], filterIndex);};
@ -237,7 +240,7 @@ public:
* @param k: spatial constant of the filter (unit is pixels) * @param k: spatial constant of the filter (unit is pixels)
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering * @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/ */
void setLPfilterParameters(const double beta, const double tau, const double k, const unsigned int filterIndex=0); // change the parameters of the filter void setLPfilterParameters(const float beta, const float tau, const float k, const unsigned int filterIndex=0); // change the parameters of the filter
/** /**
* first order spatio-temporal low pass filter setup function * first order spatio-temporal low pass filter setup function
@ -246,17 +249,17 @@ public:
* @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image * @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering * @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/ */
void setProgressiveFilterConstants_CentredAccuracy(const double beta, const double tau, const double alpha0, const unsigned int filterIndex=0); void setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex=0);
/** /**
* first order spatio-temporal low pass filter setup function * first order spatio-temporal low pass filter setup function
* @param beta: gain of the filter (generally set to zero) * @param beta: gain of the filter (generally set to zero)
* @param tau: time constant of the filter (unit is frame for video processing) * @param tau: time constant of the filter (unit is frame for video processing)
* @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image * @param alpha0: spatial constant of the filter (unit is pixels) on the border of the image
* @param accuracyMap an image (double format) which values range is between 0 and 1, where 0 means, apply no filtering and 1 means apply the filtering as specified in the parameters set, intermediate values allow to smooth variations of the filtering strenght * @param accuracyMap an image (float format) which values range is between 0 and 1, where 0 means, apply no filtering and 1 means apply the filtering as specified in the parameters set, intermediate values allow to smooth variations of the filtering strenght
* @param filterIndex: the index which specifies the parameter set that should be used for the filtering * @param filterIndex: the index which specifies the parameter set that should be used for the filtering
*/ */
void setProgressiveFilterConstants_CustomAccuracy(const double beta, const double tau, const double alpha0, const std::valarray<double> &accuracyMap, const unsigned int filterIndex=0); void setProgressiveFilterConstants_CustomAccuracy(const float beta, const float tau, const float alpha0, const std::valarray<float> &accuracyMap, const unsigned int filterIndex=0);
/** /**
* local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation) * local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation)
@ -264,20 +267,20 @@ public:
* @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous) * @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous)
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI) * @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/ */
void setV0CompressionParameter(const double v0, const double maxInputValue, const double){ _v0=v0*maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=maxInputValue*(1.0-v0); _maxInputValue=maxInputValue;}; void setV0CompressionParameter(const float v0, const float maxInputValue, const float){ _v0=v0*maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=maxInputValue*(1.0-v0); _maxInputValue=maxInputValue;};
/** /**
* update local luminance adaptation setup, initial maxInputValue is kept. This function should be applied for normal local adaptation (not for tone mapping operation) * update local luminance adaptation setup, initial maxInputValue is kept. This function should be applied for normal local adaptation (not for tone mapping operation)
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect * @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI) * @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/ */
void setV0CompressionParameter(const double v0, const double meanLuminance){ this->setV0CompressionParameter(v0, _maxInputValue, meanLuminance);}; void setV0CompressionParameter(const float v0, const float meanLuminance){ this->setV0CompressionParameter(v0, _maxInputValue, meanLuminance);};
/** /**
* local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation) * local luminance adaptation setup, this function should be applied for normal local adaptation (not for tone mapping operation)
* @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect * @param v0: compression effect for the local luminance adaptation processing, set a value between 0.6 and 0.9 for best results, a high value yields to a high compression effect
*/ */
void setV0CompressionParameter(const double v0){ _v0=v0*_maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=_maxInputValue*(1.0-v0);}; void setV0CompressionParameter(const float v0){ _v0=v0*_maxInputValue; _localLuminanceFactor=v0; _localLuminanceAddon=_maxInputValue*(1.0-v0);};
/** /**
* local luminance adaptation setup, this function should be applied for local adaptation applied to tone mapping operation * local luminance adaptation setup, this function should be applied for local adaptation applied to tone mapping operation
@ -285,23 +288,23 @@ public:
* @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous) * @param maxInputValue: the maximum amplitude value measured after local adaptation processing (c.f. function runFilter_LocalAdapdation & runFilter_LocalAdapdation_autonomous)
* @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI) * @param meanLuminance: the a priori meann luminance of the input data (should be 128 for 8bits images but can vary greatly in case of High Dynamic Range Images (HDRI)
*/ */
void setV0CompressionParameterToneMapping(const double v0, const double maxInputValue, const double meanLuminance=128.0){ _v0=v0*maxInputValue; _localLuminanceFactor=1; _localLuminanceAddon=meanLuminance*_v0; _maxInputValue=maxInputValue;}; void setV0CompressionParameterToneMapping(const float v0, const float maxInputValue, const float meanLuminance=128.0){ _v0=v0*maxInputValue; _localLuminanceFactor=1; _localLuminanceAddon=meanLuminance*_v0; _maxInputValue=maxInputValue;};
/** /**
* update compression parameters while keeping v0 parameter value * update compression parameters while keeping v0 parameter value
* @param meanLuminance the input frame mean luminance * @param meanLuminance the input frame mean luminance
*/ */
inline void updateCompressionParameter(const double meanLuminance){_localLuminanceFactor=1; _localLuminanceAddon=meanLuminance*_v0;}; inline void updateCompressionParameter(const float meanLuminance){_localLuminanceFactor=1; _localLuminanceAddon=meanLuminance*_v0;};
/** /**
* @return the v0 compression parameter used to compute the local adaptation * @return the v0 compression parameter used to compute the local adaptation
*/ */
const double getV0CompressionParameter(){ return _v0/_maxInputValue;}; const float getV0CompressionParameter(){ return _v0/_maxInputValue;};
/** /**
* @return the output result of the object * @return the output result of the object
*/ */
inline const std::valarray<double> &getOutput() const {return _filterOutput;}; inline const std::valarray<float> &getOutput() const {return _filterOutput;};
/** /**
* @return number of rows of the filter * @return number of rows of the filter
@ -322,7 +325,7 @@ public:
* force filter output to be normalized between 0 and maxValue * force filter output to be normalized between 0 and maxValue
* @param maxValue: the maximum output value that is required * @param maxValue: the maximum output value that is required
*/ */
inline void normalizeGrayOutput_0_maxOutputValue(const double maxValue){_filterOutput.normalizeGrayOutput_0_maxOutputValue(maxValue);}; inline void normalizeGrayOutput_0_maxOutputValue(const float maxValue){_filterOutput.normalizeGrayOutput_0_maxOutputValue(maxValue);};
/** /**
* force filter output to be normalized around 0 and rescaled with a sigmoide effect (extrem values saturation) * force filter output to be normalized around 0 and rescaled with a sigmoide effect (extrem values saturation)
@ -339,99 +342,99 @@ public:
/** /**
* @return the maximum input buffer value * @return the maximum input buffer value
*/ */
inline const double getMaxInputValue(){return this->_maxInputValue;}; inline const float getMaxInputValue(){return this->_maxInputValue;};
/** /**
* @return the maximum input buffer value * @return the maximum input buffer value
*/ */
inline void setMaxInputValue(const double newMaxInputValue){this->_maxInputValue=newMaxInputValue;}; inline void setMaxInputValue(const float newMaxInputValue){this->_maxInputValue=newMaxInputValue;};
protected: protected:
///////////////////////// /////////////////////////
// data buffers // data buffers
TemplateBuffer<double> _filterOutput; // primary buffer (contains processing outputs) TemplateBuffer<float> _filterOutput; // primary buffer (contains processing outputs)
std::valarray<double> _localBuffer; // local secondary buffer std::valarray<float> _localBuffer; // local secondary buffer
///////////////////////// /////////////////////////
// PARAMETERS // PARAMETERS
unsigned int _halfNBrows; unsigned int _halfNBrows;
unsigned int _halfNBcolumns; unsigned int _halfNBcolumns;
// parameters buffers // parameters buffers
std::valarray <double>_filteringCoeficientsTable; std::valarray <float>_filteringCoeficientsTable;
std::valarray <double>_progressiveSpatialConstant;// pointer to a local table containing local spatial constant (allocated with the object) std::valarray <float>_progressiveSpatialConstant;// pointer to a local table containing local spatial constant (allocated with the object)
std::valarray <double>_progressiveGain;// pointer to a local table containing local spatial constant (allocated with the object) std::valarray <float>_progressiveGain;// pointer to a local table containing local spatial constant (allocated with the object)
// local adaptation filtering parameters // local adaptation filtering parameters
double _v0; //value used for local luminance adaptation function float _v0; //value used for local luminance adaptation function
double _maxInputValue; float _maxInputValue;
double _meanInputValue; float _meanInputValue;
double _localLuminanceFactor; float _localLuminanceFactor;
double _localLuminanceAddon; float _localLuminanceAddon;
// protected data related to standard low pass filters parameters // protected data related to standard low pass filters parameters
double _a; float _a;
double _tau; float _tau;
double _gain; float _gain;
///////////////////////// /////////////////////////
// FILTERS METHODS // FILTERS METHODS
// Basic low pass spation temporal low pass filter used by each retina filters // Basic low pass spation temporal low pass filter used by each retina filters
void _spatiotemporalLPfilter(const double *inputFrame, double *LPfilterOutput, const unsigned int coefTableOffset=0); void _spatiotemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int coefTableOffset=0);
const double _squaringSpatiotemporalLPfilter(const double *inputFrame, double *outputFrame, const unsigned int filterIndex=0); const float _squaringSpatiotemporalLPfilter(const float *inputFrame, float *outputFrame, const unsigned int filterIndex=0);
// LP filter with an irregular spatial filtering // LP filter with an irregular spatial filtering
// -> rewrites the input buffer // -> rewrites the input buffer
void _spatiotemporalLPfilter_Irregular(double *inputOutputFrame, const unsigned int filterIndex=0); void _spatiotemporalLPfilter_Irregular(float *inputOutputFrame, const unsigned int filterIndex=0);
// writes the output on another buffer // writes the output on another buffer
void _spatiotemporalLPfilter_Irregular(const double *inputFrame, double *outputFrame, const unsigned int filterIndex=0); void _spatiotemporalLPfilter_Irregular(const float *inputFrame, float *outputFrame, const unsigned int filterIndex=0);
// LP filter that squares the input and computes the output ONLY on the areas where the integrationAreas map are TRUE // LP filter that squares the input and computes the output ONLY on the areas where the integrationAreas map are TRUE
void _localSquaringSpatioTemporalLPfilter(const double *inputFrame, double *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex=0); void _localSquaringSpatioTemporalLPfilter(const float *inputFrame, float *LPfilterOutput, const unsigned int *integrationAreas, const unsigned int filterIndex=0);
// local luminance adaptation of the input in regard of localLuminance buffer // local luminance adaptation of the input in regard of localLuminance buffer
void _localLuminanceAdaptation(const double *inputFrame, const double *localLuminance, double *outputFrame); void _localLuminanceAdaptation(const float *inputFrame, const float *localLuminance, float *outputFrame);
// local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output // local luminance adaptation of the input in regard of localLuminance buffer, the input is rewrited and becomes the output
void _localLuminanceAdaptation(double *inputOutputFrame, const double *localLuminance); void _localLuminanceAdaptation(float *inputOutputFrame, const float *localLuminance);
// local adaptation applied on a range of values which can be positive and negative // local adaptation applied on a range of values which can be positive and negative
void _localLuminanceAdaptationPosNegValues(const double *inputFrame, const double *localLuminance, double *outputFrame); void _localLuminanceAdaptationPosNegValues(const float *inputFrame, const float *localLuminance, float *outputFrame);
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// 1D directional filters used for the 2D low pass filtering // 1D directional filters used for the 2D low pass filtering
// 1D filters with image input // 1D filters with image input
void _horizontalCausalFilter_addInput(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
// 1D filters with image input that is squared in the function // 1D filters with image input that is squared in the function
void _squaringHorizontalCausalFilter(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
// vertical anticausal filter that returns the mean value of its result // vertical anticausal filter that returns the mean value of its result
const double _verticalAnticausalFilter_returnMeanValue(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); const float _verticalAnticausalFilter_returnMeanValue(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// most simple functions: only perform 1D filtering with output=input (no add on) // most simple functions: only perform 1D filtering with output=input (no add on)
void _horizontalCausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalCausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalAnticausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _verticalCausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); void _verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
void _verticalAnticausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); void _verticalAnticausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// perform 1D filtering with output with varrying spatial coefficient // perform 1D filtering with output with varrying spatial coefficient
void _horizontalCausalFilter_Irregular(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalCausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalCausalFilter_Irregular_addInput(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalCausalFilter_Irregular_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _horizontalAnticausalFilter_Irregular(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); void _horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
void _verticalCausalFilter_Irregular(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); void _verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
void _verticalAnticausalFilter_Irregular_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); void _verticalAnticausalFilter_Irregular_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
// 1D filters in which the output is multiplied by _gain // 1D filters in which the output is multiplied by _gain
void _verticalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output void _verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output
void _horizontalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output void _horizontalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // this functions affects _gain at the output
// LP filter on specific parts of the picture instead of all the image // LP filter on specific parts of the picture instead of all the image
// same functions (some of them) but take a binary flag to allow integration, false flag means, 0 at the output... // same functions (some of them) but take a binary flag to allow integration, false flag means, 0 at the output...
void _local_squaringHorizontalCausalFilter(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas); void _local_squaringHorizontalCausalFilter(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas);
void _local_horizontalAnticausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas); void _local_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const unsigned int *integrationAreas);
void _local_verticalCausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); void _local_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas);
void _local_verticalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output void _local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output
}; };

View File

@ -394,7 +394,7 @@ bool ImageLogPolProjection::_initLogPolarCortexSampling(const double reductionFa
} }
// action function // action function
std::valarray<double> &ImageLogPolProjection::runProjection(const std::valarray<double> &inputFrame, const double colorMode) std::valarray<float> &ImageLogPolProjection::runProjection(const std::valarray<float> &inputFrame, const bool colorMode)
{ {
if (_colorModeCapable&&colorMode) if (_colorModeCapable&&colorMode)
{ {

View File

@ -148,9 +148,10 @@ public:
/** /**
* main funtion of the class: run projection function * main funtion of the class: run projection function
* @param inputFrame: the input frame to be processed * @param inputFrame: the input frame to be processed
* @param colorMode: the input buffer color mode: false=gray levels, true = 3 color channels mode
* @return the output frame * @return the output frame
*/ */
std::valarray<double> &runProjection(const std::valarray<double> &inputFrame, const double colorMode=false); std::valarray<float> &runProjection(const std::valarray<float> &inputFrame, const bool colorMode=false);
/** /**
* @return the numbers of rows (height) of the images OUTPUTS of the object * @return the numbers of rows (height) of the images OUTPUTS of the object
@ -172,13 +173,13 @@ public:
/** /**
* @return the output of the filter which applies an irregular Low Pass spatial filter to the imag input (see function * @return the output of the filter which applies an irregular Low Pass spatial filter to the imag input (see function
*/ */
inline const std::valarray<double> &getIrregularLPfilteredInputFrame() const {return _irregularLPfilteredFrame;}; inline const std::valarray<float> &getIrregularLPfilteredInputFrame() const {return _irregularLPfilteredFrame;};
/** /**
* function which allows to retrieve the output frame which was updated after the "runProjection(...) function BasicRetinaFilter::runProgressiveFilter(...) * function which allows to retrieve the output frame which was updated after the "runProjection(...) function BasicRetinaFilter::runProgressiveFilter(...)
* @return the projection result * @return the projection result
*/ */
inline const std::valarray<double> &getSampledFrame() const {return _sampledFrame;}; inline const std::valarray<float> &getSampledFrame() const {return _sampledFrame;};
/** /**
* function which allows gives the tranformation table, its size is (getNBrows()*getNBcolumns()*2) * function which allows gives the tranformation table, its size is (getNBrows()*getNBcolumns()*2)
@ -213,11 +214,11 @@ private:
double _minDimension; double _minDimension;
// template buffers // template buffers
std::valarray<double>_sampledFrame; std::valarray<float>_sampledFrame;
std::valarray<double>&_tempBuffer; std::valarray<float>&_tempBuffer;
std::valarray<unsigned int>_transformTable; std::valarray<unsigned int>_transformTable;
std::valarray<double> &_irregularLPfilteredFrame; // just a reference for easier understanding std::valarray<float> &_irregularLPfilteredFrame; // just a reference for easier understanding
unsigned int _usefullpixelIndex; unsigned int _usefullpixelIndex;
// init transformation tables // init transformation tables

View File

@ -142,7 +142,7 @@ void MagnoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBc
clearAllBuffers(); clearAllBuffers();
} }
void MagnoRetinaFilter::setCoefficientsTable(const double parasolCells_beta, const double parasolCells_tau, const double parasolCells_k, const double amacrinCellsTemporalCutFrequency, const double localAdaptIntegration_tau, const double localAdaptIntegration_k ) void MagnoRetinaFilter::setCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float localAdaptIntegration_tau, const float localAdaptIntegration_k )
{ {
_temporalCoefficient=exp(-1.0/amacrinCellsTemporalCutFrequency); _temporalCoefficient=exp(-1.0/amacrinCellsTemporalCutFrequency);
// the first set of parameters is dedicated to the low pass filtering property of the ganglion cells // the first set of parameters is dedicated to the low pass filtering property of the ganglion cells
@ -151,24 +151,24 @@ void MagnoRetinaFilter::setCoefficientsTable(const double parasolCells_beta, con
BasicRetinaFilter::setLPfilterParameters(0, localAdaptIntegration_tau, localAdaptIntegration_k, 1); BasicRetinaFilter::setLPfilterParameters(0, localAdaptIntegration_tau, localAdaptIntegration_k, 1);
} }
void MagnoRetinaFilter::_amacrineCellsComputing(const double *OPL_ON, const double *OPL_OFF) void MagnoRetinaFilter::_amacrineCellsComputing(const float *OPL_ON, const float *OPL_OFF)
{ {
register const double *OPL_ON_PTR=OPL_ON; register const float *OPL_ON_PTR=OPL_ON;
register const double *OPL_OFF_PTR=OPL_OFF; register const float *OPL_OFF_PTR=OPL_OFF;
register double *previousInput_ON_PTR= &_previousInput_ON[0]; register float *previousInput_ON_PTR= &_previousInput_ON[0];
register double *previousInput_OFF_PTR= &_previousInput_OFF[0]; register float *previousInput_OFF_PTR= &_previousInput_OFF[0];
register double *amacrinCellsTempOutput_ON_PTR= &_amacrinCellsTempOutput_ON[0]; register float *amacrinCellsTempOutput_ON_PTR= &_amacrinCellsTempOutput_ON[0];
register double *amacrinCellsTempOutput_OFF_PTR= &_amacrinCellsTempOutput_OFF[0]; register float *amacrinCellsTempOutput_OFF_PTR= &_amacrinCellsTempOutput_OFF[0];
for (unsigned int IDpixel=0 ; IDpixel<this->getNBpixels(); ++IDpixel) for (unsigned int IDpixel=0 ; IDpixel<this->getNBpixels(); ++IDpixel)
{ {
/* Compute ON and OFF amacrin cells high pass temporal filter */ /* Compute ON and OFF amacrin cells high pass temporal filter */
double magnoXonPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR); float magnoXonPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR);
*(amacrinCellsTempOutput_ON_PTR++)=((double)(magnoXonPixelResult>0))*magnoXonPixelResult; *(amacrinCellsTempOutput_ON_PTR++)=((float)(magnoXonPixelResult>0))*magnoXonPixelResult;
double magnoXoffPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR); float magnoXoffPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR);
*(amacrinCellsTempOutput_OFF_PTR++)=((double)(magnoXoffPixelResult>0))*magnoXoffPixelResult; *(amacrinCellsTempOutput_OFF_PTR++)=((float)(magnoXoffPixelResult>0))*magnoXoffPixelResult;
/* prepare next loop */ /* prepare next loop */
*(previousInput_ON_PTR++)=*(OPL_ON_PTR++); *(previousInput_ON_PTR++)=*(OPL_ON_PTR++);
@ -178,7 +178,7 @@ void MagnoRetinaFilter::_amacrineCellsComputing(const double *OPL_ON, const doub
} }
// launch filter that runs all the IPL filter // launch filter that runs all the IPL filter
const std::valarray<double> &MagnoRetinaFilter::runFilter(const std::valarray<double> &OPL_ON, const std::valarray<double> &OPL_OFF) const std::valarray<float> &MagnoRetinaFilter::runFilter(const std::valarray<float> &OPL_ON, const std::valarray<float> &OPL_OFF)
{ {
// Compute the high pass temporal filter // Compute the high pass temporal filter
_amacrineCellsComputing(get_data(OPL_ON), get_data(OPL_OFF)); _amacrineCellsComputing(get_data(OPL_ON), get_data(OPL_OFF));
@ -194,9 +194,9 @@ const std::valarray<double> &MagnoRetinaFilter::runFilter(const std::valarray<do
_localLuminanceAdaptation(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0]); _localLuminanceAdaptation(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0]);
/* Compute MagnoY */ /* Compute MagnoY */
register double *magnoYOutput= &(*_magnoYOutput)[0]; register float *magnoYOutput= &(*_magnoYOutput)[0];
register double *magnoXOutputON_PTR= &_magnoXOutputON[0]; register float *magnoXOutputON_PTR= &_magnoXOutputON[0];
register double *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0]; register float *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0];
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
*(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++); *(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++);

View File

@ -83,7 +83,7 @@
* movingContoursExtractor->runfilter(FrameBuffer); * movingContoursExtractor->runfilter(FrameBuffer);
* *
* // get the output frame, check in the class description below for more outputs: * // get the output frame, check in the class description below for more outputs:
* const double *movingContours=movingContoursExtractor->getMagnoYsaturated(); * const float *movingContours=movingContoursExtractor->getMagnoYsaturated();
* *
* // at the end of the program, destroy object: * // at the end of the program, destroy object:
* delete movingContoursExtractor; * delete movingContoursExtractor;
@ -137,7 +137,7 @@ public:
* @param localAdaptIntegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation * @param localAdaptIntegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptIntegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation * @param localAdaptIntegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/ */
void setCoefficientsTable(const double parasolCells_beta, const double parasolCells_tau, const double parasolCells_k, const double amacrinCellsTemporalCutFrequency, const double localAdaptIntegration_tau, const double localAdaptIntegration_k); void setCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float localAdaptIntegration_tau, const float localAdaptIntegration_k);
/** /**
* launch filter that runs all the IPL magno filter (model of the magnocellular channel of the Inner Plexiform Layer of the retina) * launch filter that runs all the IPL magno filter (model of the magnocellular channel of the Inner Plexiform Layer of the retina)
@ -145,22 +145,22 @@ public:
* @param OPL_OFF: the output of the bipolar OFF cells of the retina (available from the ParvoRetinaFilter class (getBipolarCellsOFF() function) * @param OPL_OFF: the output of the bipolar OFF cells of the retina (available from the ParvoRetinaFilter class (getBipolarCellsOFF() function)
* @return the processed result without post-processing * @return the processed result without post-processing
*/ */
const std::valarray<double> &runFilter(const std::valarray<double> &OPL_ON, const std::valarray<double> &OPL_OFF); const std::valarray<float> &runFilter(const std::valarray<float> &OPL_ON, const std::valarray<float> &OPL_OFF);
/** /**
* @return the Magnocellular ON channel filtering output * @return the Magnocellular ON channel filtering output
*/ */
inline const std::valarray<double> &getMagnoON() const {return _magnoXOutputON;}; inline const std::valarray<float> &getMagnoON() const {return _magnoXOutputON;};
/** /**
* @return the Magnocellular OFF channel filtering output * @return the Magnocellular OFF channel filtering output
*/ */
inline const std::valarray<double> &getMagnoOFF() const {return _magnoXOutputOFF;}; inline const std::valarray<float> &getMagnoOFF() const {return _magnoXOutputOFF;};
/** /**
* @return the Magnocellular Y (sum of the ON and OFF magno channels) filtering output * @return the Magnocellular Y (sum of the ON and OFF magno channels) filtering output
*/ */
inline const std::valarray<double> &getMagnoYsaturated() const {return *_magnoYsaturated;}; inline const std::valarray<float> &getMagnoYsaturated() const {return *_magnoYsaturated;};
/** /**
* applies an image normalization which saturates the high output values by the use of an assymetric sigmoide * applies an image normalization which saturates the high output values by the use of an assymetric sigmoide
@ -170,28 +170,28 @@ public:
/** /**
* @return the horizontal cells' temporal constant * @return the horizontal cells' temporal constant
*/ */
inline const double getTemporalConstant(){return this->_filteringCoeficientsTable[2];}; inline const float getTemporalConstant(){return this->_filteringCoeficientsTable[2];};
private: private:
// related pointers to these buffers // related pointers to these buffers
std::valarray<double> _previousInput_ON; std::valarray<float> _previousInput_ON;
std::valarray<double> _previousInput_OFF; std::valarray<float> _previousInput_OFF;
std::valarray<double> _amacrinCellsTempOutput_ON; std::valarray<float> _amacrinCellsTempOutput_ON;
std::valarray<double> _amacrinCellsTempOutput_OFF; std::valarray<float> _amacrinCellsTempOutput_OFF;
std::valarray<double> _magnoXOutputON; std::valarray<float> _magnoXOutputON;
std::valarray<double> _magnoXOutputOFF; std::valarray<float> _magnoXOutputOFF;
std::valarray<double> _localProcessBufferON; std::valarray<float> _localProcessBufferON;
std::valarray<double> _localProcessBufferOFF; std::valarray<float> _localProcessBufferOFF;
// reference to parent buffers and allow better readability // reference to parent buffers and allow better readability
TemplateBuffer<double> *_magnoYOutput; TemplateBuffer<float> *_magnoYOutput;
std::valarray<double> *_magnoYsaturated; std::valarray<float> *_magnoYsaturated;
// varialbles // varialbles
double _temporalCoefficient; float _temporalCoefficient;
// amacrine cells filter : high pass temporal filter // amacrine cells filter : high pass temporal filter
void _amacrineCellsComputing(const double *ONinput, const double *OFFinput); void _amacrineCellsComputing(const float *ONinput, const float *OFFinput);
}; };

View File

@ -155,7 +155,7 @@ void ParvoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBc
} }
// change the parameters of the filter // change the parameters of the filter
void ParvoRetinaFilter::setOPLandParvoFiltersParameters(const double beta1, const double tau1, const double k1, const double beta2, const double tau2, const double k2) void ParvoRetinaFilter::setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2)
{ {
// init photoreceptors low pass filter // init photoreceptors low pass filter
setLPfilterParameters(beta1, tau1, k1); setLPfilterParameters(beta1, tau1, k1);
@ -170,7 +170,7 @@ void ParvoRetinaFilter::setOPLandParvoFiltersParameters(const double beta1, cons
// run filter for a new frame input // run filter for a new frame input
// output return is (*_parvocellularOutputONminusOFF) // output return is (*_parvocellularOutputONminusOFF)
const std::valarray<double> &ParvoRetinaFilter::runFilter(const std::valarray<double> &inputFrame, const bool useParvoOutput) const std::valarray<float> &ParvoRetinaFilter::runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput)
{ {
_spatiotemporalLPfilter(get_data(inputFrame), &_photoreceptorsOutput[0]); _spatiotemporalLPfilter(get_data(inputFrame), &_photoreceptorsOutput[0]);
_spatiotemporalLPfilter(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], 1); _spatiotemporalLPfilter(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], 1);
@ -189,9 +189,9 @@ const std::valarray<double> &ParvoRetinaFilter::runFilter(const std::valarray<do
// //
//// loop that makes the difference between photoreceptor cells output and horizontal cells //// loop that makes the difference between photoreceptor cells output and horizontal cells
//// positive part goes on the ON way, negative pat goes on the OFF way //// positive part goes on the ON way, negative pat goes on the OFF way
register double *parvocellularOutputONminusOFF_PTR=&(*_parvocellularOutputONminusOFF)[0]; register float *parvocellularOutputONminusOFF_PTR=&(*_parvocellularOutputONminusOFF)[0];
register double *parvocellularOutputON_PTR=&_parvocellularOutputON[0]; register float *parvocellularOutputON_PTR=&_parvocellularOutputON[0];
register double *parvocellularOutputOFF_PTR=&_parvocellularOutputOFF[0]; register float *parvocellularOutputOFF_PTR=&_parvocellularOutputOFF[0];
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
*(parvocellularOutputONminusOFF_PTR++)= (*(parvocellularOutputON_PTR++)-*(parvocellularOutputOFF_PTR++)); *(parvocellularOutputONminusOFF_PTR++)= (*(parvocellularOutputON_PTR++)-*(parvocellularOutputOFF_PTR++));
@ -203,20 +203,20 @@ void ParvoRetinaFilter::_OPL_OnOffWaysComputing()
{ {
// loop that makes the difference between photoreceptor cells output and horizontal cells // loop that makes the difference between photoreceptor cells output and horizontal cells
// positive part goes on the ON way, negative pat goes on the OFF way // positive part goes on the ON way, negative pat goes on the OFF way
register double *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0]; register float *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0];
register double *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0]; register float *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0];
register double *bipolarCellsON_PTR = &_bipolarCellsOutputON[0]; register float *bipolarCellsON_PTR = &_bipolarCellsOutputON[0];
register double *bipolarCellsOFF_PTR = &_bipolarCellsOutputOFF[0]; register float *bipolarCellsOFF_PTR = &_bipolarCellsOutputOFF[0];
register double *parvocellularOutputON_PTR= &_parvocellularOutputON[0]; register float *parvocellularOutputON_PTR= &_parvocellularOutputON[0];
register double *parvocellularOutputOFF_PTR= &_parvocellularOutputOFF[0]; register float *parvocellularOutputOFF_PTR= &_parvocellularOutputOFF[0];
// compute bipolar cells response equal to photoreceptors minus horizontal cells response // compute bipolar cells response equal to photoreceptors minus horizontal cells response
// and copy the result on parvo cellular outputs... keeping time before their local contrast adaptation for final result // and copy the result on parvo cellular outputs... keeping time before their local contrast adaptation for final result
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel) for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
{ {
double pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++); float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over // test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
double isPositive=(double) (pixelDifference>0); float isPositive=(float) (pixelDifference>0);
// ON and OFF channels writing step // ON and OFF channels writing step
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference; *(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;

View File

@ -85,7 +85,7 @@
* contoursExtractor->runfilter(FrameBuffer); * contoursExtractor->runfilter(FrameBuffer);
* *
* // get the output frame, check in the class description below for more outputs: * // get the output frame, check in the class description below for more outputs:
* const double *contours=contoursExtractor->getParvoONminusOFF(); * const float *contours=contoursExtractor->getParvoONminusOFF();
* *
* // at the end of the program, destroy object: * // at the end of the program, destroy object:
* delete contoursExtractor; * delete contoursExtractor;
@ -141,14 +141,14 @@ public:
* @param tau2: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors * @param tau2: the time constant of the first order low pass filter of the horizontal cells, use it to cut low temporal frequencies (local luminance variations), unit is frames, typical value is 1 frame, as the photoreceptors
* @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model) * @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
*/ */
void setOPLandParvoFiltersParameters(const double beta1, const double tau1, const double k1, const double beta2, const double tau2, const double k2); void setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2);
/** /**
* setup more precisely the low pass filter used for the ganglion cells low pass filtering (used for local luminance adaptation) * setup more precisely the low pass filter used for the ganglion cells low pass filtering (used for local luminance adaptation)
* @param tau: time constant of the filter (unit is frame for video processing) * @param tau: time constant of the filter (unit is frame for video processing)
* @param k: spatial constant of the filter (unit is pixels) * @param k: spatial constant of the filter (unit is pixels)
*/ */
void setGanglionCellsLocalAdaptationLPfilterParameters(const double tau, const double k){BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);}; // change the parameters of the filter void setGanglionCellsLocalAdaptationLPfilterParameters(const float tau, const float k){BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);}; // change the parameters of the filter
/** /**
@ -160,59 +160,59 @@ public:
* also, bipolar cells output are accessible (difference between photoreceptors and horizontal cells, ON output has positive values, OFF ouput has negative values), use the following access methods: getBipolarCellsON() and getBipolarCellsOFF()if useParvoOutput is true, * also, bipolar cells output are accessible (difference between photoreceptors and horizontal cells, ON output has positive values, OFF ouput has negative values), use the following access methods: getBipolarCellsON() and getBipolarCellsOFF()if useParvoOutput is true,
* if useParvoOutput is true, the complete Parvocellular channel is computed, more outputs are updated and can be accessed threw: getParvoON(), getParvoOFF() and their difference with getOutput() * if useParvoOutput is true, the complete Parvocellular channel is computed, more outputs are updated and can be accessed threw: getParvoON(), getParvoOFF() and their difference with getOutput()
*/ */
const std::valarray<double> &runFilter(const std::valarray<double> &inputFrame, const bool useParvoOutput=true); // output return is _parvocellularOutputONminusOFF const std::valarray<float> &runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput=true); // output return is _parvocellularOutputONminusOFF
/** /**
* @return the output of the photoreceptors filtering step (high cut frequency spatio-temporal low pass filter) * @return the output of the photoreceptors filtering step (high cut frequency spatio-temporal low pass filter)
*/ */
inline const std::valarray<double> &getPhotoreceptorsLPfilteringOutput() const {return _photoreceptorsOutput;}; inline const std::valarray<float> &getPhotoreceptorsLPfilteringOutput() const {return _photoreceptorsOutput;};
/** /**
* @return the output of the photoreceptors filtering step (low cut frequency spatio-temporal low pass filter) * @return the output of the photoreceptors filtering step (low cut frequency spatio-temporal low pass filter)
*/ */
inline const std::valarray<double> &getHorizontalCellsOutput() const { return _horizontalCellsOutput;}; inline const std::valarray<float> &getHorizontalCellsOutput() const { return _horizontalCellsOutput;};
/** /**
* @return the output Parvocellular ON channel of the retina model * @return the output Parvocellular ON channel of the retina model
*/ */
inline const std::valarray<double> &getParvoON() const {return _parvocellularOutputON;}; inline const std::valarray<float> &getParvoON() const {return _parvocellularOutputON;};
/** /**
* @return the output Parvocellular OFF channel of the retina model * @return the output Parvocellular OFF channel of the retina model
*/ */
inline const std::valarray<double> &getParvoOFF() const {return _parvocellularOutputOFF;}; inline const std::valarray<float> &getParvoOFF() const {return _parvocellularOutputOFF;};
/** /**
* @return the output of the Bipolar cells of the ON channel of the retina model same as function getParvoON() but without luminance local adaptation * @return the output of the Bipolar cells of the ON channel of the retina model same as function getParvoON() but without luminance local adaptation
*/ */
inline const std::valarray<double> &getBipolarCellsON() const {return _bipolarCellsOutputON;}; inline const std::valarray<float> &getBipolarCellsON() const {return _bipolarCellsOutputON;};
/** /**
* @return the output of the Bipolar cells of the OFF channel of the retina model same as function getParvoON() but without luminance local adaptation * @return the output of the Bipolar cells of the OFF channel of the retina model same as function getParvoON() but without luminance local adaptation
*/ */
inline const std::valarray<double> &getBipolarCellsOFF() const {return _bipolarCellsOutputOFF;}; inline const std::valarray<float> &getBipolarCellsOFF() const {return _bipolarCellsOutputOFF;};
/** /**
* @return the photoreceptors's temporal constant * @return the photoreceptors's temporal constant
*/ */
inline const double getPhotoreceptorsTemporalConstant(){return this->_filteringCoeficientsTable[2];}; inline const float getPhotoreceptorsTemporalConstant(){return this->_filteringCoeficientsTable[2];};
/** /**
* @return the horizontal cells' temporal constant * @return the horizontal cells' temporal constant
*/ */
inline const double getHcellsTemporalConstant(){return this->_filteringCoeficientsTable[5];}; inline const float getHcellsTemporalConstant(){return this->_filteringCoeficientsTable[5];};
private: private:
// template buffers // template buffers
std::valarray <double>_photoreceptorsOutput; std::valarray <float>_photoreceptorsOutput;
std::valarray <double>_horizontalCellsOutput; std::valarray <float>_horizontalCellsOutput;
std::valarray <double>_parvocellularOutputON; std::valarray <float>_parvocellularOutputON;
std::valarray <double>_parvocellularOutputOFF; std::valarray <float>_parvocellularOutputOFF;
std::valarray <double>_bipolarCellsOutputON; std::valarray <float>_bipolarCellsOutputON;
std::valarray <double>_bipolarCellsOutputOFF; std::valarray <float>_bipolarCellsOutputOFF;
std::valarray <double>_localAdaptationOFF; std::valarray <float>_localAdaptationOFF;
std::valarray <double> *_localAdaptationON; std::valarray <float> *_localAdaptationON;
TemplateBuffer<double> *_parvocellularOutputONminusOFF; TemplateBuffer<float> *_parvocellularOutputONminusOFF;
// private functions // private functions
void _OPL_OnOffWaysComputing(); void _OPL_OnOffWaysComputing();

View File

@ -92,7 +92,7 @@ Retina::~Retina()
delete _retinaFilter; delete _retinaFilter;
} }
void Retina::setColorSaturation(const bool saturateColors, const double colorSaturationValue) void Retina::setColorSaturation(const bool saturateColors, const float colorSaturationValue)
{ {
_retinaFilter->setColorSaturation(saturateColors, colorSaturationValue); _retinaFilter->setColorSaturation(saturateColors, colorSaturationValue);
} }
@ -123,7 +123,7 @@ void Retina::setup(std::string retinaParameterFile, const bool applyDefaultSetup
// preparing parameter setup // preparing parameter setup
bool colorMode, normaliseOutput; bool colorMode, normaliseOutput;
double photoreceptorsLocalAdaptationSensitivity, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, hcellsTemporalConstant, hcellsSpatialConstant, ganglionCellsSensitivity; float photoreceptorsLocalAdaptationSensitivity, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, hcellsTemporalConstant, hcellsSpatialConstant, ganglionCellsSensitivity;
// OPL and Parvo init first // OPL and Parvo init first
cv::FileNode rootFn = fs.root(), currFn=rootFn["OPLandIPLparvo"]; cv::FileNode rootFn = fs.root(), currFn=rootFn["OPLandIPLparvo"];
currFn["colorMode"]>>colorMode; currFn["colorMode"]>>colorMode;
@ -140,7 +140,7 @@ void Retina::setup(std::string retinaParameterFile, const bool applyDefaultSetup
// init retina IPL magno setup // init retina IPL magno setup
currFn=rootFn["IPLmagno"]; currFn=rootFn["IPLmagno"];
currFn["normaliseOutput"]>>normaliseOutput; currFn["normaliseOutput"]>>normaliseOutput;
double parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k; float parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k;
currFn["parasolCells_beta"]>>parasolCells_beta; currFn["parasolCells_beta"]>>parasolCells_beta;
currFn["parasolCells_tau"]>>parasolCells_tau; currFn["parasolCells_tau"]>>parasolCells_tau;
currFn["parasolCells_k"]>>parasolCells_k; currFn["parasolCells_k"]>>parasolCells_k;
@ -221,7 +221,7 @@ const std::string Retina::printSetup()
return outmessage.str(); return outmessage.str();
} }
void Retina::setupOPLandIPLParvoChannel(const bool colorMode, const bool normaliseOutput, const double photoreceptorsLocalAdaptationSensitivity, const double photoreceptorsTemporalConstant, const double photoreceptorsSpatialConstant, const double horizontalCellsGain, const double HcellsTemporalConstant, const double HcellsSpatialConstant, const double ganglionCellsSensitivity) void Retina::setupOPLandIPLParvoChannel(const bool colorMode, const bool normaliseOutput, const float photoreceptorsLocalAdaptationSensitivity, const float photoreceptorsTemporalConstant, const float photoreceptorsSpatialConstant, const float horizontalCellsGain, const float HcellsTemporalConstant, const float HcellsSpatialConstant, const float ganglionCellsSensitivity)
{ {
// parameters setup (default setup) // parameters setup (default setup)
_retinaFilter->setColorMode(colorMode); _retinaFilter->setColorMode(colorMode);
@ -246,7 +246,7 @@ void Retina::setupOPLandIPLParvoChannel(const bool colorMode, const bool normali
_parametersSaveFile << "}"; _parametersSaveFile << "}";
} }
void Retina::setupIPLMagnoChannel(const bool normaliseOutput, const double parasolCells_beta, const double parasolCells_tau, const double parasolCells_k, const double amacrinCellsTemporalCutFrequency, const double V0CompressionParameter, const double localAdaptintegration_tau, const double localAdaptintegration_k) void Retina::setupIPLMagnoChannel(const bool normaliseOutput, const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k)
{ {
_retinaFilter->setMagnoCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k); _retinaFilter->setMagnoCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k);
@ -270,7 +270,7 @@ void Retina::setupIPLMagnoChannel(const bool normaliseOutput, const double paras
void Retina::run(const cv::Mat &inputMatToConvert) void Retina::run(const cv::Mat &inputMatToConvert)
{ {
// first convert input image to the compatible format : std::valarray<double> // first convert input image to the compatible format : std::valarray<float>
const bool colorMode = _convertCvMat2ValarrayBuffer(inputMatToConvert, _inputBuffer); const bool colorMode = _convertCvMat2ValarrayBuffer(inputMatToConvert, _inputBuffer);
// process the retina // process the retina
if (!_retinaFilter->runFilter(_inputBuffer, colorMode, false, colorMode, false)) if (!_retinaFilter->runFilter(_inputBuffer, colorMode, false, colorMode, false))
@ -338,10 +338,10 @@ void Retina::_init(const std::string parametersSaveFile, const cv::Size inputSiz
std::cout<<printSetup()<<std::endl; std::cout<<printSetup()<<std::endl;
} }
void Retina::_convertValarrayBuffer2cvMat(const std::valarray<double> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, cv::Mat &outBuffer) void Retina::_convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, cv::Mat &outBuffer)
{ {
// fill output buffer with the valarray buffer // fill output buffer with the valarray buffer
const double *valarrayPTR=get_data(grayMatrixToConvert); const float *valarrayPTR=get_data(grayMatrixToConvert);
if (!colorMode) if (!colorMode)
{ {
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U); outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U);
@ -373,8 +373,7 @@ void Retina::_convertValarrayBuffer2cvMat(const std::valarray<double> &grayMatri
} }
} }
const bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert, std::valarray<float> &outputValarrayMatrix)
const bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert, std::valarray<double> &outputValarrayMatrix)
{ {
// first check input consistency // first check input consistency
if (inputMatToConvert.empty()) if (inputMatToConvert.empty())
@ -383,9 +382,8 @@ const bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert,
// retreive color mode from image input // retreive color mode from image input
bool colorMode = inputMatToConvert.channels() >=3; bool colorMode = inputMatToConvert.channels() >=3;
// convert to double AND fill the valarray buffer // convert to float AND fill the valarray buffer
const int dsttype = CV_64F; // output buffer is double format const int dsttype = CV_32F; // output buffer is float format
if (colorMode) if (colorMode)
{ {
// create a cv::Mat table (for RGB planes) // create a cv::Mat table (for RGB planes)
@ -396,12 +394,12 @@ const bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert,
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]) cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
}; };
// split color cv::Mat in 3 planes... it fills valarray directely // split color cv::Mat in 3 planes... it fills valarray directely
cv::split(Mat_<double>(inputMatToConvert), planes); cv::split(cv::Mat(inputMatToConvert), planes);
}else }else
{ {
// create a cv::Mat header for the valarray // create a cv::Mat header for the valarray
cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]); cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]);
inputMatToConvert.convertTo(dst, dsttype); inputMatToConvert.convertTo(dst, dsttype);
} }
return colorMode; return colorMode;
@ -410,3 +408,4 @@ const bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert,
void Retina::clearBuffers() {_retinaFilter->clearAllBuffers();} void Retina::clearBuffers() {_retinaFilter->clearAllBuffers();}
} // end of namespace cv } // end of namespace cv

View File

@ -75,9 +75,9 @@ namespace cv
{ {
// init static values // init static values
static double _LMStoACr1Cr2[]={1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -0.5, -0.5, 1.0}; static float _LMStoACr1Cr2[]={1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -0.5, -0.5, 1.0};
//static double _ACr1Cr2toLMS[]={0.5, 0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.0, 1.0}; //static double _ACr1Cr2toLMS[]={0.5, 0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.0, 1.0};
static double _LMStoLab[]={0.5774, 0.5774, 0.5774, 0.4082, 0.4082, -0.8165, 0.7071, -0.7071, 0.0}; static float _LMStoLab[]={0.5774, 0.5774, 0.5774, 0.4082, 0.4082, -0.8165, 0.7071, -0.7071, 0.0};
// constructor/desctructor // constructor/desctructor
RetinaColor::RetinaColor(const unsigned int NBrows, const unsigned int NBcolumns, const RETINA_COLORSAMPLINGMETHOD samplingMethod) RetinaColor::RetinaColor(const unsigned int NBrows, const unsigned int NBcolumns, const RETINA_COLORSAMPLINGMETHOD samplingMethod)
@ -196,9 +196,9 @@ void RetinaColor::_initColorSampling()
} }
_colorSampling[index] = colorIndex*this->getNBpixels()+index; _colorSampling[index] = colorIndex*this->getNBpixels()+index;
} }
_pR/=(double)this->getNBpixels(); _pR/=(float)this->getNBpixels();
_pG/=(double)this->getNBpixels(); _pG/=(float)this->getNBpixels();
_pB/=(double)this->getNBpixels(); _pB/=(float)this->getNBpixels();
std::cout<<"Color channels proportions: pR, pG, pB= "<<_pR<<", "<<_pG<<", "<<_pB<<", "<<std::endl; std::cout<<"Color channels proportions: pR, pG, pB= "<<_pR<<", "<<_pG<<", "<<_pB<<", "<<std::endl;
break; break;
case RETINA_COLOR_DIAGONAL: case RETINA_COLOR_DIAGONAL:
@ -238,7 +238,7 @@ void RetinaColor::_initColorSampling()
_spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getNBpixels(), &_colorLocalDensity[0]+_filterOutput.getNBpixels()); _spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getNBpixels(), &_colorLocalDensity[0]+_filterOutput.getNBpixels());
_spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getDoubleNBpixels(), &_colorLocalDensity[0]+_filterOutput.getDoubleNBpixels()); _spatiotemporalLPfilter(&_RGBmosaic[0]+_filterOutput.getDoubleNBpixels(), &_colorLocalDensity[0]+_filterOutput.getDoubleNBpixels());
unsigned int maxNBpixels=3*_filterOutput.getNBpixels(); unsigned int maxNBpixels=3*_filterOutput.getNBpixels();
register double *colorLocalDensityPTR=&_colorLocalDensity[0]; register float *colorLocalDensityPTR=&_colorLocalDensity[0];
for (unsigned int i=0;i<maxNBpixels;++i, ++colorLocalDensityPTR) for (unsigned int i=0;i<maxNBpixels;++i, ++colorLocalDensityPTR)
*colorLocalDensityPTR=1.0/ *colorLocalDensityPTR; *colorLocalDensityPTR=1.0/ *colorLocalDensityPTR;
@ -251,14 +251,14 @@ void RetinaColor::_initColorSampling()
// public functions // public functions
void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexedColorFrame, const bool adaptiveFiltering, const double maxInputValue) void RetinaColor::runColorDemultiplexing(const std::valarray<float> &multiplexedColorFrame, const bool adaptiveFiltering, const float maxInputValue)
{ {
// demultiplex the grey frame to RGB frame // demultiplex the grey frame to RGB frame
// -> first set demultiplexed frame to 0 // -> first set demultiplexed frame to 0
_demultiplexedTempBuffer=0; _demultiplexedTempBuffer=0;
// -> demultiplex process // -> demultiplex process
register unsigned int *colorSamplingPRT=&_colorSampling[0]; register unsigned int *colorSamplingPRT=&_colorSampling[0];
register const double *multiplexedColorFramePTR=get_data(multiplexedColorFrame); register const float *multiplexedColorFramePTR=get_data(multiplexedColorFrame);
for (unsigned int indexa=0; indexa<_filterOutput.getNBpixels() ; ++indexa) for (unsigned int indexa=0; indexa<_filterOutput.getNBpixels() ; ++indexa)
_demultiplexedTempBuffer[*(colorSamplingPRT++)]=*(multiplexedColorFramePTR++); _demultiplexedTempBuffer[*(colorSamplingPRT++)]=*(multiplexedColorFramePTR++);
@ -279,18 +279,18 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
}*/ }*/
// normalize by the photoreceptors local density and retrieve the local luminance // normalize by the photoreceptors local density and retrieve the local luminance
register double *chrominancePTR= &_chrominance[0]; register float *chrominancePTR= &_chrominance[0];
register double *colorLocalDensityPTR= &_colorLocalDensity[0]; register float *colorLocalDensityPTR= &_colorLocalDensity[0];
register double *luminance= &(*_luminance)[0]; register float *luminance= &(*_luminance)[0];
if (!adaptiveFiltering)// compute the gradient on the luminance if (!adaptiveFiltering)// compute the gradient on the luminance
{ {
if (_samplingMethod==RETINA_COLOR_RANDOM) if (_samplingMethod==RETINA_COLOR_RANDOM)
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance) for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance)
{ {
// normalize by photoreceptors density // normalize by photoreceptors density
double Cr=*(chrominancePTR)*_colorLocalDensity[indexc]; float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
double Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()]; float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
double Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()]; float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG; *luminance=(Cr+Cg+Cb)*_pG;
*(chrominancePTR)=Cr-*luminance; *(chrominancePTR)=Cr-*luminance;
*(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance; *(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance;
@ -299,9 +299,9 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
else else
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance) for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance)
{ {
double Cr=*(chrominancePTR); float Cr=*(chrominancePTR);
double Cg=*(chrominancePTR+_filterOutput.getNBpixels()); float Cg=*(chrominancePTR+_filterOutput.getNBpixels());
double Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels()); float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels());
*luminance=_pR*Cr+_pG*Cg+_pB*Cb; *luminance=_pR*Cr+_pG*Cg+_pB*Cb;
*(chrominancePTR)=Cr-*luminance; *(chrominancePTR)=Cr-*luminance;
*(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance; *(chrominancePTR+_filterOutput.getNBpixels())=Cg-*luminance;
@ -312,9 +312,9 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
// -> to do so, compute: multiplexedColorFrame - remultiplexed chrominances // -> to do so, compute: multiplexedColorFrame - remultiplexed chrominances
runColorMultiplexing(_chrominance, _tempMultiplexedFrame); runColorMultiplexing(_chrominance, _tempMultiplexedFrame);
//lum = 1/3((f*(ImR))/(f*mR) + (f*(ImG))/(f*mG) + (f*(ImB))/(f*mB)); //lum = 1/3((f*(ImR))/(f*mR) + (f*(ImG))/(f*mG) + (f*(ImB))/(f*mB));
double *luminancePTR= &(*_luminance)[0]; float *luminancePTR= &(*_luminance)[0];
chrominancePTR= &_chrominance[0]; chrominancePTR= &_chrominance[0];
double *demultiplexedColorFramePTR= &_demultiplexedColorFrame[0]; float *demultiplexedColorFramePTR= &_demultiplexedColorFrame[0];
for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels() ; ++indexp, ++luminancePTR, ++chrominancePTR, ++demultiplexedColorFramePTR) for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels() ; ++indexp, ++luminancePTR, ++chrominancePTR, ++demultiplexedColorFramePTR)
{ {
*luminancePTR=(multiplexedColorFrame[indexp]-_tempMultiplexedFrame[indexp]); *luminancePTR=(multiplexedColorFrame[indexp]-_tempMultiplexedFrame[indexp]);
@ -325,13 +325,13 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
}else }else
{ {
register const double *multiplexedColorFramePTR= get_data(multiplexedColorFrame); register const float *multiplexedColorFramePTR= get_data(multiplexedColorFrame);
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR) for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR)
{ {
// normalize by photoreceptors density // normalize by photoreceptors density
double Cr=*(chrominancePTR)*_colorLocalDensity[indexc]; float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
double Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()]; float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
double Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()]; float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG; *luminance=(Cr+Cg+Cb)*_pG;
_demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR - *luminance; _demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR - *luminance;
@ -355,7 +355,7 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
// compute and substract the residual luminance // compute and substract the residual luminance
for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index) for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index)
{ {
double residu = _pR*_demultiplexedColorFrame[index] + _pG*_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] + _pB*_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()]; float residu = _pR*_demultiplexedColorFrame[index] + _pG*_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] + _pB*_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()];
_demultiplexedColorFrame[index] = _demultiplexedColorFrame[index] - residu; _demultiplexedColorFrame[index] = _demultiplexedColorFrame[index] - residu;
_demultiplexedColorFrame[index+_filterOutput.getNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getNBpixels()] - residu; _demultiplexedColorFrame[index+_filterOutput.getNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getNBpixels()] - residu;
_demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] - residu; _demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] = _demultiplexedColorFrame[index+_filterOutput.getDoubleNBpixels()] - residu;
@ -389,50 +389,50 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<double> &multiplexe
clipRGBOutput_0_maxInputValue(NULL, maxInputValue); clipRGBOutput_0_maxInputValue(NULL, maxInputValue);
/* transfert image gradient in order to check validity /* transfert image gradient in order to check validity
memcpy((*_luminance), _imageGradient, sizeof(double)*_filterOutput.getNBpixels()); memcpy((*_luminance), _imageGradient, sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame, _imageGradient+_filterOutput.getNBpixels(), sizeof(double)*_filterOutput.getNBpixels()); memcpy(_demultiplexedColorFrame, _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(double)*_filterOutput.getNBpixels()); memcpy(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
memcpy(_demultiplexedColorFrame+2*_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(double)*_filterOutput.getNBpixels()); memcpy(_demultiplexedColorFrame+2*_filterOutput.getNBpixels(), _imageGradient+_filterOutput.getNBpixels(), sizeof(float)*_filterOutput.getNBpixels());
*/ */
if (_saturateColors) if (_saturateColors)
{ {
TemplateBuffer<double>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0], &_demultiplexedColorFrame[0], _filterOutput.getNBpixels()); TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0], &_demultiplexedColorFrame[0], _filterOutput.getNBpixels());
TemplateBuffer<double>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), _filterOutput.getNBpixels()); TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels(), _filterOutput.getNBpixels());
TemplateBuffer<double>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, _filterOutput.getNBpixels()); TemplateBuffer<float>::normalizeGrayOutputCentredSigmoide(128, _colorSaturationValue, maxInputValue, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, &_demultiplexedColorFrame[0]+_filterOutput.getNBpixels()*2, _filterOutput.getNBpixels());
} }
} }
// color multiplexing: input frame size=_NBrows*_filterOutput.getNBcolumns()*3, multiplexedFrame output size=_NBrows*_filterOutput.getNBcolumns() // color multiplexing: input frame size=_NBrows*_filterOutput.getNBcolumns()*3, multiplexedFrame output size=_NBrows*_filterOutput.getNBcolumns()
void RetinaColor::runColorMultiplexing(const std::valarray<double> &demultiplexedInputFrame, std::valarray<double> &multiplexedFrame) void RetinaColor::runColorMultiplexing(const std::valarray<float> &demultiplexedInputFrame, std::valarray<float> &multiplexedFrame)
{ {
// multiply each color layer by its bayer mask // multiply each color layer by its bayer mask
register unsigned int *colorSamplingPTR= &_colorSampling[0]; register unsigned int *colorSamplingPTR= &_colorSampling[0];
register double *multiplexedFramePTR= &multiplexedFrame[0]; register float *multiplexedFramePTR= &multiplexedFrame[0];
for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels(); ++indexp) for (unsigned int indexp=0; indexp<_filterOutput.getNBpixels(); ++indexp)
*(multiplexedFramePTR++)=demultiplexedInputFrame[*(colorSamplingPTR++)]; *(multiplexedFramePTR++)=demultiplexedInputFrame[*(colorSamplingPTR++)];
} }
void RetinaColor::normalizeRGBOutput_0_maxOutputValue(const double maxOutputValue) void RetinaColor::normalizeRGBOutput_0_maxOutputValue(const float maxOutputValue)
{ {
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance); //normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance);
TemplateBuffer<double>::normalizeGrayOutput_0_maxOutputValue(&_demultiplexedColorFrame[0], 3*_filterOutput.getNBpixels(), maxOutputValue); TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&_demultiplexedColorFrame[0], 3*_filterOutput.getNBpixels(), maxOutputValue);
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+_filterOutput.getNBpixels()); //normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+_filterOutput.getNBpixels());
//normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _filterOutput.getNBpixels(), maxOutputValue); //normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getNBpixels(), _filterOutput.getNBpixels(), maxOutputValue);
//normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+2*_filterOutput.getNBpixels()); //normalizeGrayOutputCentredSigmoide(0.0, 2, _chrominance+2*_filterOutput.getNBpixels());
//normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getDoubleNBpixels(), _filterOutput.getNBpixels(), maxOutputValue); //normalizeGrayOutput_0_maxOutputValue(_demultiplexedColorFrame+_filterOutput.getDoubleNBpixels(), _filterOutput.getNBpixels(), maxOutputValue);
TemplateBuffer<double>::normalizeGrayOutput_0_maxOutputValue(&(*_luminance)[0], _filterOutput.getNBpixels(), maxOutputValue); TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&(*_luminance)[0], _filterOutput.getNBpixels(), maxOutputValue);
} }
/// normalize output between 0 and maxOutputValue; /// normalize output between 0 and maxOutputValue;
void RetinaColor::clipRGBOutput_0_maxInputValue(double *inputOutputBuffer, const double maxInputValue) void RetinaColor::clipRGBOutput_0_maxInputValue(float *inputOutputBuffer, const float maxInputValue)
{ {
//std::cout<<"RetinaColor::normalizing RGB frame..."<<std::endl; //std::cout<<"RetinaColor::normalizing RGB frame..."<<std::endl;
// if outputBuffer unsassigned, the rewrite the buffer // if outputBuffer unsassigned, the rewrite the buffer
if (inputOutputBuffer==NULL) if (inputOutputBuffer==NULL)
inputOutputBuffer= &_demultiplexedColorFrame[0]; inputOutputBuffer= &_demultiplexedColorFrame[0];
register double *inputOutputBufferPTR=inputOutputBuffer; register float *inputOutputBufferPTR=inputOutputBuffer;
for (register unsigned int jf = 0; jf < _filterOutput.getNBpixels()*3; ++jf, ++inputOutputBufferPTR) for (register unsigned int jf = 0; jf < _filterOutput.getNBpixels()*3; ++jf, ++inputOutputBufferPTR)
{ {
if (*inputOutputBufferPTR>maxInputValue) if (*inputOutputBufferPTR>maxInputValue)
@ -443,7 +443,7 @@ void RetinaColor::clipRGBOutput_0_maxInputValue(double *inputOutputBuffer, const
//std::cout<<"RetinaColor::...normalizing RGB frame OK"<<std::endl; //std::cout<<"RetinaColor::...normalizing RGB frame OK"<<std::endl;
} }
void RetinaColor::_interpolateImageDemultiplexedImage(double *inputOutputBuffer) void RetinaColor::_interpolateImageDemultiplexedImage(float *inputOutputBuffer)
{ {
switch(_samplingMethod) switch(_samplingMethod)
@ -469,7 +469,7 @@ void RetinaColor::_interpolateImageDemultiplexedImage(double *inputOutputBuffer)
} }
void RetinaColor::_interpolateSingleChannelImage111(double *inputOutputBuffer) void RetinaColor::_interpolateSingleChannelImage111(float *inputOutputBuffer)
{ {
for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows(); ++indexr) for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows(); ++indexr)
{ {
@ -489,7 +489,7 @@ void RetinaColor::_interpolateSingleChannelImage111(double *inputOutputBuffer)
} }
} }
void RetinaColor::_interpolateBayerRGBchannels(double *inputOutputBuffer) void RetinaColor::_interpolateBayerRGBchannels(float *inputOutputBuffer)
{ {
for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows()-1; indexr+=2) for (unsigned int indexr=0 ; indexr<_filterOutput.getNBrows()-1; indexr+=2)
{ {
@ -520,7 +520,7 @@ void RetinaColor::_interpolateBayerRGBchannels(double *inputOutputBuffer)
} }
} }
void RetinaColor::_applyRIFfilter(const double *sourceBuffer, double *destinationBuffer) void RetinaColor::_applyRIFfilter(const float *sourceBuffer, float *destinationBuffer)
{ {
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr) for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
{ {
@ -530,13 +530,13 @@ void RetinaColor::_applyRIFfilter(const double *sourceBuffer, double *destinatio
_tempMultiplexedFrame[index]=(4.0*sourceBuffer[index]+sourceBuffer[index-1-_filterOutput.getNBcolumns()]+sourceBuffer[index-1+_filterOutput.getNBcolumns()]+sourceBuffer[index+1-_filterOutput.getNBcolumns()]+sourceBuffer[index+1+_filterOutput.getNBcolumns()])*0.125; _tempMultiplexedFrame[index]=(4.0*sourceBuffer[index]+sourceBuffer[index-1-_filterOutput.getNBcolumns()]+sourceBuffer[index-1+_filterOutput.getNBcolumns()]+sourceBuffer[index+1-_filterOutput.getNBcolumns()]+sourceBuffer[index+1+_filterOutput.getNBcolumns()])*0.125;
} }
} }
memcpy(destinationBuffer, &_tempMultiplexedFrame[0], sizeof(double)*_filterOutput.getNBpixels()); memcpy(destinationBuffer, &_tempMultiplexedFrame[0], sizeof(float)*_filterOutput.getNBpixels());
} }
void RetinaColor::_getNormalizedContoursImage(const double *inputFrame, double *outputFrame) void RetinaColor::_getNormalizedContoursImage(const float *inputFrame, float *outputFrame)
{ {
double maxValue=0; float maxValue=0;
double normalisationFactor=1.0/3.0; float normalisationFactor=1.0/3.0;
for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr) for (unsigned int indexr=1 ; indexr<_filterOutput.getNBrows()-1; ++indexr)
{ {
for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; ++indexc) for (unsigned int indexc=1 ; indexc<_filterOutput.getNBcolumns()-1; ++indexc)
@ -557,7 +557,7 @@ void RetinaColor::_getNormalizedContoursImage(const double *inputFrame, double *
// ADAPTIVE BASIC RETINA FILTER // ADAPTIVE BASIC RETINA FILTER
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// run LP filter for a new frame input and save result at a specific output adress // run LP filter for a new frame input and save result at a specific output adress
void RetinaColor::_adaptiveSpatialLPfilter(const double *inputFrame, double *outputFrame) void RetinaColor::_adaptiveSpatialLPfilter(const float *inputFrame, float *outputFrame)
{ {
/**********/ /**********/
@ -572,14 +572,14 @@ void RetinaColor::_adaptiveSpatialLPfilter(const double *inputFrame, double *out
} }
// horizontal causal filter which adds the input inside // horizontal causal filter which adds the input inside
void RetinaColor::_adaptiveHorizontalCausalFilter_addInput(const double *inputFrame, double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void RetinaColor::_adaptiveHorizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns(); register float* outputPTR=outputFrame+IDrowStart*_filterOutput.getNBcolumns();
register const double* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns(); register const float* inputPTR=inputFrame+IDrowStart*_filterOutput.getNBcolumns();
register double *imageGradientPTR= &_imageGradient[0]+IDrowStart*_filterOutput.getNBcolumns(); register float *imageGradientPTR= &_imageGradient[0]+IDrowStart*_filterOutput.getNBcolumns();
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
//std::cout<<(*imageGradientPTR)<<" "; //std::cout<<(*imageGradientPTR)<<" ";
@ -592,14 +592,14 @@ void RetinaColor::_adaptiveHorizontalCausalFilter_addInput(const double *inputFr
} }
// horizontal anticausal filter (basic way, no add on) // horizontal anticausal filter (basic way, no add on)
void RetinaColor::_adaptiveHorizontalAnticausalFilter(double *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd) void RetinaColor::_adaptiveHorizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{ {
register double* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1; register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
register double *imageGradientPTR= &_imageGradient[0]+IDrowEnd*(_filterOutput.getNBcolumns())-1; register float *imageGradientPTR= &_imageGradient[0]+IDrowEnd*(_filterOutput.getNBcolumns())-1;
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow) for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{ {
register double result=0; register float result=0;
for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index) for (unsigned int index=0; index<_filterOutput.getNBcolumns(); ++index)
{ {
result = *(outputPTR)+ (*imageGradientPTR)* result; result = *(outputPTR)+ (*imageGradientPTR)* result;
@ -610,13 +610,13 @@ void RetinaColor::_adaptiveHorizontalAnticausalFilter(double *outputFrame, unsig
} }
// vertical anticausal filter // vertical anticausal filter
void RetinaColor::_adaptiveVerticalCausalFilter(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void RetinaColor::_adaptiveVerticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputFrame+IDcolumn; register float *outputPTR=outputFrame+IDcolumn;
register double *imageGradientPTR= &_imageGradient[0]+IDcolumn; register float *imageGradientPTR= &_imageGradient[0]+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
@ -630,16 +630,16 @@ void RetinaColor::_adaptiveVerticalCausalFilter(double *outputFrame, unsigned in
} }
// vertical anticausal filter which multiplies the output by _gain // vertical anticausal filter which multiplies the output by _gain
void RetinaColor::_adaptiveVerticalAnticausalFilter_multGain(double *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd) void RetinaColor::_adaptiveVerticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{ {
double* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* outputOffset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
double* gradOffset= &_imageGradient[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns(); float* gradOffset= &_imageGradient[0]+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn) for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{ {
register double result=0; register float result=0;
register double *outputPTR=outputOffset+IDcolumn; register float *outputPTR=outputOffset+IDcolumn;
register double *imageGradientPTR=gradOffset+IDcolumn; register float *imageGradientPTR=gradOffset+IDcolumn;
for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index) for (unsigned int index=0; index<_filterOutput.getNBrows(); ++index)
{ {
result = *(outputPTR) + (*(imageGradientPTR+_filterOutput.getNBpixels())) * result; result = *(outputPTR) + (*(imageGradientPTR+_filterOutput.getNBpixels())) * result;
@ -651,7 +651,7 @@ void RetinaColor::_adaptiveVerticalAnticausalFilter_multGain(double *outputFrame
} }
/////////////////////////// ///////////////////////////
void RetinaColor::_computeGradient(const double *luminance) void RetinaColor::_computeGradient(const float *luminance)
{ {
for (unsigned int idLine=2;idLine<_filterOutput.getNBrows()-2;++idLine) for (unsigned int idLine=2;idLine<_filterOutput.getNBrows()-2;++idLine)
{ {
@ -660,17 +660,17 @@ void RetinaColor::_computeGradient(const double *luminance)
const unsigned int pixelIndex=idColumn+_filterOutput.getNBcolumns()*idLine; const unsigned int pixelIndex=idColumn+_filterOutput.getNBcolumns()*idLine;
// horizontal and vertical local gradients // horizontal and vertical local gradients
const double verticalGrad=fabs(luminance[pixelIndex+_filterOutput.getNBcolumns()]-luminance[pixelIndex-_filterOutput.getNBcolumns()]); const float verticalGrad=fabs(luminance[pixelIndex+_filterOutput.getNBcolumns()]-luminance[pixelIndex-_filterOutput.getNBcolumns()]);
const double horizontalGrad=fabs(luminance[pixelIndex+1]-luminance[pixelIndex-1]); const float horizontalGrad=fabs(luminance[pixelIndex+1]-luminance[pixelIndex-1]);
// neighborhood horizontal and vertical gradients // neighborhood horizontal and vertical gradients
const double verticalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2*_filterOutput.getNBcolumns()]); const float verticalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2*_filterOutput.getNBcolumns()]);
const double horizontalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2]); const float horizontalGrad_p=fabs(luminance[pixelIndex]-luminance[pixelIndex-2]);
const double verticalGrad_n=fabs(luminance[pixelIndex+2*_filterOutput.getNBcolumns()]-luminance[pixelIndex]); const float verticalGrad_n=fabs(luminance[pixelIndex+2*_filterOutput.getNBcolumns()]-luminance[pixelIndex]);
const double horizontalGrad_n=fabs(luminance[pixelIndex+2]-luminance[pixelIndex]); const float horizontalGrad_n=fabs(luminance[pixelIndex+2]-luminance[pixelIndex]);
const double horizontalGradient=0.5*horizontalGrad+0.25*(horizontalGrad_p+horizontalGrad_n); const float horizontalGradient=0.5*horizontalGrad+0.25*(horizontalGrad_p+horizontalGrad_n);
const double verticalGradient=0.5*verticalGrad+0.25*(verticalGrad_p+verticalGrad_n); const float verticalGradient=0.5*verticalGrad+0.25*(verticalGrad_p+verticalGrad_n);
// compare local gradient means and fill the appropriate filtering coefficient value that will be used in adaptative filters // compare local gradient means and fill the appropriate filtering coefficient value that will be used in adaptative filters
if (horizontalGradient<verticalGradient) if (horizontalGradient<verticalGradient)
@ -687,7 +687,7 @@ void RetinaColor::_computeGradient(const double *luminance)
} }
} }
const bool RetinaColor::applyKrauskopfLMS2Acr1cr2Transform(std::valarray<double> &result) const bool RetinaColor::applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result)
{ {
bool processSuccess=true; bool processSuccess=true;
// basic preliminary error check // basic preliminary error check
@ -703,7 +703,7 @@ const bool RetinaColor::applyKrauskopfLMS2Acr1cr2Transform(std::valarray<double>
return processSuccess; return processSuccess;
} }
const bool RetinaColor::applyLMS2LabTransform(std::valarray<double> &result) const bool RetinaColor::applyLMS2LabTransform(std::valarray<float> &result)
{ {
bool processSuccess=true; bool processSuccess=true;
// basic preliminary error check // basic preliminary error check
@ -720,20 +720,20 @@ const bool RetinaColor::applyLMS2LabTransform(std::valarray<double> &result)
} }
// template function able to perform a custom color space transformation // template function able to perform a custom color space transformation
void RetinaColor::_applyImageColorSpaceConversion(const std::valarray<double> &inputFrameBuffer, std::valarray<double> &outputFrameBuffer, const double *transformTable) void RetinaColor::_applyImageColorSpaceConversion(const std::valarray<float> &inputFrameBuffer, std::valarray<float> &outputFrameBuffer, const float *transformTable)
{ {
// two step methods in order to allow inputFrame and outputFrame to be the same // two step methods in order to allow inputFrame and outputFrame to be the same
unsigned int nbPixels=(unsigned int)(inputFrameBuffer.size()/3), dbpixels=(unsigned int)(2*inputFrameBuffer.size()/3); unsigned int nbPixels=(unsigned int)(inputFrameBuffer.size()/3), dbpixels=(unsigned int)(2*inputFrameBuffer.size()/3);
const double *inputFrame=get_data(inputFrameBuffer); const float *inputFrame=get_data(inputFrameBuffer);
double *outputFrame= &outputFrameBuffer[0]; float *outputFrame= &outputFrameBuffer[0];
for (unsigned int dataIndex=0; dataIndex<nbPixels;++dataIndex, ++outputFrame, ++inputFrame) for (unsigned int dataIndex=0; dataIndex<nbPixels;++dataIndex, ++outputFrame, ++inputFrame)
{ {
// first step, compute each new values // first step, compute each new values
double layer1 = *(inputFrame)**(transformTable+0) +*(inputFrame+nbPixels)**(transformTable+1) +*(inputFrame+dbpixels)**(transformTable+2); float layer1 = *(inputFrame)**(transformTable+0) +*(inputFrame+nbPixels)**(transformTable+1) +*(inputFrame+dbpixels)**(transformTable+2);
double layer2 = *(inputFrame)**(transformTable+3) +*(inputFrame+nbPixels)**(transformTable+4) +*(inputFrame+dbpixels)**(transformTable+5); float layer2 = *(inputFrame)**(transformTable+3) +*(inputFrame+nbPixels)**(transformTable+4) +*(inputFrame+dbpixels)**(transformTable+5);
double layer3 = *(inputFrame)**(transformTable+6) +*(inputFrame+nbPixels)**(transformTable+7) +*(inputFrame+dbpixels)**(transformTable+8); float layer3 = *(inputFrame)**(transformTable+6) +*(inputFrame+nbPixels)**(transformTable+7) +*(inputFrame+dbpixels)**(transformTable+8);
// second, affect the output // second, affect the output
*(outputFrame) = layer1; *(outputFrame) = layer1;
*(outputFrame+nbPixels) = layer2; *(outputFrame+nbPixels) = layer2;

View File

@ -124,14 +124,14 @@ public:
* @param inputRGBFrame: the input RGB frame to be processed * @param inputRGBFrame: the input RGB frame to be processed
* @return, nothing but the multiplexed frame is available by the use of the getMultiplexedFrame() function * @return, nothing but the multiplexed frame is available by the use of the getMultiplexedFrame() function
*/ */
inline void runColorMultiplexing(const std::valarray<double> &inputRGBFrame){runColorMultiplexing(inputRGBFrame, *_multiplexedFrame);}; inline void runColorMultiplexing(const std::valarray<float> &inputRGBFrame){runColorMultiplexing(inputRGBFrame, *_multiplexedFrame);};
/** /**
* color multiplexing function: a demultipleed RGB frame of size M*N*3 is transformed into a multiplexed M*N*1 pixels frame where each pixel is either Red, or Green or Blue if using RGB images * color multiplexing function: a demultipleed RGB frame of size M*N*3 is transformed into a multiplexed M*N*1 pixels frame where each pixel is either Red, or Green or Blue if using RGB images
* @param demultiplexedInputFrame: the demultiplexed input frame to be processed of size M*N*3 * @param demultiplexedInputFrame: the demultiplexed input frame to be processed of size M*N*3
* @param multiplexedFrame: the resulting multiplexed frame * @param multiplexedFrame: the resulting multiplexed frame
*/ */
void runColorMultiplexing(const std::valarray<double> &demultiplexedInputFrame, std::valarray<double> &multiplexedFrame); void runColorMultiplexing(const std::valarray<float> &demultiplexedInputFrame, std::valarray<float> &multiplexedFrame);
/** /**
* color demultiplexing function: a multiplexed frame of size M*N*1 pixels is transformed into a RGB demultiplexed M*N*3 pixels frame * color demultiplexing function: a multiplexed frame of size M*N*1 pixels is transformed into a RGB demultiplexed M*N*3 pixels frame
@ -140,7 +140,7 @@ public:
* @param maxInputValue: the maximum input data value (should be 255 for 8 bits images but it can change in the case of High Dynamic Range Images (HDRI) * @param maxInputValue: the maximum input data value (should be 255 for 8 bits images but it can change in the case of High Dynamic Range Images (HDRI)
* @return, nothing but the output demultiplexed frame is available by the use of the getDemultiplexedColorFrame() function, also use getLuminance() and getChrominance() in order to retreive either luminance or chrominance * @return, nothing but the output demultiplexed frame is available by the use of the getDemultiplexedColorFrame() function, also use getLuminance() and getChrominance() in order to retreive either luminance or chrominance
*/ */
void runColorDemultiplexing(const std::valarray<double> &multiplexedColorFrame, const bool adaptiveFiltering=false, const double maxInputValue=255.0); void runColorDemultiplexing(const std::valarray<float> &multiplexedColorFrame, const bool adaptiveFiltering=false, const float maxInputValue=255.0);
/** /**
* activate color saturation as the final step of the color demultiplexing process * activate color saturation as the final step of the color demultiplexing process
@ -148,7 +148,7 @@ public:
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false) * @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor * @param colorSaturationValue: the saturation factor
* */ * */
void setColorSaturation(const bool saturateColors=true, const double colorSaturationValue=4.0){_saturateColors=saturateColors; _colorSaturationValue=colorSaturationValue;}; void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0){_saturateColors=saturateColors; _colorSaturationValue=colorSaturationValue;};
/** /**
* set parameters of the low pass spatio-temporal filter used to retreive the low chrominance * set parameters of the low pass spatio-temporal filter used to retreive the low chrominance
@ -156,54 +156,54 @@ public:
* @param tau: time constant of the filter (unit is frame for video processing), typically 0 when considering static processing, 1 or more if a temporal smoothing effect is required * @param tau: time constant of the filter (unit is frame for video processing), typically 0 when considering static processing, 1 or more if a temporal smoothing effect is required
* @param k: spatial constant of the filter (unit is pixels), typical value is 2.5 * @param k: spatial constant of the filter (unit is pixels), typical value is 2.5
*/ */
void setChrominanceLPfilterParameters(const double beta, const double tau, const double k){setLPfilterParameters(beta, tau, k);}; void setChrominanceLPfilterParameters(const float beta, const float tau, const float k){setLPfilterParameters(beta, tau, k);};
/** /**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space * apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output * @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully * @return true if process ended successfully
*/ */
const bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<double> &result); const bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result);
/** /**
* apply to the retina color output the CIE Lab color transformation * apply to the retina color output the CIE Lab color transformation
* @param result: the input buffer to fill with the transformed colorspace retina output * @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully * @return true if process ended successfully
*/ */
const bool applyLMS2LabTransform(std::valarray<double> &result); const bool applyLMS2LabTransform(std::valarray<float> &result);
/** /**
* @return the multiplexed frame result (use this after function runColorMultiplexing) * @return the multiplexed frame result (use this after function runColorMultiplexing)
*/ */
inline const std::valarray<double> &getMultiplexedFrame() const {return *_multiplexedFrame;}; inline const std::valarray<float> &getMultiplexedFrame() const {return *_multiplexedFrame;};
/** /**
* @return the demultiplexed frame result (use this after function runColorDemultiplexing) * @return the demultiplexed frame result (use this after function runColorDemultiplexing)
*/ */
inline const std::valarray<double> &getDemultiplexedColorFrame() const {return _demultiplexedColorFrame;}; inline const std::valarray<float> &getDemultiplexedColorFrame() const {return _demultiplexedColorFrame;};
/** /**
* @return the luminance of the processed frame (use this after function runColorDemultiplexing) * @return the luminance of the processed frame (use this after function runColorDemultiplexing)
*/ */
inline const std::valarray<double> &getLuminance() const {return *_luminance;}; inline const std::valarray<float> &getLuminance() const {return *_luminance;};
/** /**
* @return the chrominance of the processed frame (use this after function runColorDemultiplexing) * @return the chrominance of the processed frame (use this after function runColorDemultiplexing)
*/ */
inline const std::valarray<double> &getChrominance() const {return _chrominance;}; inline const std::valarray<float> &getChrominance() const {return _chrominance;};
/** /**
* standard 0 to 255 image clipping function appled to RGB images (of size M*N*3 pixels) * standard 0 to 255 image clipping function appled to RGB images (of size M*N*3 pixels)
* @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized * @param inputOutputBuffer: the image to be normalized (rewrites the input), if no parameter, then, the built in buffer reachable by getOutput() function is normalized
* @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped * @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped
*/ */
void clipRGBOutput_0_maxInputValue(double *inputOutputBuffer, const double maxOutputValue=255.0); void clipRGBOutput_0_maxInputValue(float *inputOutputBuffer, const float maxOutputValue=255.0);
/** /**
* standard 0 to 255 image normalization function appled to RGB images (of size M*N*3 pixels) * standard 0 to 255 image normalization function appled to RGB images (of size M*N*3 pixels)
* @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped * @param maxOutputValue: the maximum value allowed at the output (values superior to it would be clipped
*/ */
void normalizeRGBOutput_0_maxOutputValue(const double maxOutputValue=255.0); void normalizeRGBOutput_0_maxOutputValue(const float maxOutputValue=255.0);
/** /**
* return the color sampling map: a Nrows*Mcolumns image in which each pixel value is the ofsset adress which gives the adress of the sampled pixel on an Nrows*Mcolumns*3 color image ordered by layers: layer1, layer2, layer3 * return the color sampling map: a Nrows*Mcolumns image in which each pixel value is the ofsset adress which gives the adress of the sampled pixel on an Nrows*Mcolumns*3 color image ordered by layers: layer1, layer2, layer3
@ -214,49 +214,49 @@ public:
* function used (to bypass processing) to manually set the color output * function used (to bypass processing) to manually set the color output
* @param demultiplexedImage: the color image (luminance+chrominance) which has to be written in the object buffer * @param demultiplexedImage: the color image (luminance+chrominance) which has to be written in the object buffer
*/ */
inline void setDemultiplexedColorFrame(const std::valarray<double> &demultiplexedImage){_demultiplexedColorFrame=demultiplexedImage;}; inline void setDemultiplexedColorFrame(const std::valarray<float> &demultiplexedImage){_demultiplexedColorFrame=demultiplexedImage;};
protected: protected:
// private functions // private functions
RETINA_COLORSAMPLINGMETHOD _samplingMethod; RETINA_COLORSAMPLINGMETHOD _samplingMethod;
bool _saturateColors; bool _saturateColors;
double _colorSaturationValue; float _colorSaturationValue;
// links to parent buffers (more convienient names // links to parent buffers (more convienient names
TemplateBuffer<double> *_luminance; TemplateBuffer<float> *_luminance;
std::valarray<double> *_multiplexedFrame; std::valarray<float> *_multiplexedFrame;
// instance buffers // instance buffers
std::valarray<unsigned int> _colorSampling; // table (size (_nbRows*_nbColumns) which specifies the color of each pixel std::valarray<unsigned int> _colorSampling; // table (size (_nbRows*_nbColumns) which specifies the color of each pixel
std::valarray<double> _RGBmosaic; std::valarray<float> _RGBmosaic;
std::valarray<double> _tempMultiplexedFrame; std::valarray<float> _tempMultiplexedFrame;
std::valarray<double> _demultiplexedTempBuffer; std::valarray<float> _demultiplexedTempBuffer;
std::valarray<double> _demultiplexedColorFrame; std::valarray<float> _demultiplexedColorFrame;
std::valarray<double> _chrominance; std::valarray<float> _chrominance;
std::valarray<double> _colorLocalDensity;// buffer which contains the local density of the R, G and B photoreceptors for a normalization use std::valarray<float> _colorLocalDensity;// buffer which contains the local density of the R, G and B photoreceptors for a normalization use
std::valarray<double> _imageGradient; std::valarray<float> _imageGradient;
// variables // variables
double _pR, _pG, _pB; // probabilities of color R, G and B float _pR, _pG, _pB; // probabilities of color R, G and B
bool _objectInit; bool _objectInit;
// protected functions // protected functions
void _initColorSampling(); void _initColorSampling();
void _interpolateImageDemultiplexedImage(double *inputOutputBuffer); void _interpolateImageDemultiplexedImage(float *inputOutputBuffer);
void _interpolateSingleChannelImage111(double *inputOutputBuffer); void _interpolateSingleChannelImage111(float *inputOutputBuffer);
void _interpolateBayerRGBchannels(double *inputOutputBuffer); void _interpolateBayerRGBchannels(float *inputOutputBuffer);
void _applyRIFfilter(const double *sourceBuffer, double *destinationBuffer); void _applyRIFfilter(const float *sourceBuffer, float *destinationBuffer);
void _getNormalizedContoursImage(const double *inputFrame, double *outputFrame); void _getNormalizedContoursImage(const float *inputFrame, float *outputFrame);
// -> special adaptive filters dedicated to low pass filtering on the chrominance (skeeps filtering on the edges) // -> special adaptive filters dedicated to low pass filtering on the chrominance (skeeps filtering on the edges)
void _adaptiveSpatialLPfilter(const double *inputFrame, double *outputFrame); void _adaptiveSpatialLPfilter(const float *inputFrame, float *outputFrame);
void _adaptiveHorizontalCausalFilter_addInput(const double *inputFrame, double *outputFrame, const unsigned int IDrowStart, const unsigned int IDrowEnd); void _adaptiveHorizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, const unsigned int IDrowStart, const unsigned int IDrowEnd);
void _adaptiveHorizontalAnticausalFilter(double *outputFrame, const unsigned int IDrowStart, const unsigned int IDrowEnd); void _adaptiveHorizontalAnticausalFilter(float *outputFrame, const unsigned int IDrowStart, const unsigned int IDrowEnd);
void _adaptiveVerticalCausalFilter(double *outputFrame, const unsigned int IDcolumnStart, const unsigned int IDcolumnEnd); void _adaptiveVerticalCausalFilter(float *outputFrame, const unsigned int IDcolumnStart, const unsigned int IDcolumnEnd);
void _adaptiveVerticalAnticausalFilter_multGain(double *outputFrame, const unsigned int IDcolumnStart, const unsigned int IDcolumnEnd); void _adaptiveVerticalAnticausalFilter_multGain(float *outputFrame, const unsigned int IDcolumnStart, const unsigned int IDcolumnEnd);
void _computeGradient(const double *luminance); void _computeGradient(const float *luminance);
void _normalizeOutputs_0_maxOutputValue(void); void _normalizeOutputs_0_maxOutputValue(void);
// color space transform // color space transform
void _applyImageColorSpaceConversion(const std::valarray<double> &inputFrame, std::valarray<double> &outputFrame, const double *transformTable); void _applyImageColorSpaceConversion(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const float *transformTable);
}; };
} }

View File

@ -200,16 +200,16 @@ void RetinaFilter::_createHybridTable()
// fill _hybridParvoMagnoCoefTable // fill _hybridParvoMagnoCoefTable
int i, j, halfRows=_photoreceptorsPrefilter.getNBrows()/2, halfColumns=_photoreceptorsPrefilter.getNBcolumns()/2; int i, j, halfRows=_photoreceptorsPrefilter.getNBrows()/2, halfColumns=_photoreceptorsPrefilter.getNBcolumns()/2;
double *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0]; float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
double minDistance=MIN(halfRows, halfColumns)*0.7; float minDistance=(float)MIN(halfRows, halfColumns)*0.7;
for (i=0;i<(int)_photoreceptorsPrefilter.getNBrows();++i) for (i=0;i<(int)_photoreceptorsPrefilter.getNBrows();++i)
{ {
for (j=0;j<(int)_photoreceptorsPrefilter.getNBcolumns();++j) for (j=0;j<(int)_photoreceptorsPrefilter.getNBcolumns();++j)
{ {
double distanceToCenter=sqrt(((double)(i-halfRows)*(i-halfRows)+(j-halfColumns)*(j-halfColumns))); float distanceToCenter=sqrt(((float)(i-halfRows)*(i-halfRows)+(j-halfColumns)*(j-halfColumns)));
if (distanceToCenter<minDistance) if (distanceToCenter<minDistance)
{ {
double a=*(hybridParvoMagnoCoefTablePTR++)=0.5+0.5*cos(CV_PI*distanceToCenter/minDistance); float a=*(hybridParvoMagnoCoefTablePTR++)=0.5+0.5*cos(CV_PI*distanceToCenter/minDistance);
*(hybridParvoMagnoCoefTablePTR++)=1.0-a; *(hybridParvoMagnoCoefTablePTR++)=1.0-a;
}else }else
{ {
@ -221,7 +221,7 @@ void RetinaFilter::_createHybridTable()
} }
// setup parameters function and global data filling // setup parameters function and global data filling
void RetinaFilter::setGlobalParameters(const double OPLspatialResponse1, const double OPLtemporalresponse1, const double OPLassymetryGain, const double OPLspatialResponse2, const double OPLtemporalresponse2, const double LPfilterSpatialResponse, const double LPfilterGain, const double LPfilterTemporalresponse, const double MovingContoursExtractorCoefficient, const bool normalizeParvoOutput_0_maxOutputValue, const bool normalizeMagnoOutput_0_maxOutputValue, const double maxOutputValue, const double maxInputValue, const double meanValue) void RetinaFilter::setGlobalParameters(const float OPLspatialResponse1, const float OPLtemporalresponse1, const float OPLassymetryGain, const float OPLspatialResponse2, const float OPLtemporalresponse2, const float LPfilterSpatialResponse, const float LPfilterGain, const float LPfilterTemporalresponse, const float MovingContoursExtractorCoefficient, const bool normalizeParvoOutput_0_maxOutputValue, const bool normalizeMagnoOutput_0_maxOutputValue, const float maxOutputValue, const float maxInputValue, const float meanValue)
{ {
_normalizeParvoOutput_0_maxOutputValue=normalizeParvoOutput_0_maxOutputValue; _normalizeParvoOutput_0_maxOutputValue=normalizeParvoOutput_0_maxOutputValue;
_normalizeMagnoOutput_0_maxOutputValue=normalizeMagnoOutput_0_maxOutputValue; _normalizeMagnoOutput_0_maxOutputValue=normalizeMagnoOutput_0_maxOutputValue;
@ -240,7 +240,7 @@ void RetinaFilter::setGlobalParameters(const double OPLspatialResponse1, const d
_setInitPeriodCount(); _setInitPeriodCount();
} }
const bool RetinaFilter::checkInput(const std::valarray<double> &input, const bool) const bool RetinaFilter::checkInput(const std::valarray<float> &input, const bool)
{ {
BasicRetinaFilter *inputTarget=&_photoreceptorsPrefilter; BasicRetinaFilter *inputTarget=&_photoreceptorsPrefilter;
@ -259,7 +259,7 @@ const bool RetinaFilter::checkInput(const std::valarray<double> &input, const bo
} }
// main function that runs the filter for a given input frame // main function that runs the filter for a given input frame
const bool RetinaFilter::runFilter(const std::valarray<double> &imageInput, const bool useAdaptiveFiltering, const bool processRetinaParvoMagnoMapping, const bool useColorMode, const bool inputIsColorMultiplexed) const bool RetinaFilter::runFilter(const std::valarray<float> &imageInput, const bool useAdaptiveFiltering, const bool processRetinaParvoMagnoMapping, const bool useColorMode, const bool inputIsColorMultiplexed)
{ {
// preliminary check // preliminary check
bool processSuccess=true; bool processSuccess=true;
@ -281,8 +281,8 @@ const bool RetinaFilter::runFilter(const std::valarray<double> &imageInput, cons
* if color or something else must be considered, specific preprocessing are applied * if color or something else must be considered, specific preprocessing are applied
*/ */
const std::valarray<double> *selectedPhotoreceptorsLocalAdaptationInput= &imageInput; const std::valarray<float> *selectedPhotoreceptorsLocalAdaptationInput= &imageInput;
const std::valarray<double> *selectedPhotoreceptorsColorInput=&imageInput; const std::valarray<float> *selectedPhotoreceptorsColorInput=&imageInput;
//********** Following is input data specific photoreceptors processing //********** Following is input data specific photoreceptors processing
if (_photoreceptorsLogSampling) if (_photoreceptorsLogSampling)
@ -346,7 +346,7 @@ const bool RetinaFilter::runFilter(const std::valarray<double> &imageInput, cons
return processSuccess; return processSuccess;
} }
const std::valarray<double> &RetinaFilter::getContours() const std::valarray<float> &RetinaFilter::getContours()
{ {
if (_useColorMode) if (_useColorMode)
return _colorEngine.getLuminance(); return _colorEngine.getLuminance();
@ -355,7 +355,7 @@ const std::valarray<double> &RetinaFilter::getContours()
} }
// run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated // run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated
void RetinaFilter::runGrayToneMapping(const std::valarray<double> &grayImageInput, std::valarray<double> &grayImageOutput, const double PhotoreceptorsCompression, const double ganglionCellsCompression) void RetinaFilter::runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{ {
// preliminary check // preliminary check
if (!checkInput(grayImageInput, false)) if (!checkInput(grayImageInput, false))
@ -365,17 +365,17 @@ void RetinaFilter::runGrayToneMapping(const std::valarray<double> &grayImageInpu
} }
// run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated // run the initilized retina filter in order to perform gray image tone mapping, after this call all retina outputs are updated
void RetinaFilter::_runGrayToneMapping(const std::valarray<double> &grayImageInput, std::valarray<double> &grayImageOutput, const double PhotoreceptorsCompression, const double ganglionCellsCompression) void RetinaFilter::_runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{ {
// stability controls value update // stability controls value update
++_ellapsedFramesSinceLastReset; ++_ellapsedFramesSinceLastReset;
std::valarray<double> temp2(grayImageInput.size()); std::valarray<float> temp2(grayImageInput.size());
// apply tone mapping on the multiplexed image // apply tone mapping on the multiplexed image
// -> photoreceptors local adaptation (large area adaptation) // -> photoreceptors local adaptation (large area adaptation)
_photoreceptorsPrefilter.runFilter_LPfilter(grayImageInput, grayImageOutput, 2); // compute low pass filtering modeling the horizontal cells filtering to acess local luminance _photoreceptorsPrefilter.runFilter_LPfilter(grayImageInput, grayImageOutput, 2); // compute low pass filtering modeling the horizontal cells filtering to acess local luminance
_photoreceptorsPrefilter.setV0CompressionParameterToneMapping(PhotoreceptorsCompression, grayImageOutput.sum()/(double)_photoreceptorsPrefilter.getNBpixels()); _photoreceptorsPrefilter.setV0CompressionParameterToneMapping(PhotoreceptorsCompression, grayImageOutput.sum()/(float)_photoreceptorsPrefilter.getNBpixels());
_photoreceptorsPrefilter.runFilter_LocalAdapdation(grayImageInput, grayImageOutput, temp2); // adapt contrast to local luminance _photoreceptorsPrefilter.runFilter_LocalAdapdation(grayImageInput, grayImageOutput, temp2); // adapt contrast to local luminance
// high pass filter // high pass filter
@ -386,12 +386,12 @@ void RetinaFilter::_runGrayToneMapping(const std::valarray<double> &grayImageInp
// -> ganglion cells local adaptation (short area adaptation) // -> ganglion cells local adaptation (short area adaptation)
_photoreceptorsPrefilter.runFilter_LPfilter(temp2, grayImageOutput, 1); // compute low pass filtering (high cut frequency (remove spatio-temporal noise) _photoreceptorsPrefilter.runFilter_LPfilter(temp2, grayImageOutput, 1); // compute low pass filtering (high cut frequency (remove spatio-temporal noise)
_photoreceptorsPrefilter.setV0CompressionParameterToneMapping(ganglionCellsCompression, temp2.max(), temp2.sum()/(double)_photoreceptorsPrefilter.getNBpixels()); _photoreceptorsPrefilter.setV0CompressionParameterToneMapping(ganglionCellsCompression, temp2.max(), temp2.sum()/(float)_photoreceptorsPrefilter.getNBpixels());
_photoreceptorsPrefilter.runFilter_LocalAdapdation(temp2, grayImageOutput, grayImageOutput); // adapt contrast to local luminance _photoreceptorsPrefilter.runFilter_LocalAdapdation(temp2, grayImageOutput, grayImageOutput); // adapt contrast to local luminance
} }
// run the initilized retina filter in order to perform color tone mapping, after this call all retina outputs are updated // run the initilized retina filter in order to perform color tone mapping, after this call all retina outputs are updated
void RetinaFilter::runRGBToneMapping(const std::valarray<double> &RGBimageInput, std::valarray<double> &RGBimageOutput, const bool useAdaptiveFiltering, const double PhotoreceptorsCompression, const double ganglionCellsCompression) void RetinaFilter::runRGBToneMapping(const std::valarray<float> &RGBimageInput, std::valarray<float> &RGBimageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression, const float ganglionCellsCompression)
{ {
// preliminary check // preliminary check
if (!checkInput(RGBimageInput, true)) if (!checkInput(RGBimageInput, true))
@ -413,12 +413,12 @@ void RetinaFilter::runRGBToneMapping(const std::valarray<double> &RGBimageInput,
RGBimageOutput=_colorEngine.getDemultiplexedColorFrame(); RGBimageOutput=_colorEngine.getDemultiplexedColorFrame();
} }
void RetinaFilter::runLMSToneMapping(const std::valarray<double> &, std::valarray<double> &, const bool, const double, const double) void RetinaFilter::runLMSToneMapping(const std::valarray<float> &, std::valarray<float> &, const bool, const float, const float)
{ {
std::cerr<<"not working, sorry"<<std::endl; std::cerr<<"not working, sorry"<<std::endl;
/* // preliminary check /* // preliminary check
const std::valarray<double> &bufferInput=checkInput(LMSimageInput, true); const std::valarray<float> &bufferInput=checkInput(LMSimageInput, true);
if (!bufferInput) if (!bufferInput)
return NULL; return NULL;
@ -426,7 +426,7 @@ void RetinaFilter::runLMSToneMapping(const std::valarray<double> &, std::valarra
std::cerr<<"RetinaFilter::Can not call tone mapping oeration if the retina filter was created for gray scale images"<<std::endl; std::cerr<<"RetinaFilter::Can not call tone mapping oeration if the retina filter was created for gray scale images"<<std::endl;
// create a temporary buffer of size nrows, Mcolumns, 3 layers // create a temporary buffer of size nrows, Mcolumns, 3 layers
std::valarray<double> lmsTempBuffer(LMSimageInput); std::valarray<float> lmsTempBuffer(LMSimageInput);
std::cout<<"RetinaFilter::--->min LMS value="<<lmsTempBuffer.min()<<std::endl; std::cout<<"RetinaFilter::--->min LMS value="<<lmsTempBuffer.min()<<std::endl;
// setup local adaptation parameter at the photoreceptors level // setup local adaptation parameter at the photoreceptors level
@ -454,8 +454,8 @@ void RetinaFilter::runLMSToneMapping(const std::valarray<double> &, std::valarra
// compute LMS to A Cr1 Cr2 color space conversion // compute LMS to A Cr1 Cr2 color space conversion
_applyImageColorSpaceConversion(lmsTempBuffer.Buffer(), lmsTempBuffer.Buffer(), _LMStoACr1Cr2); _applyImageColorSpaceConversion(lmsTempBuffer.Buffer(), lmsTempBuffer.Buffer(), _LMStoACr1Cr2);
TemplateBuffer <double> acr1cr2TempBuffer(_NBrows, _NBcolumns, 3); TemplateBuffer <float> acr1cr2TempBuffer(_NBrows, _NBcolumns, 3);
memcpy(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), sizeof(double)*_NBpixels*3); memcpy(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), sizeof(float)*_NBpixels*3);
// compute A Cr1 Cr2 to LMS color space conversion // compute A Cr1 Cr2 to LMS color space conversion
_applyImageColorSpaceConversion(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), _ACr1Cr2toLMS); _applyImageColorSpaceConversion(acr1cr2TempBuffer.Buffer(), lmsTempBuffer.Buffer(), _ACr1Cr2toLMS);
@ -473,31 +473,31 @@ void RetinaFilter::runLMSToneMapping(const std::valarray<double> &, std::valarra
// return image with center Parvo and peripheral Magno channels // return image with center Parvo and peripheral Magno channels
void RetinaFilter::_processRetinaParvoMagnoMapping() void RetinaFilter::_processRetinaParvoMagnoMapping()
{ {
register double *hybridParvoMagnoPTR= &_retinaParvoMagnoMappedFrame[0]; register float *hybridParvoMagnoPTR= &_retinaParvoMagnoMappedFrame[0];
register const double *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput()); register const float *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput());
register const double *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput()); register const float *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput());
register double *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0]; register float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2) for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{ {
double hybridValue=*(parvoOutputPTR++)**(hybridParvoMagnoCoefTablePTR)+*(magnoXOutputPTR++)**(hybridParvoMagnoCoefTablePTR+1); float hybridValue=*(parvoOutputPTR++)**(hybridParvoMagnoCoefTablePTR)+*(magnoXOutputPTR++)**(hybridParvoMagnoCoefTablePTR+1);
*(hybridParvoMagnoPTR++)=hybridValue; *(hybridParvoMagnoPTR++)=hybridValue;
} }
TemplateBuffer<double>::normalizeGrayOutput_0_maxOutputValue(&_retinaParvoMagnoMappedFrame[0], _photoreceptorsPrefilter.getNBpixels()); TemplateBuffer<float>::normalizeGrayOutput_0_maxOutputValue(&_retinaParvoMagnoMappedFrame[0], _photoreceptorsPrefilter.getNBpixels());
} }
const bool RetinaFilter::getParvoFoveaResponse(std::valarray<double> &parvoFovealResponse) const bool RetinaFilter::getParvoFoveaResponse(std::valarray<float> &parvoFovealResponse)
{ {
if (!_useParvoOutput) if (!_useParvoOutput)
return false; return false;
if (parvoFovealResponse.size() != _ParvoRetinaFilter.getNBpixels()) if (parvoFovealResponse.size() != _ParvoRetinaFilter.getNBpixels())
return false; return false;
register const double *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput()); register const float *parvoOutputPTR= get_data(_ParvoRetinaFilter.getOutput());
register double *fovealParvoResponsePTR= &parvoFovealResponse[0]; register float *fovealParvoResponsePTR= &parvoFovealResponse[0];
register double *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0]; register float *hybridParvoMagnoCoefTablePTR= &_retinaParvoMagnoMapCoefTable[0];
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2) for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{ {
@ -508,16 +508,16 @@ const bool RetinaFilter::getParvoFoveaResponse(std::valarray<double> &parvoFovea
} }
// method to retrieve the parafoveal magnocellular pathway response (no energy motion in fovea) // method to retrieve the parafoveal magnocellular pathway response (no energy motion in fovea)
const bool RetinaFilter::getMagnoParaFoveaResponse(std::valarray<double> &magnoParafovealResponse) const bool RetinaFilter::getMagnoParaFoveaResponse(std::valarray<float> &magnoParafovealResponse)
{ {
if (!_useMagnoOutput) if (!_useMagnoOutput)
return false; return false;
if (magnoParafovealResponse.size() != _MagnoRetinaFilter.getNBpixels()) if (magnoParafovealResponse.size() != _MagnoRetinaFilter.getNBpixels())
return false; return false;
register const double *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput()); register const float *magnoXOutputPTR= get_data(_MagnoRetinaFilter.getOutput());
register double *parafovealMagnoResponsePTR=&magnoParafovealResponse[0]; register float *parafovealMagnoResponsePTR=&magnoParafovealResponse[0];
register double *hybridParvoMagnoCoefTablePTR=&_retinaParvoMagnoMapCoefTable[0]+1; register float *hybridParvoMagnoCoefTablePTR=&_retinaParvoMagnoMapCoefTable[0]+1;
for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2) for (unsigned int i=0 ; i<_photoreceptorsPrefilter.getNBpixels() ; ++i, hybridParvoMagnoCoefTablePTR+=2)
{ {

View File

@ -84,9 +84,9 @@
* retina->runfilter(FrameBuffer); * retina->runfilter(FrameBuffer);
* *
* // get the different output frames, check in the class description below for more outputs: * // get the different output frames, check in the class description below for more outputs:
* const std::valarray<double> correctedLuminance=retina->getLocalAdaptation(); * const std::valarray<float> correctedLuminance=retina->getLocalAdaptation();
* const std::valarray<double> contours=retina->getContours(); * const std::valarray<float> contours=retina->getContours();
* const std::valarray<double> movingContours=retina->getMovingContours(); * const std::valarray<float> movingContours=retina->getMovingContours();
* *
* // at the end of the program, destroy object: * // at the end of the program, destroy object:
* delete retina; * delete retina;
@ -151,7 +151,7 @@ public:
* @param colorMode: specifiy if the input should be considered by the retina as colored of not * @param colorMode: specifiy if the input should be considered by the retina as colored of not
* @return false if not compatible or it returns true if OK * @return false if not compatible or it returns true if OK
*/ */
const bool checkInput(const std::valarray<double> &input, const bool colorMode); const bool checkInput(const std::valarray<float> &input, const bool colorMode);
/** /**
* run the initilized retina filter, after this call all retina outputs are updated * run the initilized retina filter, after this call all retina outputs are updated
@ -163,7 +163,7 @@ public:
@param inputIsColorMultiplexed: set trus if the input data is a multiplexed color image (using Bayer sampling for example), the color sampling method must correspond to the RETINA_COLORSAMPLINGMETHOD passed at constructor! @param inputIsColorMultiplexed: set trus if the input data is a multiplexed color image (using Bayer sampling for example), the color sampling method must correspond to the RETINA_COLORSAMPLINGMETHOD passed at constructor!
* @return true if process ran well, false in case of failure * @return true if process ran well, false in case of failure
*/ */
const bool runFilter(const std::valarray<double> &imageInput, const bool useAdaptiveFiltering=true, const bool processRetinaParvoMagnoMapping=false, const bool useColorMode=false, const bool inputIsColorMultiplexed=false); const bool runFilter(const std::valarray<float> &imageInput, const bool useAdaptiveFiltering=true, const bool processRetinaParvoMagnoMapping=false, const bool useColorMode=false, const bool inputIsColorMultiplexed=false);
/** /**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it) * run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
@ -174,7 +174,7 @@ public:
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas) * @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast) * @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast)
*/ */
void runGrayToneMapping(const std::valarray<double> &grayImageInput, std::valarray<double> &grayImageOutput, const double PhotoreceptorsCompression=0.6, const double ganglionCellsCompression=0.6); void runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/** /**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it) * run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
@ -186,7 +186,7 @@ public:
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas) * @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the ganglion cells output (enhance contrast) * @param ganglionCellsCompression: sets the log compression applied at the ganglion cells output (enhance contrast)
*/ */
void runRGBToneMapping(const std::valarray<double> &RGBimageInput, std::valarray<double> &imageOutput, const bool useAdaptiveFiltering, const double PhotoreceptorsCompression=0.6, const double ganglionCellsCompression=0.6); void runRGBToneMapping(const std::valarray<float> &RGBimageInput, std::valarray<float> &imageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/** /**
* run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it) * run the initilized retina filter in order to perform color tone mapping applied on an RGB image, after this call the color output of the retina is updated (use function getColorOutput() to grab it)
@ -196,7 +196,7 @@ public:
* @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas) * @param PhotoreceptorsCompression: sets the log compression parameters applied at the photoreceptors level (enhance luminance in dark areas)
* @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast) * @param ganglionCellsCompression: sets the log compression applied at the gnaglion cells output (enhance contrast)
*/ */
void runLMSToneMapping(const std::valarray<double> &LMSimageInput, std::valarray<double> &imageOutput, const bool useAdaptiveFiltering, const double PhotoreceptorsCompression=0.6, const double ganglionCellsCompression=0.6); void runLMSToneMapping(const std::valarray<float> &LMSimageInput, std::valarray<float> &imageOutput, const bool useAdaptiveFiltering, const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
/** /**
* set up function of the retina filter: all the retina is initialized at this step, some specific parameters are set by default, use setOPLandParvoCoefficientsTable() and setMagnoCoefficientsTable in order to setup the retina with more options * set up function of the retina filter: all the retina is initialized at this step, some specific parameters are set by default, use setOPLandParvoCoefficientsTable() and setMagnoCoefficientsTable in order to setup the retina with more options
@ -215,32 +215,32 @@ public:
* @param maxInputValue: the maximum pixel value of the input picture (generally 255 for 8bit per channel pictures), specify it in other case (for example High Dynamic Range Images) * @param maxInputValue: the maximum pixel value of the input picture (generally 255 for 8bit per channel pictures), specify it in other case (for example High Dynamic Range Images)
* @param meanValue: the global mean value of the input data usefull for local adaptation setup * @param meanValue: the global mean value of the input data usefull for local adaptation setup
*/ */
void setGlobalParameters(const double OPLspatialResponse1=0.7, const double OPLtemporalresponse1=1, const double OPLassymetryGain=0, const double OPLspatialResponse2=5, const double OPLtemporalresponse2=1, const double LPfilterSpatialResponse=5, const double LPfilterGain=0, const double LPfilterTemporalresponse=0, const double MovingContoursExtractorCoefficient=5, const bool normalizeParvoOutput_0_maxOutputValue=false, const bool normalizeMagnoOutput_0_maxOutputValue=false, const double maxOutputValue=255.0, const double maxInputValue=255.0, const double meanValue=128.0); void setGlobalParameters(const float OPLspatialResponse1=0.7, const float OPLtemporalresponse1=1, const float OPLassymetryGain=0, const float OPLspatialResponse2=5, const float OPLtemporalresponse2=1, const float LPfilterSpatialResponse=5, const float LPfilterGain=0, const float LPfilterTemporalresponse=0, const float MovingContoursExtractorCoefficient=5, const bool normalizeParvoOutput_0_maxOutputValue=false, const bool normalizeMagnoOutput_0_maxOutputValue=false, const float maxOutputValue=255.0, const float maxInputValue=255.0, const float meanValue=128.0);
/** /**
* setup the local luminance adaptation capability * setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the photoreceptors local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160 * @param V0CompressionParameter: the compression strengh of the photoreceptors local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/ */
inline void setPhotoreceptorsLocalAdaptationSensitivity(const double V0CompressionParameter){_photoreceptorsPrefilter.setV0CompressionParameter(1.0-V0CompressionParameter);_setInitPeriodCount();}; inline void setPhotoreceptorsLocalAdaptationSensitivity(const float V0CompressionParameter){_photoreceptorsPrefilter.setV0CompressionParameter(1.0-V0CompressionParameter);_setInitPeriodCount();};
/** /**
* setup the local luminance adaptation capability * setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the parvocellular pathway (details) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160 * @param V0CompressionParameter: the compression strengh of the parvocellular pathway (details) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/ */
inline void setParvoGanglionCellsLocalAdaptationSensitivity(const double V0CompressionParameter){_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();}; inline void setParvoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter){_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/** /**
* setup the local luminance adaptation area of integration * setup the local luminance adaptation area of integration
* @param spatialResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values * @param spatialResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values
* @param temporalResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values (generally set to zero: immediate response) * @param temporalResponse: the spatial constant of the low pass filter applied on the bipolar cells output in order to compute local contrast mean values (generally set to zero: immediate response)
*/ */
inline void setGanglionCellsLocalAdaptationLPfilterParameters(const double spatialResponse, const double temporalResponse){_ParvoRetinaFilter.setGanglionCellsLocalAdaptationLPfilterParameters(temporalResponse, spatialResponse);_setInitPeriodCount();}; inline void setGanglionCellsLocalAdaptationLPfilterParameters(const float spatialResponse, const float temporalResponse){_ParvoRetinaFilter.setGanglionCellsLocalAdaptationLPfilterParameters(temporalResponse, spatialResponse);_setInitPeriodCount();};
/** /**
* setup the local luminance adaptation capability * setup the local luminance adaptation capability
* @param V0CompressionParameter: the compression strengh of the magnocellular pathway (motion) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160 * @param V0CompressionParameter: the compression strengh of the magnocellular pathway (motion) local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 160
*/ */
inline void setMagnoGanglionCellsLocalAdaptationSensitivity(const double V0CompressionParameter){_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();}; inline void setMagnoGanglionCellsLocalAdaptationSensitivity(const float V0CompressionParameter){_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/** /**
* setup the OPL and IPL parvo channels * setup the OPL and IPL parvo channels
@ -252,7 +252,7 @@ public:
* @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model) * @param k2: the spatial constant of the first order low pass filter of the horizontal cells, use it to cut low spatial frequencies (local luminance), unit is pixels, typical value is 5 pixel, this value is also used for local contrast computing when computing the local contrast adaptation at the ganglion cells level (Inner Plexiform Layer parvocellular channel model)
* @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 230 * @param V0CompressionParameter: the compression strengh of the ganglion cells local adaptation output, set a value between 160 and 250 for best results, a high value increases more the low value sensitivity... and the output saturates faster, recommended value: 230
*/ */
void setOPLandParvoParameters(const double beta1, const double tau1, const double k1, const double beta2, const double tau2, const double k2, const double V0CompressionParameter){_ParvoRetinaFilter.setOPLandParvoFiltersParameters(beta1, tau1, k1, beta2, tau2, k2);_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();}; void setOPLandParvoParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2, const float V0CompressionParameter){_ParvoRetinaFilter.setOPLandParvoFiltersParameters(beta1, tau1, k1, beta2, tau2, k2);_ParvoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/** /**
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel * set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
@ -264,7 +264,7 @@ public:
* @param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation * @param localAdaptintegration_tau: specifies the temporal constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
* @param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation * @param localAdaptintegration_k: specifies the spatial constant of the low pas filter involved in the computation of the local "motion mean" for the local adaptation computation
*/ */
void setMagnoCoefficientsTable(const double parasolCells_beta, const double parasolCells_tau, const double parasolCells_k, const double amacrinCellsTemporalCutFrequency, const double V0CompressionParameter, const double localAdaptintegration_tau, const double localAdaptintegration_k){_MagnoRetinaFilter.setCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, localAdaptintegration_tau, localAdaptintegration_k);_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();}; void setMagnoCoefficientsTable(const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k){_MagnoRetinaFilter.setCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, localAdaptintegration_tau, localAdaptintegration_k);_MagnoRetinaFilter.setV0CompressionParameter(V0CompressionParameter);_setInitPeriodCount();};
/** /**
* set if the parvo output should be or not normalized between 0 and 255 (for display purpose generally) * set if the parvo output should be or not normalized between 0 and 255 (for display purpose generally)
@ -282,7 +282,7 @@ public:
* setup the maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures) * setup the maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures)
* @param maxOutputValue: maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures) * @param maxOutputValue: maximum amplitude value of the normalized outputs (generally 255 for 8bit per channel pictures)
*/ */
inline void setMaxOutputValue(const double maxOutputValue){_maxOutputValue=maxOutputValue;}; inline void setMaxOutputValue(const float maxOutputValue){_maxOutputValue=maxOutputValue;};
/** /**
* sets the color mode of the frame grabber * sets the color mode of the frame grabber
@ -296,7 +296,7 @@ public:
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false) * @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
* @param colorSaturationValue: the saturation factor * @param colorSaturationValue: the saturation factor
* */ * */
inline void setColorSaturation(const bool saturateColors=true, const double colorSaturationValue=4.0){_colorEngine.setColorSaturation(saturateColors, colorSaturationValue);}; inline void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0){_colorEngine.setColorSaturation(saturateColors, colorSaturationValue);};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// function that retrieve the main retina outputs, one by one, or all in a structure // function that retrieve the main retina outputs, one by one, or all in a structure
@ -304,22 +304,22 @@ public:
/** /**
* @return the input image sampled by the photoreceptors spatial sampling * @return the input image sampled by the photoreceptors spatial sampling
*/ */
inline const std::valarray<double> &getPhotoreceptorsSampledFrame() const {if (_photoreceptorsLogSampling)return _photoreceptorsLogSampling->getSampledFrame();}; inline const std::valarray<float> &getPhotoreceptorsSampledFrame() const {if (_photoreceptorsLogSampling)return _photoreceptorsLogSampling->getSampledFrame();};
/** /**
* @return photoreceptors output, locally adapted luminance only, no high frequency spatio-temporal noise reduction at the next retina processing stages, use getPhotoreceptors method to get complete photoreceptors output * @return photoreceptors output, locally adapted luminance only, no high frequency spatio-temporal noise reduction at the next retina processing stages, use getPhotoreceptors method to get complete photoreceptors output
*/ */
inline const std::valarray<double> &getLocalAdaptation() const {return _photoreceptorsPrefilter.getOutput();}; inline const std::valarray<float> &getLocalAdaptation() const {return _photoreceptorsPrefilter.getOutput();};
/** /**
* @return photoreceptors output: locally adapted luminance and high frequency spatio-temporal noise reduction, high luminance is a little saturated at this stage, but this is corrected naturally at the next retina processing stages * @return photoreceptors output: locally adapted luminance and high frequency spatio-temporal noise reduction, high luminance is a little saturated at this stage, but this is corrected naturally at the next retina processing stages
*/ */
inline const std::valarray<double> &getPhotoreceptors() const {return _ParvoRetinaFilter.getPhotoreceptorsLPfilteringOutput();}; inline const std::valarray<float> &getPhotoreceptors() const {return _ParvoRetinaFilter.getPhotoreceptorsLPfilteringOutput();};
/** /**
* @return the local luminance of the processed frame (it is the horizontal cells output) * @return the local luminance of the processed frame (it is the horizontal cells output)
*/ */
inline const std::valarray<double> &getHorizontalCells() const {return _ParvoRetinaFilter.getHorizontalCellsOutput();}; inline const std::valarray<float> &getHorizontalCells() const {return _ParvoRetinaFilter.getHorizontalCellsOutput();};
///////// CONTOURS part, PARVOCELLULAR RETINA PATHWAY ///////// CONTOURS part, PARVOCELLULAR RETINA PATHWAY
/** /**
@ -332,7 +332,7 @@ public:
* @param parvoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area * @param parvoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area
* @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized * @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized
*/ */
const bool getParvoFoveaResponse(std::valarray<double> &parvoFovealResponse); const bool getParvoFoveaResponse(std::valarray<float> &parvoFovealResponse);
/** /**
* @param useParvoOutput: true if Parvocellular output should be activated, false if not * @param useParvoOutput: true if Parvocellular output should be activated, false if not
@ -342,17 +342,17 @@ public:
/** /**
* @return the parvocellular contours information (details), should be used at the fovea level * @return the parvocellular contours information (details), should be used at the fovea level
*/ */
const std::valarray<double> &getContours(); // Parvocellular output const std::valarray<float> &getContours(); // Parvocellular output
/** /**
* @return the parvocellular contours ON information (details), should be used at the fovea level * @return the parvocellular contours ON information (details), should be used at the fovea level
*/ */
inline const std::valarray<double> &getContoursON() const {return _ParvoRetinaFilter.getParvoON();};// Parvocellular ON output inline const std::valarray<float> &getContoursON() const {return _ParvoRetinaFilter.getParvoON();};// Parvocellular ON output
/** /**
* @return the parvocellular contours OFF information (details), should be used at the fovea level * @return the parvocellular contours OFF information (details), should be used at the fovea level
*/ */
inline const std::valarray<double> &getContoursOFF() const {return _ParvoRetinaFilter.getParvoOFF();};// Parvocellular OFF output inline const std::valarray<float> &getContoursOFF() const {return _ParvoRetinaFilter.getParvoOFF();};// Parvocellular OFF output
///////// MOVING CONTOURS part, MAGNOCELLULAR RETINA PATHWAY ///////// MOVING CONTOURS part, MAGNOCELLULAR RETINA PATHWAY
/** /**
@ -365,7 +365,7 @@ public:
* @param magnoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area * @param magnoParafovealResponse: buffer that will be filled with the response of the magnocellular pathway in the parafoveal area
* @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized * @return true if process succeeded (if buffer exists, is its size matches retina size, if magno channel is activated and if mapping is initialized
*/ */
const bool getMagnoParaFoveaResponse(std::valarray<double> &magnoParafovealResponse); const bool getMagnoParaFoveaResponse(std::valarray<float> &magnoParafovealResponse);
/** /**
* @param useMagnoOutput: true if Magnoocellular output should be activated, false if not * @param useMagnoOutput: true if Magnoocellular output should be activated, false if not
@ -375,60 +375,60 @@ public:
/** /**
* @return the magnocellular moving contours information (motion), should be used at the parafovea level without post-processing * @return the magnocellular moving contours information (motion), should be used at the parafovea level without post-processing
*/ */
inline const std::valarray<double> &getMovingContours() const {return _MagnoRetinaFilter.getOutput();};// Magnocellular output inline const std::valarray<float> &getMovingContours() const {return _MagnoRetinaFilter.getOutput();};// Magnocellular output
/** /**
* @return the magnocellular moving contours information (motion), should be used at the parafovea level with assymetric sigmoide post-processing which saturates motion information * @return the magnocellular moving contours information (motion), should be used at the parafovea level with assymetric sigmoide post-processing which saturates motion information
*/ */
inline const std::valarray<double> &getMovingContoursSaturated() const {return _MagnoRetinaFilter.getMagnoYsaturated();};// Saturated Magnocellular output inline const std::valarray<float> &getMovingContoursSaturated() const {return _MagnoRetinaFilter.getMagnoYsaturated();};// Saturated Magnocellular output
/** /**
* @return the magnocellular moving contours ON information (motion), should be used at the parafovea level without post-processing * @return the magnocellular moving contours ON information (motion), should be used at the parafovea level without post-processing
*/ */
inline const std::valarray<double> &getMovingContoursON() const {return _MagnoRetinaFilter.getMagnoON();};// Magnocellular ON output inline const std::valarray<float> &getMovingContoursON() const {return _MagnoRetinaFilter.getMagnoON();};// Magnocellular ON output
/** /**
* @return the magnocellular moving contours OFF information (motion), should be used at the parafovea level without post-processing * @return the magnocellular moving contours OFF information (motion), should be used at the parafovea level without post-processing
*/ */
inline const std::valarray<double> &getMovingContoursOFF() const {return _MagnoRetinaFilter.getMagnoOFF();};// Magnocellular OFF output inline const std::valarray<float> &getMovingContoursOFF() const {return _MagnoRetinaFilter.getMagnoOFF();};// Magnocellular OFF output
/** /**
* @return a gray level image with center Parvo and peripheral Magno X channels, WARNING, the result will be ok if you called previously fucntion runFilter(imageInput, processRetinaParvoMagnoMapping=true); * @return a gray level image with center Parvo and peripheral Magno X channels, WARNING, the result will be ok if you called previously fucntion runFilter(imageInput, processRetinaParvoMagnoMapping=true);
* -> will be accessible even if color mode is activated (but the image is color sampled so quality is poor), but get the same thing but in color by the use of function getParvoColor() * -> will be accessible even if color mode is activated (but the image is color sampled so quality is poor), but get the same thing but in color by the use of function getParvoColor()
*/ */
inline const std::valarray<double> &getRetinaParvoMagnoMappedOutput() const {return _retinaParvoMagnoMappedFrame;};// return image with center Parvo and peripheral Magno channels inline const std::valarray<float> &getRetinaParvoMagnoMappedOutput() const {return _retinaParvoMagnoMappedFrame;};// return image with center Parvo and peripheral Magno channels
/** /**
* color processing dedicated functions * color processing dedicated functions
* @return the parvo channel (contours, details) of the processed frame, grayscale output * @return the parvo channel (contours, details) of the processed frame, grayscale output
*/ */
inline const std::valarray<double> &getParvoContoursChannel() const {return _colorEngine.getLuminance();}; inline const std::valarray<float> &getParvoContoursChannel() const {return _colorEngine.getLuminance();};
/** /**
* color processing dedicated functions * color processing dedicated functions
* @return the chrominance of the processed frame (same colorspace as the input output, usually RGB) * @return the chrominance of the processed frame (same colorspace as the input output, usually RGB)
*/ */
inline const std::valarray<double> &getParvoChrominance() const {return _colorEngine.getChrominance();}; // only retreive chrominance inline const std::valarray<float> &getParvoChrominance() const {return _colorEngine.getChrominance();}; // only retreive chrominance
/** /**
* color processing dedicated functions * color processing dedicated functions
* @return the parvo + chrominance channels of the processed frame (same colorspace as the input output, usually RGB) * @return the parvo + chrominance channels of the processed frame (same colorspace as the input output, usually RGB)
*/ */
inline const std::valarray<double> &getColorOutput() const {return _colorEngine.getDemultiplexedColorFrame();};// retrieve luminance+chrominance inline const std::valarray<float> &getColorOutput() const {return _colorEngine.getDemultiplexedColorFrame();};// retrieve luminance+chrominance
/** /**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space * apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output * @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully * @return true if process ended successfully
*/ */
inline const bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<double> &result){return _colorEngine.applyKrauskopfLMS2Acr1cr2Transform(result);}; inline const bool applyKrauskopfLMS2Acr1cr2Transform(std::valarray<float> &result){return _colorEngine.applyKrauskopfLMS2Acr1cr2Transform(result);};
/** /**
* apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space * apply to the retina color output the Krauskopf transformation which leads to an opponent color system: output colorspace if Acr1cr2 if input of the retina was LMS color space
* @param result: the input buffer to fill with the transformed colorspace retina output * @param result: the input buffer to fill with the transformed colorspace retina output
* @return true if process ended successfully * @return true if process ended successfully
*/ */
inline const bool applyLMS2LabTransform(std::valarray<double> &result){return _colorEngine.applyLMS2LabTransform(result);}; inline const bool applyLMS2LabTransform(std::valarray<float> &result){return _colorEngine.applyLMS2LabTransform(result);};
/** /**
* color processing dedicated functions * color processing dedicated functions
@ -439,7 +439,7 @@ public:
/** /**
* @return the irregular low pass filter ouput at the photoreceptors level * @return the irregular low pass filter ouput at the photoreceptors level
*/ */
inline const std::valarray<double> &getIrregularLPfilteredInputFrame() const {return _photoreceptorsLogSampling->getIrregularLPfilteredInputFrame();}; inline const std::valarray<float> &getIrregularLPfilteredInputFrame() const {return _photoreceptorsLogSampling->getIrregularLPfilteredInputFrame();};
/** /**
* @return true if color mode is activated, false if gray levels processing * @return true if color mode is activated, false if gray levels processing
@ -457,7 +457,7 @@ public:
* @param projectedRadiusLength: the distance to image center in the retina log sampled space * @param projectedRadiusLength: the distance to image center in the retina log sampled space
* @return the distance to image center in the input image space * @return the distance to image center in the input image space
*/ */
inline const double getRetinaSamplingBackProjection(const double projectedRadiusLength){if (_photoreceptorsLogSampling)return _photoreceptorsLogSampling->getOriginalRadiusLength(projectedRadiusLength);else return projectedRadiusLength;}; inline const float getRetinaSamplingBackProjection(const float projectedRadiusLength){if (_photoreceptorsLogSampling)return _photoreceptorsLogSampling->getOriginalRadiusLength(projectedRadiusLength);else return projectedRadiusLength;};
/////////////////: /////////////////:
// retina dimensions getters // retina dimensions getters
@ -505,8 +505,8 @@ private:
unsigned int _globalTemporalConstant; unsigned int _globalTemporalConstant;
// private template buffers and related access pointers // private template buffers and related access pointers
std::valarray<double> _retinaParvoMagnoMappedFrame; std::valarray<float> _retinaParvoMagnoMappedFrame;
std::valarray<double> _retinaParvoMagnoMapCoefTable; std::valarray<float> _retinaParvoMagnoMapCoefTable;
// private objects of the class // private objects of the class
BasicRetinaFilter _photoreceptorsPrefilter; BasicRetinaFilter _photoreceptorsPrefilter;
ParvoRetinaFilter _ParvoRetinaFilter; ParvoRetinaFilter _ParvoRetinaFilter;
@ -518,7 +518,7 @@ private:
bool _normalizeParvoOutput_0_maxOutputValue; bool _normalizeParvoOutput_0_maxOutputValue;
bool _normalizeMagnoOutput_0_maxOutputValue; bool _normalizeMagnoOutput_0_maxOutputValue;
double _maxOutputValue; float _maxOutputValue;
bool _useColorMode; bool _useColorMode;
@ -527,7 +527,7 @@ private:
void _setInitPeriodCount(); void _setInitPeriodCount();
void _createHybridTable(); void _createHybridTable();
void _processRetinaParvoMagnoMapping(); void _processRetinaParvoMagnoMapping();
void _runGrayToneMapping(const std::valarray<double> &grayImageInput, std::valarray<double> &grayImageOutput ,const double PhotoreceptorsCompression=0.6, const double ganglionCellsCompression=0.6); void _runGrayToneMapping(const std::valarray<float> &grayImageInput, std::valarray<float> &grayImageOutput ,const float PhotoreceptorsCompression=0.6, const float ganglionCellsCompression=0.6);
}; };