// run filter for a new frame input // output return is (*_parvocellularOutputONminusOFF) const std::valarray<float> &ParvoRetinaFilter::runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput) { _spatiotemporalLPfilter(get_data(inputFrame), &_photoreceptorsOutput[0]); _spatiotemporalLPfilter(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], 1); _OPL_OnOffWaysComputing(); if (useParvoOutput) { // local adaptation processes on ON and OFF ways _spatiotemporalLPfilter(&_bipolarCellsOutputON[0], &(*_localAdaptationON)[0], 2); _localLuminanceAdaptation(&_parvocellularOutputON[0], &(*_localAdaptationON)[0]); _spatiotemporalLPfilter(&_bipolarCellsOutputOFF[0], &_localAdaptationOFF[0], 2); _localLuminanceAdaptation(&_parvocellularOutputOFF[0], &_localAdaptationOFF[0]); //// Final loop that computes the main output of this filter // //// 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 register float *parvocellularOutputONminusOFF_PTR=&(*_parvocellularOutputONminusOFF)[0]; register float *parvocellularOutputON_PTR=&_parvocellularOutputON[0]; register float *parvocellularOutputOFF_PTR=&_parvocellularOutputOFF[0]; for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel) *(parvocellularOutputONminusOFF_PTR++)= (*(parvocellularOutputON_PTR++)-*(parvocellularOutputOFF_PTR++)); } return (*_parvocellularOutputONminusOFF); }
// 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) { // Compute the high pass temporal filter _amacrineCellsComputing(get_data(OPL_ON), get_data(OPL_OFF)); // apply low pass filtering on ON and OFF ways after temporal high pass filtering _spatiotemporalLPfilter(&_amacrinCellsTempOutput_ON[0], &_magnoXOutputON[0], 0); _spatiotemporalLPfilter(&_amacrinCellsTempOutput_OFF[0], &_magnoXOutputOFF[0], 0); // local adaptation of the ganglion cells to the local contrast of the moving contours _spatiotemporalLPfilter(&_magnoXOutputON[0], &_localProcessBufferON[0], 1); _localLuminanceAdaptation(&_magnoXOutputON[0], &_localProcessBufferON[0]); _spatiotemporalLPfilter(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0], 1); _localLuminanceAdaptation(&_magnoXOutputOFF[0], &_localProcessBufferOFF[0]); /* Compute MagnoY */ register double *magnoYOutput= &(*_magnoYOutput)[0]; register double *magnoXOutputON_PTR= &_magnoXOutputON[0]; register double *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0]; for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel) *(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++); return (*_magnoYOutput); }
// run LP filter for a new frame input and save result at a specific output adress void BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const unsigned int filterIndex) { _spatiotemporalLPfilter(get_data(inputFrame), &outputFrame[0], filterIndex); }
/////////////////////////////////////////////////////////////////////// /// Spatio temporal Low Pass filter functions // run LP filter and save result in the basic retina element buffer const std::valarray<float> &BasicRetinaFilter::runFilter_LPfilter(const std::valarray<float> &inputFrame, const unsigned int filterIndex) { _spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0], filterIndex); return _filterOutput; }
// run local adaptation filter at a specific output adress with autonomous low pass filtering before adaptation void BasicRetinaFilter::runFilter_LocalAdapdation_autonomous(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame) { _spatiotemporalLPfilter(get_data(inputFrame), &_filterOutput[0]); _localLuminanceAdaptation(get_data(inputFrame), &_filterOutput[0], &outputFrame[0]); }
void TransientAreasSegmentationModuleImpl::_run(const std::valarray<float> &inputToSegment, const int channelIndex) { #ifdef SEGMENTATIONDEBUG std::cout<<"Input length vs internal buffers length = "<<inputToSegment.size()<<", "<<_localMotion.size()<<std::endl; #endif // preliminary basic error check // FIXME validate basic tests //if (inputToSegment.size() != _localMotion.size()) // throw cv::Exception(-1, "Input matrix size does not match instance buffers setup !", "SegmentationModule::run", "SegmentationModule.cpp", 0); // first square the input in order to increase the signal to noise ratio // get motion local energy _squaringSpatiotemporalLPfilter(&inputToSegment[channelIndex*getNBpixels()], &_localMotion[0]); // second low pass filter: access to the neighborhood motion energy _spatiotemporalLPfilter(&_localMotion[0], &_neighborhoodMotion[0], 1); // third low pass filter: access to the background motion energy _spatiotemporalLPfilter(&_localMotion[0], &_contextMotionEnergy[0], 2); // compute the ON and OFF ways (positive and negative values of the difference of the two filterings) float*localMotionPTR=&_localMotion[0], *neighborhoodMotionPTR=&_neighborhoodMotion[0], *contextMotionPTR=&_contextMotionEnergy[0]; // float meanEnergy=LPfilter2.sum()/(float)_LPfilter2.size(); register bool *segmentationPicturePTR= &_segmentedAreas[0]; for (unsigned int index=0; index<_filterOutput.getNBpixels() ; ++index, ++segmentationPicturePTR, ++localMotionPTR, ++neighborhoodMotionPTR, contextMotionPTR++) { float generalMotionContextDecision=*neighborhoodMotionPTR-*contextMotionPTR; if (generalMotionContextDecision>0) // local maximum should be detected in this case { /* apply segmentation on local motion superior to its neighborhood * => to segment objects moving faster than their neighborhood */ if (generalMotionContextDecision>_segmentationParameters.thresholdON)// && meanEnergy*1.1<*neighborhoodMotionPTR) { *segmentationPicturePTR=((*localMotionPTR-*neighborhoodMotionPTR)>_segmentationParameters.thresholdON); } else *segmentationPicturePTR=false; } #ifdef USE_LOCALMINIMUMS else // local minimum should be detected in this case { /* apply segmentation for non moving objects * only if the wide area around motion energy is high * => to segment object moving slower than the neighborhood */ if (-1.0*generalMotionContextDecision>_segmentationParameters.thresholdOFF && meanEnergy*0.9>*neighborhoodMotionPTR) { /* in order to segment non moving objects in a camera motion case * we focus on local energy which is much lower than the wide neighborhood */ *segmentationPicturePTR+=(*neighborhoodMotionPTR-*localMotionPTR>_segmentationParameters.thresholdOFF)*127; } } #else else *segmentationPicturePTR=false; #endif }