Normalize line endings and whitespace
This commit is contained in:

committed by
Andrey Kamaev

parent
0442bca235
commit
81f826db2b
@@ -1,9 +1,9 @@
|
||||
FaceRecognizer - Face Recognition with OpenCV
|
||||
##############################################
|
||||
|
||||
OpenCV 2.4 now comes with the very new :ocv:class:`FaceRecognizer` class for face recognition. This documentation is going to explain you :doc:`the API <facerec_api>` in detail and it will give you a lot of help to get started (full source code examples). :doc:`Face Recognition with OpenCV <facerec_tutorial>` is the definite guide to the new :ocv:class:`FaceRecognizer`. There's also a :doc:`tutorial on gender classification <tutorial/facerec_gender_classification>`, a :doc:`tutorial for face recognition in videos <tutorial/facerec_video_recognition>` and it's shown :doc:`how to load & save your results <tutorial/facerec_save_load>`.
|
||||
OpenCV 2.4 now comes with the very new :ocv:class:`FaceRecognizer` class for face recognition. This documentation is going to explain you :doc:`the API <facerec_api>` in detail and it will give you a lot of help to get started (full source code examples). :doc:`Face Recognition with OpenCV <facerec_tutorial>` is the definite guide to the new :ocv:class:`FaceRecognizer`. There's also a :doc:`tutorial on gender classification <tutorial/facerec_gender_classification>`, a :doc:`tutorial for face recognition in videos <tutorial/facerec_video_recognition>` and it's shown :doc:`how to load & save your results <tutorial/facerec_save_load>`.
|
||||
|
||||
These documents are the help I have wished for, when I was working myself into face recognition. I hope you also think the new :ocv:class:`FaceRecognizer` is a useful addition to OpenCV.
|
||||
These documents are the help I have wished for, when I was working myself into face recognition. I hope you also think the new :ocv:class:`FaceRecognizer` is a useful addition to OpenCV.
|
||||
|
||||
Please issue any feature requests and/or bugs on the official OpenCV bug tracker at:
|
||||
|
||||
@@ -15,7 +15,7 @@ Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
|
||||
FaceRecognizer API <facerec_api>
|
||||
Guide to Face Recognition with OpenCV <facerec_tutorial>
|
||||
Tutorial on Gender Classification <tutorial/facerec_gender_classification>
|
||||
|
@@ -11,13 +11,13 @@ find_package(OpenCV REQUIRED) # http://opencv.willowgarage.com
|
||||
# probably you should loop through the sample files here
|
||||
add_executable(facerec_demo facerec_demo.cpp)
|
||||
target_link_libraries(facerec_demo opencv_core opencv_contrib opencv_imgproc opencv_highgui)
|
||||
|
||||
|
||||
add_executable(facerec_video facerec_video.cpp)
|
||||
target_link_libraries(facerec_video opencv_contrib opencv_core opencv_imgproc opencv_highgui opencv_objdetect opencv_imgproc)
|
||||
|
||||
|
||||
add_executable(facerec_eigenfaces facerec_eigenfaces.cpp)
|
||||
target_link_libraries(facerec_eigenfaces opencv_contrib opencv_core opencv_imgproc opencv_highgui)
|
||||
|
||||
|
||||
add_executable(facerec_fisherfaces facerec_fisherfaces.cpp)
|
||||
target_link_libraries(facerec_fisherfaces opencv_contrib opencv_core opencv_imgproc opencv_highgui)
|
||||
|
||||
|
6
modules/contrib/doc/facerec/src/create_csv.py
Normal file → Executable file
6
modules/contrib/doc/facerec/src/create_csv.py
Normal file → Executable file
@@ -3,7 +3,7 @@ import os.path
|
||||
|
||||
# This is a tiny script to help you creating a CSV file from a face
|
||||
# database with a similar hierarchie:
|
||||
#
|
||||
#
|
||||
# philipp@mango:~/facerec/data/at$ tree
|
||||
# .
|
||||
# |-- README
|
||||
@@ -23,11 +23,11 @@ import os.path
|
||||
#
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print "usage: create_csv <base_path>"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
BASE_PATH=sys.argv[1]
|
||||
SEPARATOR=";"
|
||||
|
||||
|
@@ -80,7 +80,7 @@ def CropFace(image, eye_left=(0,0), eye_right=(0,0), offset_pct=(0.2,0.2), dest_
|
||||
# resize it
|
||||
image = image.resize(dest_sz, Image.ANTIALIAS)
|
||||
return image
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
image = Image.open("arnie.jpg")
|
||||
CropFace(image, eye_left=(252,364), eye_right=(420,366), offset_pct=(0.1,0.1), dest_sz=(200,200)).save("arnie_10_10_200_200.jpg")
|
||||
|
@@ -85,7 +85,7 @@ class DetectionBasedTracker
|
||||
bool setParameters(const Parameters& params);
|
||||
const Parameters& getParameters() const;
|
||||
|
||||
|
||||
|
||||
typedef std::pair<cv::Rect, int> Object;
|
||||
virtual void getObjects(std::vector<cv::Rect>& result) const;
|
||||
virtual void getObjects(std::vector<Object>& result) const;
|
||||
|
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -80,9 +80,9 @@ namespace cv
|
||||
|
||||
enum RETINA_COLORSAMPLINGMETHOD
|
||||
{
|
||||
RETINA_COLOR_RANDOM, //!< each pixel position is either R, G or B in a random choice
|
||||
RETINA_COLOR_DIAGONAL,//!< color sampling is RGBRGBRGB..., line 2 BRGBRGBRG..., line 3, GBRGBRGBR...
|
||||
RETINA_COLOR_BAYER//!< standard bayer sampling
|
||||
RETINA_COLOR_RANDOM, //!< each pixel position is either R, G or B in a random choice
|
||||
RETINA_COLOR_DIAGONAL,//!< color sampling is RGBRGBRGB..., line 2 BRGBRGBRG..., line 3, GBRGBRGBR...
|
||||
RETINA_COLOR_BAYER//!< standard bayer sampling
|
||||
};
|
||||
|
||||
class RetinaFilter;
|
||||
@@ -114,9 +114,9 @@ class CV_EXPORTS Retina {
|
||||
|
||||
public:
|
||||
|
||||
// parameters structure for better clarity, check explenations on the comments of methods : setupOPLandIPLParvoChannel and setupIPLMagnoChannel
|
||||
struct RetinaParameters{
|
||||
struct OPLandIplParvoParameters{ // Outer Plexiform Layer (OPL) and Inner Plexiform Layer Parvocellular (IplParvo) parameters
|
||||
// parameters structure for better clarity, check explenations on the comments of methods : setupOPLandIPLParvoChannel and setupIPLMagnoChannel
|
||||
struct RetinaParameters{
|
||||
struct OPLandIplParvoParameters{ // Outer Plexiform Layer (OPL) and Inner Plexiform Layer Parvocellular (IplParvo) parameters
|
||||
OPLandIplParvoParameters():colorMode(true),
|
||||
normaliseOutput(true),
|
||||
photoreceptorsLocalAdaptationSensitivity(0.7f),
|
||||
@@ -144,166 +144,166 @@ public:
|
||||
};
|
||||
struct OPLandIplParvoParameters OPLandIplParvo;
|
||||
struct IplMagnoParameters IplMagno;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor with most commun use setup : create an instance of color ready retina model
|
||||
* @param inputSize : the input frame size
|
||||
*/
|
||||
Retina(Size inputSize);
|
||||
/**
|
||||
* Main constructor with most commun use setup : create an instance of color ready retina model
|
||||
* @param inputSize : the input frame size
|
||||
*/
|
||||
Retina(Size inputSize);
|
||||
|
||||
/**
|
||||
* Complete Retina filter constructor which allows all basic structural parameters definition
|
||||
/**
|
||||
* Complete Retina filter constructor which allows all basic structural parameters definition
|
||||
* @param inputSize : the input frame size
|
||||
* @param colorMode : the chosen processing mode : with or without color processing
|
||||
* @param colorSamplingMethod: specifies which kind of color sampling will be used
|
||||
* @param useRetinaLogSampling: activate retina log sampling, if true, the 2 following parameters can be used
|
||||
* @param reductionFactor: only usefull if param useRetinaLogSampling=true, specifies the reduction factor of the output frame (as the center (fovea) is high resolution and corners can be underscaled, then a reduction of the output is allowed without precision leak
|
||||
* @param samplingStrenght: only usefull if param useRetinaLogSampling=true, specifies the strenght of the log scale that is applied
|
||||
*/
|
||||
Retina(Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
|
||||
* @param colorMode : the chosen processing mode : with or without color processing
|
||||
* @param colorSamplingMethod: specifies which kind of color sampling will be used
|
||||
* @param useRetinaLogSampling: activate retina log sampling, if true, the 2 following parameters can be used
|
||||
* @param reductionFactor: only usefull if param useRetinaLogSampling=true, specifies the reduction factor of the output frame (as the center (fovea) is high resolution and corners can be underscaled, then a reduction of the output is allowed without precision leak
|
||||
* @param samplingStrenght: only usefull if param useRetinaLogSampling=true, specifies the strenght of the log scale that is applied
|
||||
*/
|
||||
Retina(Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
|
||||
|
||||
virtual ~Retina();
|
||||
virtual ~Retina();
|
||||
|
||||
/**
|
||||
* retreive retina input buffer size
|
||||
/**
|
||||
* retreive retina input buffer size
|
||||
*/
|
||||
Size inputSize();
|
||||
|
||||
/**
|
||||
* retreive retina output buffer size
|
||||
/**
|
||||
* retreive retina output buffer size
|
||||
*/
|
||||
Size outputSize();
|
||||
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param retinaParameterFile : the parameters filename
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param retinaParameterFile : the parameters filename
|
||||
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
|
||||
*/
|
||||
void setup(std::string retinaParameterFile="", const bool applyDefaultSetupOnFailure=true);
|
||||
*/
|
||||
void setup(std::string retinaParameterFile="", const bool applyDefaultSetupOnFailure=true);
|
||||
|
||||
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param fs : the open Filestorage which contains retina parameters
|
||||
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param fs : the open Filestorage which contains retina parameters
|
||||
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
|
||||
*/
|
||||
*/
|
||||
void setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure=true);
|
||||
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param newParameters : a parameters structures updated with the new target configuration
|
||||
/**
|
||||
* try to open an XML retina parameters file to adjust current retina instance setup
|
||||
* => if the xml file does not exist, then default setup is applied
|
||||
* => warning, Exceptions are thrown if read XML file is not valid
|
||||
* @param newParameters : a parameters structures updated with the new target configuration
|
||||
* @param applyDefaultSetupOnFailure : set to true if an error must be thrown on error
|
||||
*/
|
||||
void setup(RetinaParameters newParameters);
|
||||
*/
|
||||
void setup(RetinaParameters newParameters);
|
||||
|
||||
/**
|
||||
* @return the current parameters setup
|
||||
*/
|
||||
struct Retina::RetinaParameters getParameters();
|
||||
|
||||
/**
|
||||
* parameters setup display method
|
||||
* @return a string which contains formatted parameters information
|
||||
*/
|
||||
const std::string printSetup();
|
||||
/**
|
||||
* parameters setup display method
|
||||
* @return a string which contains formatted parameters information
|
||||
*/
|
||||
const std::string printSetup();
|
||||
|
||||
/**
|
||||
* write xml/yml formated parameters information
|
||||
* @rparam fs : the filename of the xml file that will be open and writen with formatted parameters information
|
||||
*/
|
||||
virtual void write( std::string fs ) const;
|
||||
/**
|
||||
* write xml/yml formated parameters information
|
||||
* @rparam fs : the filename of the xml file that will be open and writen with formatted parameters information
|
||||
*/
|
||||
virtual void write( std::string fs ) const;
|
||||
|
||||
|
||||
/**
|
||||
* write xml/yml formated parameters information
|
||||
* @param fs : a cv::Filestorage object ready to be filled
|
||||
/**
|
||||
* write xml/yml formated parameters information
|
||||
* @param fs : a cv::Filestorage object ready to be filled
|
||||
*/
|
||||
virtual void write( FileStorage& fs ) const;
|
||||
virtual void write( FileStorage& fs ) const;
|
||||
|
||||
/**
|
||||
* setup the OPL and IPL parvo channels (see biologocal model)
|
||||
* OPL is referred as Outer Plexiform Layer of the retina, it allows the spatio-temporal filtering which withens the spectrum and reduces spatio-temporal noise while attenuating global luminance (low frequency energy)
|
||||
* IPL parvo is the OPL next processing stage, it refers to Inner Plexiform layer of the retina, it allows high contours sensitivity in foveal vision.
|
||||
* for more informations, please have a look at the paper Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
* @param colorMode : specifies if (true) color is processed of not (false) to then processing gray level image
|
||||
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
|
||||
* @param photoreceptorsLocalAdaptationSensitivity: the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
|
||||
* @param photoreceptorsTemporalConstant: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
|
||||
* @param photoreceptorsSpatialConstant: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
|
||||
* @param horizontalCellsGain: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
|
||||
* @param HcellsTemporalConstant: 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 HcellsSpatialConstant: 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 ganglionCellsSensitivity: 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 setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput = true, const float photoreceptorsLocalAdaptationSensitivity=0.7, const float photoreceptorsTemporalConstant=0.5, const float photoreceptorsSpatialConstant=0.53, const float horizontalCellsGain=0, const float HcellsTemporalConstant=1, const float HcellsSpatialConstant=7, const float ganglionCellsSensitivity=0.7);
|
||||
/**
|
||||
* setup the OPL and IPL parvo channels (see biologocal model)
|
||||
* OPL is referred as Outer Plexiform Layer of the retina, it allows the spatio-temporal filtering which withens the spectrum and reduces spatio-temporal noise while attenuating global luminance (low frequency energy)
|
||||
* IPL parvo is the OPL next processing stage, it refers to Inner Plexiform layer of the retina, it allows high contours sensitivity in foveal vision.
|
||||
* for more informations, please have a look at the paper Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
* @param colorMode : specifies if (true) color is processed of not (false) to then processing gray level image
|
||||
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
|
||||
* @param photoreceptorsLocalAdaptationSensitivity: the photoreceptors sensitivity renage is 0-1 (more log compression effect when value increases)
|
||||
* @param photoreceptorsTemporalConstant: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
|
||||
* @param photoreceptorsSpatialConstant: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
|
||||
* @param horizontalCellsGain: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
|
||||
* @param HcellsTemporalConstant: 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 HcellsSpatialConstant: 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 ganglionCellsSensitivity: 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 setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput = true, const float photoreceptorsLocalAdaptationSensitivity=0.7, const float photoreceptorsTemporalConstant=0.5, const float photoreceptorsSpatialConstant=0.53, const float horizontalCellsGain=0, const float HcellsTemporalConstant=1, const float HcellsSpatialConstant=7, const float ganglionCellsSensitivity=0.7);
|
||||
|
||||
/**
|
||||
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
|
||||
* this channel processes signals outpint from OPL processing stage in peripheral vision, it allows motion information enhancement. It is decorrelated from the details channel. See reference paper for more details.
|
||||
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
|
||||
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
|
||||
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
|
||||
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
|
||||
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
|
||||
* @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: 200
|
||||
* @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
|
||||
*/
|
||||
void setupIPLMagnoChannel(const bool normaliseOutput = true, const float parasolCells_beta=0, const float parasolCells_tau=0, const float parasolCells_k=7, const float amacrinCellsTemporalCutFrequency=1.2, const float V0CompressionParameter=0.95, const float localAdaptintegration_tau=0, const float localAdaptintegration_k=7);
|
||||
/**
|
||||
* set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
|
||||
* this channel processes signals outpint from OPL processing stage in peripheral vision, it allows motion information enhancement. It is decorrelated from the details channel. See reference paper for more details.
|
||||
* @param normaliseOutput : specifies if (true) output is rescaled between 0 and 255 of not (false)
|
||||
* @param parasolCells_beta: the low pass filter gain used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), typical value is 0
|
||||
* @param parasolCells_tau: the low pass filter time constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is frame, typical value is 0 (immediate response)
|
||||
* @param parasolCells_k: the low pass filter spatial constant used for local contrast adaptation at the IPL level of the retina (for ganglion cells local adaptation), unit is pixels, typical value is 5
|
||||
* @param amacrinCellsTemporalCutFrequency: the time constant of the first order high pass fiter of the magnocellular way (motion information channel), unit is frames, tipicall value is 5
|
||||
* @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: 200
|
||||
* @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
|
||||
*/
|
||||
void setupIPLMagnoChannel(const bool normaliseOutput = true, const float parasolCells_beta=0, const float parasolCells_tau=0, const float parasolCells_k=7, const float amacrinCellsTemporalCutFrequency=1.2, const float V0CompressionParameter=0.95, const float localAdaptintegration_tau=0, const float localAdaptintegration_k=7);
|
||||
|
||||
/**
|
||||
* method which allows retina to be applied on an input image, after run, encapsulated retina module is ready to deliver its outputs using dedicated acccessors, see getParvo and getMagno methods
|
||||
* @param inputImage : the input cv::Mat image to be processed, can be gray level or BGR coded in any format (from 8bit to 16bits)
|
||||
*/
|
||||
void run(const Mat &inputImage);
|
||||
/**
|
||||
* method which allows retina to be applied on an input image, after run, encapsulated retina module is ready to deliver its outputs using dedicated acccessors, see getParvo and getMagno methods
|
||||
* @param inputImage : the input cv::Mat image to be processed, can be gray level or BGR coded in any format (from 8bit to 16bits)
|
||||
*/
|
||||
void run(const Mat &inputImage);
|
||||
|
||||
/**
|
||||
* accessor of the details channel of the retina (models foveal vision)
|
||||
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
|
||||
*/
|
||||
void getParvo(Mat &retinaOutput_parvo);
|
||||
/**
|
||||
* accessor of the details channel of the retina (models foveal vision)
|
||||
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
|
||||
*/
|
||||
void getParvo(Mat &retinaOutput_parvo);
|
||||
|
||||
/**
|
||||
* accessor of the details channel of the retina (models foveal vision)
|
||||
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is the original retina filter model output, without any quantification or rescaling
|
||||
*/
|
||||
void getParvo(std::valarray<float> &retinaOutput_parvo);
|
||||
/**
|
||||
* accessor of the details channel of the retina (models foveal vision)
|
||||
* @param retinaOutput_parvo : the output buffer (reallocated if necessary), this output is the original retina filter model output, without any quantification or rescaling
|
||||
*/
|
||||
void getParvo(std::valarray<float> &retinaOutput_parvo);
|
||||
|
||||
/**
|
||||
* accessor of the motion channel of the retina (models peripheral vision)
|
||||
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
|
||||
*/
|
||||
void getMagno(Mat &retinaOutput_magno);
|
||||
/**
|
||||
* accessor of the motion channel of the retina (models peripheral vision)
|
||||
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is rescaled for standard 8bits image processing use in OpenCV
|
||||
*/
|
||||
void getMagno(Mat &retinaOutput_magno);
|
||||
|
||||
/**
|
||||
* accessor of the motion channel of the retina (models peripheral vision)
|
||||
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is the original retina filter model output, without any quantification or rescaling
|
||||
*/
|
||||
void getMagno(std::valarray<float> &retinaOutput_magno);
|
||||
/**
|
||||
* accessor of the motion channel of the retina (models peripheral vision)
|
||||
* @param retinaOutput_magno : the output buffer (reallocated if necessary), this output is the original retina filter model output, without any quantification or rescaling
|
||||
*/
|
||||
void getMagno(std::valarray<float> &retinaOutput_magno);
|
||||
|
||||
// original API level data accessors : get buffers addresses...
|
||||
const std::valarray<float> & getMagno() const;
|
||||
const std::valarray<float> & getParvo() const;
|
||||
// original API level data accessors : get buffers addresses...
|
||||
const std::valarray<float> & getMagno() const;
|
||||
const std::valarray<float> & getParvo() const;
|
||||
|
||||
/**
|
||||
* activate color saturation as the final step of the color demultiplexing process
|
||||
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
|
||||
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
|
||||
* @param colorSaturationValue: the saturation factor
|
||||
*/
|
||||
void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0);
|
||||
/**
|
||||
* activate color saturation as the final step of the color demultiplexing process
|
||||
* -> this saturation is a sigmoide function applied to each channel of the demultiplexed image.
|
||||
* @param saturateColors: boolean that activates color saturation (if true) or desactivate (if false)
|
||||
* @param colorSaturationValue: the saturation factor
|
||||
*/
|
||||
void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0);
|
||||
|
||||
/**
|
||||
* clear all retina buffers (equivalent to opening the eyes after a long period of eye close ;o)
|
||||
*/
|
||||
void clearBuffers();
|
||||
/**
|
||||
* clear all retina buffers (equivalent to opening the eyes after a long period of eye close ;o)
|
||||
*/
|
||||
void clearBuffers();
|
||||
|
||||
/**
|
||||
* Activate/desactivate the Magnocellular pathway processing (motion information extraction), by default, it is activated
|
||||
@@ -318,35 +318,35 @@ public:
|
||||
void activateContoursProcessing(const bool activate);
|
||||
|
||||
protected:
|
||||
// Parameteres setup members
|
||||
RetinaParameters _retinaParameters; // structure of parameters
|
||||
|
||||
// Parameteres setup members
|
||||
RetinaParameters _retinaParameters; // structure of parameters
|
||||
|
||||
// Retina model related modules
|
||||
std::valarray<float> _inputBuffer; //!< buffer used to convert input cv::Mat to internal retina buffers format (valarrays)
|
||||
std::valarray<float> _inputBuffer; //!< buffer used to convert input cv::Mat to internal retina buffers format (valarrays)
|
||||
|
||||
// pointer to retina model
|
||||
RetinaFilter* _retinaFilter; //!< the pointer to the retina module, allocated with instance construction
|
||||
// pointer to retina model
|
||||
RetinaFilter* _retinaFilter; //!< the pointer to the retina module, allocated with instance construction
|
||||
|
||||
/**
|
||||
* exports a valarray buffer outing from HVStools objects to a cv::Mat in CV_8UC1 (gray level picture) or CV_8UC3 (color) format
|
||||
* @param grayMatrixToConvert the valarray to export to OpenCV
|
||||
* @param nbRows : the number of rows of the valarray flatten matrix
|
||||
* @param nbColumns : the number of rows of the valarray flatten matrix
|
||||
* @param colorMode : a flag which mentions if matrix is color (true) or graylevel (false)
|
||||
* @param outBuffer : the output matrix which is reallocated to satisfy Retina output buffer dimensions
|
||||
*/
|
||||
void _convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, Mat &outBuffer);
|
||||
/**
|
||||
* exports a valarray buffer outing from HVStools objects to a cv::Mat in CV_8UC1 (gray level picture) or CV_8UC3 (color) format
|
||||
* @param grayMatrixToConvert the valarray to export to OpenCV
|
||||
* @param nbRows : the number of rows of the valarray flatten matrix
|
||||
* @param nbColumns : the number of rows of the valarray flatten matrix
|
||||
* @param colorMode : a flag which mentions if matrix is color (true) or graylevel (false)
|
||||
* @param outBuffer : the output matrix which is reallocated to satisfy Retina output buffer dimensions
|
||||
*/
|
||||
void _convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, Mat &outBuffer);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inputMatToConvert : the OpenCV cv::Mat that has to be converted to gray or RGB valarray buffer that will be processed by the retina model
|
||||
* @param outputValarrayMatrix : the output valarray
|
||||
* @return the input image color mode (color=true, gray levels=false)
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param inputMatToConvert : the OpenCV cv::Mat that has to be converted to gray or RGB valarray buffer that will be processed by the retina model
|
||||
* @param outputValarrayMatrix : the output valarray
|
||||
* @return the input image color mode (color=true, gray levels=false)
|
||||
*/
|
||||
bool _convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert, std::valarray<float> &outputValarrayMatrix);
|
||||
|
||||
//! private method called by constructors, gathers their parameters and use them in a unified way
|
||||
void _init(const Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
|
||||
//! private method called by constructors, gathers their parameters and use them in a unified way
|
||||
void _init(const Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod=RETINA_COLOR_BAYER, const bool useRetinaLogSampling=false, const double reductionFactor=1.0, const double samplingStrenght=10.0);
|
||||
|
||||
|
||||
};
|
||||
|
@@ -42,152 +42,152 @@
|
||||
|
||||
void CvAdaptiveSkinDetector::initData(IplImage *src, int widthDivider, int heightDivider)
|
||||
{
|
||||
CvSize imageSize = cvSize(src->width/widthDivider, src->height/heightDivider);
|
||||
CvSize imageSize = cvSize(src->width/widthDivider, src->height/heightDivider);
|
||||
|
||||
imgHueFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgShrinked = cvCreateImage(imageSize, IPL_DEPTH_8U, src->nChannels);
|
||||
imgSaturationFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgMotionFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgTemp = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgFilteredFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgLastGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgHSVFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 3);
|
||||
imgHueFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgShrinked = cvCreateImage(imageSize, IPL_DEPTH_8U, src->nChannels);
|
||||
imgSaturationFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgMotionFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgTemp = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgFilteredFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgLastGrayFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
|
||||
imgHSVFrame = cvCreateImage(imageSize, IPL_DEPTH_8U, 3);
|
||||
};
|
||||
|
||||
CvAdaptiveSkinDetector::CvAdaptiveSkinDetector(int samplingDivider, int morphingMethod)
|
||||
{
|
||||
nSkinHueLowerBound = GSD_HUE_LT;
|
||||
nSkinHueUpperBound = GSD_HUE_UT;
|
||||
nSkinHueLowerBound = GSD_HUE_LT;
|
||||
nSkinHueUpperBound = GSD_HUE_UT;
|
||||
|
||||
fHistogramMergeFactor = 0.05; // empirical result
|
||||
fHuePercentCovered = 0.95; // empirical result
|
||||
fHistogramMergeFactor = 0.05; // empirical result
|
||||
fHuePercentCovered = 0.95; // empirical result
|
||||
|
||||
nMorphingMethod = morphingMethod;
|
||||
nSamplingDivider = samplingDivider;
|
||||
nMorphingMethod = morphingMethod;
|
||||
nSamplingDivider = samplingDivider;
|
||||
|
||||
nFrameCount = 0;
|
||||
nStartCounter = 0;
|
||||
nFrameCount = 0;
|
||||
nStartCounter = 0;
|
||||
|
||||
imgHueFrame = NULL;
|
||||
imgMotionFrame = NULL;
|
||||
imgTemp = NULL;
|
||||
imgFilteredFrame = NULL;
|
||||
imgShrinked = NULL;
|
||||
imgGrayFrame = NULL;
|
||||
imgLastGrayFrame = NULL;
|
||||
imgSaturationFrame = NULL;
|
||||
imgHSVFrame = NULL;
|
||||
imgHueFrame = NULL;
|
||||
imgMotionFrame = NULL;
|
||||
imgTemp = NULL;
|
||||
imgFilteredFrame = NULL;
|
||||
imgShrinked = NULL;
|
||||
imgGrayFrame = NULL;
|
||||
imgLastGrayFrame = NULL;
|
||||
imgSaturationFrame = NULL;
|
||||
imgHSVFrame = NULL;
|
||||
};
|
||||
|
||||
CvAdaptiveSkinDetector::~CvAdaptiveSkinDetector()
|
||||
{
|
||||
cvReleaseImage(&imgHueFrame);
|
||||
cvReleaseImage(&imgSaturationFrame);
|
||||
cvReleaseImage(&imgMotionFrame);
|
||||
cvReleaseImage(&imgTemp);
|
||||
cvReleaseImage(&imgFilteredFrame);
|
||||
cvReleaseImage(&imgShrinked);
|
||||
cvReleaseImage(&imgGrayFrame);
|
||||
cvReleaseImage(&imgLastGrayFrame);
|
||||
cvReleaseImage(&imgHSVFrame);
|
||||
cvReleaseImage(&imgHueFrame);
|
||||
cvReleaseImage(&imgSaturationFrame);
|
||||
cvReleaseImage(&imgMotionFrame);
|
||||
cvReleaseImage(&imgTemp);
|
||||
cvReleaseImage(&imgFilteredFrame);
|
||||
cvReleaseImage(&imgShrinked);
|
||||
cvReleaseImage(&imgGrayFrame);
|
||||
cvReleaseImage(&imgLastGrayFrame);
|
||||
cvReleaseImage(&imgHSVFrame);
|
||||
};
|
||||
|
||||
void CvAdaptiveSkinDetector::process(IplImage *inputBGRImage, IplImage *outputHueMask)
|
||||
{
|
||||
IplImage *src = inputBGRImage;
|
||||
IplImage *src = inputBGRImage;
|
||||
|
||||
int h, v, i, l;
|
||||
bool isInit = false;
|
||||
int h, v, i, l;
|
||||
bool isInit = false;
|
||||
|
||||
nFrameCount++;
|
||||
nFrameCount++;
|
||||
|
||||
if (imgHueFrame == NULL)
|
||||
{
|
||||
isInit = true;
|
||||
initData(src, nSamplingDivider, nSamplingDivider);
|
||||
}
|
||||
if (imgHueFrame == NULL)
|
||||
{
|
||||
isInit = true;
|
||||
initData(src, nSamplingDivider, nSamplingDivider);
|
||||
}
|
||||
|
||||
unsigned char *pShrinked, *pHueFrame, *pMotionFrame, *pLastGrayFrame, *pFilteredFrame, *pGrayFrame;
|
||||
pShrinked = (unsigned char *)imgShrinked->imageData;
|
||||
pHueFrame = (unsigned char *)imgHueFrame->imageData;
|
||||
pMotionFrame = (unsigned char *)imgMotionFrame->imageData;
|
||||
pLastGrayFrame = (unsigned char *)imgLastGrayFrame->imageData;
|
||||
pFilteredFrame = (unsigned char *)imgFilteredFrame->imageData;
|
||||
pGrayFrame = (unsigned char *)imgGrayFrame->imageData;
|
||||
unsigned char *pShrinked, *pHueFrame, *pMotionFrame, *pLastGrayFrame, *pFilteredFrame, *pGrayFrame;
|
||||
pShrinked = (unsigned char *)imgShrinked->imageData;
|
||||
pHueFrame = (unsigned char *)imgHueFrame->imageData;
|
||||
pMotionFrame = (unsigned char *)imgMotionFrame->imageData;
|
||||
pLastGrayFrame = (unsigned char *)imgLastGrayFrame->imageData;
|
||||
pFilteredFrame = (unsigned char *)imgFilteredFrame->imageData;
|
||||
pGrayFrame = (unsigned char *)imgGrayFrame->imageData;
|
||||
|
||||
if ((src->width != imgHueFrame->width) || (src->height != imgHueFrame->height))
|
||||
{
|
||||
cvResize(src, imgShrinked);
|
||||
cvCvtColor(imgShrinked, imgHSVFrame, CV_BGR2HSV);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvCvtColor(src, imgHSVFrame, CV_BGR2HSV);
|
||||
}
|
||||
if ((src->width != imgHueFrame->width) || (src->height != imgHueFrame->height))
|
||||
{
|
||||
cvResize(src, imgShrinked);
|
||||
cvCvtColor(imgShrinked, imgHSVFrame, CV_BGR2HSV);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvCvtColor(src, imgHSVFrame, CV_BGR2HSV);
|
||||
}
|
||||
|
||||
cvSplit(imgHSVFrame, imgHueFrame, imgSaturationFrame, imgGrayFrame, 0);
|
||||
cvSplit(imgHSVFrame, imgHueFrame, imgSaturationFrame, imgGrayFrame, 0);
|
||||
|
||||
cvSetZero(imgMotionFrame);
|
||||
cvSetZero(imgFilteredFrame);
|
||||
cvSetZero(imgMotionFrame);
|
||||
cvSetZero(imgFilteredFrame);
|
||||
|
||||
l = imgHueFrame->height * imgHueFrame->width;
|
||||
l = imgHueFrame->height * imgHueFrame->width;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
v = (*pGrayFrame);
|
||||
if ((v >= GSD_INTENSITY_LT) && (v <= GSD_INTENSITY_UT))
|
||||
{
|
||||
h = (*pHueFrame);
|
||||
if ((h >= GSD_HUE_LT) && (h <= GSD_HUE_UT))
|
||||
{
|
||||
if ((h >= nSkinHueLowerBound) && (h <= nSkinHueUpperBound))
|
||||
ASD_INTENSITY_SET_PIXEL(pFilteredFrame, h);
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
v = (*pGrayFrame);
|
||||
if ((v >= GSD_INTENSITY_LT) && (v <= GSD_INTENSITY_UT))
|
||||
{
|
||||
h = (*pHueFrame);
|
||||
if ((h >= GSD_HUE_LT) && (h <= GSD_HUE_UT))
|
||||
{
|
||||
if ((h >= nSkinHueLowerBound) && (h <= nSkinHueUpperBound))
|
||||
ASD_INTENSITY_SET_PIXEL(pFilteredFrame, h);
|
||||
|
||||
if (ASD_IS_IN_MOTION(pLastGrayFrame, v, 7))
|
||||
ASD_INTENSITY_SET_PIXEL(pMotionFrame, h);
|
||||
}
|
||||
}
|
||||
pShrinked += 3;
|
||||
pGrayFrame++;
|
||||
pLastGrayFrame++;
|
||||
pMotionFrame++;
|
||||
pHueFrame++;
|
||||
pFilteredFrame++;
|
||||
}
|
||||
if (ASD_IS_IN_MOTION(pLastGrayFrame, v, 7))
|
||||
ASD_INTENSITY_SET_PIXEL(pMotionFrame, h);
|
||||
}
|
||||
}
|
||||
pShrinked += 3;
|
||||
pGrayFrame++;
|
||||
pLastGrayFrame++;
|
||||
pMotionFrame++;
|
||||
pHueFrame++;
|
||||
pFilteredFrame++;
|
||||
}
|
||||
|
||||
if (isInit)
|
||||
cvCalcHist(&imgHueFrame, skinHueHistogram.fHistogram);
|
||||
if (isInit)
|
||||
cvCalcHist(&imgHueFrame, skinHueHistogram.fHistogram);
|
||||
|
||||
cvCopy(imgGrayFrame, imgLastGrayFrame);
|
||||
cvCopy(imgGrayFrame, imgLastGrayFrame);
|
||||
|
||||
cvErode(imgMotionFrame, imgTemp); // eliminate disperse pixels, which occur because of the camera noise
|
||||
cvDilate(imgTemp, imgMotionFrame);
|
||||
cvErode(imgMotionFrame, imgTemp); // eliminate disperse pixels, which occur because of the camera noise
|
||||
cvDilate(imgTemp, imgMotionFrame);
|
||||
|
||||
cvCalcHist(&imgMotionFrame, histogramHueMotion.fHistogram);
|
||||
cvCalcHist(&imgMotionFrame, histogramHueMotion.fHistogram);
|
||||
|
||||
skinHueHistogram.mergeWith(&histogramHueMotion, fHistogramMergeFactor);
|
||||
skinHueHistogram.mergeWith(&histogramHueMotion, fHistogramMergeFactor);
|
||||
|
||||
skinHueHistogram.findCurveThresholds(nSkinHueLowerBound, nSkinHueUpperBound, 1 - fHuePercentCovered);
|
||||
skinHueHistogram.findCurveThresholds(nSkinHueLowerBound, nSkinHueUpperBound, 1 - fHuePercentCovered);
|
||||
|
||||
switch (nMorphingMethod)
|
||||
{
|
||||
case MORPHING_METHOD_ERODE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvCopy(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
case MORPHING_METHOD_ERODE_ERODE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvErode(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
case MORPHING_METHOD_ERODE_DILATE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvDilate(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
}
|
||||
switch (nMorphingMethod)
|
||||
{
|
||||
case MORPHING_METHOD_ERODE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvCopy(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
case MORPHING_METHOD_ERODE_ERODE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvErode(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
case MORPHING_METHOD_ERODE_DILATE :
|
||||
cvErode(imgFilteredFrame, imgTemp);
|
||||
cvDilate(imgTemp, imgFilteredFrame);
|
||||
break;
|
||||
}
|
||||
|
||||
if (outputHueMask != NULL)
|
||||
cvCopy(imgFilteredFrame, outputHueMask);
|
||||
if (outputHueMask != NULL)
|
||||
cvCopy(imgFilteredFrame, outputHueMask);
|
||||
};
|
||||
|
||||
|
||||
@@ -195,94 +195,94 @@ void CvAdaptiveSkinDetector::process(IplImage *inputBGRImage, IplImage *outputHu
|
||||
|
||||
CvAdaptiveSkinDetector::Histogram::Histogram()
|
||||
{
|
||||
int histogramSize[] = { HistogramSize };
|
||||
float range[] = { GSD_HUE_LT, GSD_HUE_UT };
|
||||
float *ranges[] = { range };
|
||||
fHistogram = cvCreateHist(1, histogramSize, CV_HIST_ARRAY, ranges, 1);
|
||||
cvClearHist(fHistogram);
|
||||
int histogramSize[] = { HistogramSize };
|
||||
float range[] = { GSD_HUE_LT, GSD_HUE_UT };
|
||||
float *ranges[] = { range };
|
||||
fHistogram = cvCreateHist(1, histogramSize, CV_HIST_ARRAY, ranges, 1);
|
||||
cvClearHist(fHistogram);
|
||||
};
|
||||
|
||||
CvAdaptiveSkinDetector::Histogram::~Histogram()
|
||||
{
|
||||
cvReleaseHist(&fHistogram);
|
||||
cvReleaseHist(&fHistogram);
|
||||
};
|
||||
|
||||
int CvAdaptiveSkinDetector::Histogram::findCoverageIndex(double surfaceToCover, int defaultValue)
|
||||
{
|
||||
double s = 0;
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
s += cvGetReal1D( fHistogram->bins, i );
|
||||
if (s >= surfaceToCover)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
double s = 0;
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
s += cvGetReal1D( fHistogram->bins, i );
|
||||
if (s >= surfaceToCover)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
void CvAdaptiveSkinDetector::Histogram::findCurveThresholds(int &x1, int &x2, double percent)
|
||||
{
|
||||
double sum = 0;
|
||||
double sum = 0;
|
||||
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
sum += cvGetReal1D( fHistogram->bins, i );
|
||||
}
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
sum += cvGetReal1D( fHistogram->bins, i );
|
||||
}
|
||||
|
||||
x1 = findCoverageIndex(sum * percent, -1);
|
||||
x2 = findCoverageIndex(sum * (1-percent), -1);
|
||||
x1 = findCoverageIndex(sum * percent, -1);
|
||||
x2 = findCoverageIndex(sum * (1-percent), -1);
|
||||
|
||||
if (x1 == -1)
|
||||
x1 = GSD_HUE_LT;
|
||||
else
|
||||
x1 += GSD_HUE_LT;
|
||||
if (x1 == -1)
|
||||
x1 = GSD_HUE_LT;
|
||||
else
|
||||
x1 += GSD_HUE_LT;
|
||||
|
||||
if (x2 == -1)
|
||||
x2 = GSD_HUE_UT;
|
||||
else
|
||||
x2 += GSD_HUE_LT;
|
||||
if (x2 == -1)
|
||||
x2 = GSD_HUE_UT;
|
||||
else
|
||||
x2 += GSD_HUE_LT;
|
||||
};
|
||||
|
||||
void CvAdaptiveSkinDetector::Histogram::mergeWith(CvAdaptiveSkinDetector::Histogram *source, double weight)
|
||||
{
|
||||
float myweight = (float)(1-weight);
|
||||
float maxVal1 = 0, maxVal2 = 0, *f1, *f2, ff1, ff2;
|
||||
float myweight = (float)(1-weight);
|
||||
float maxVal1 = 0, maxVal2 = 0, *f1, *f2, ff1, ff2;
|
||||
|
||||
cvGetMinMaxHistValue(source->fHistogram, NULL, &maxVal2);
|
||||
cvGetMinMaxHistValue(source->fHistogram, NULL, &maxVal2);
|
||||
|
||||
if (maxVal2 > 0 )
|
||||
{
|
||||
cvGetMinMaxHistValue(fHistogram, NULL, &maxVal1);
|
||||
if (maxVal1 <= 0)
|
||||
{
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
f1 = (float*)cvPtr1D(fHistogram->bins, i);
|
||||
f2 = (float*)cvPtr1D(source->fHistogram->bins, i);
|
||||
(*f1) = (*f2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
f1 = (float*)cvPtr1D(fHistogram->bins, i);
|
||||
f2 = (float*)cvPtr1D(source->fHistogram->bins, i);
|
||||
if (maxVal2 > 0 )
|
||||
{
|
||||
cvGetMinMaxHistValue(fHistogram, NULL, &maxVal1);
|
||||
if (maxVal1 <= 0)
|
||||
{
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
f1 = (float*)cvPtr1D(fHistogram->bins, i);
|
||||
f2 = (float*)cvPtr1D(source->fHistogram->bins, i);
|
||||
(*f1) = (*f2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < HistogramSize; i++)
|
||||
{
|
||||
f1 = (float*)cvPtr1D(fHistogram->bins, i);
|
||||
f2 = (float*)cvPtr1D(source->fHistogram->bins, i);
|
||||
|
||||
ff1 = ((*f1)/maxVal1)*myweight;
|
||||
if (ff1 < 0)
|
||||
ff1 = -ff1;
|
||||
ff1 = ((*f1)/maxVal1)*myweight;
|
||||
if (ff1 < 0)
|
||||
ff1 = -ff1;
|
||||
|
||||
ff2 = (float)(((*f2)/maxVal2)*weight);
|
||||
if (ff2 < 0)
|
||||
ff2 = -ff2;
|
||||
ff2 = (float)(((*f2)/maxVal2)*weight);
|
||||
if (ff2 < 0)
|
||||
ff2 = -ff2;
|
||||
|
||||
(*f1) = (ff1 + ff2);
|
||||
(*f1) = (ff1 + ff2);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -414,14 +414,14 @@ namespace cv
|
||||
// most simple functions: only perform 1D filtering with output=input (no add on)
|
||||
void _horizontalCausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd);
|
||||
void _horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd); // parallelized with TBB
|
||||
void _verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // parallelized with TBB
|
||||
void _verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd); // parallelized with TBB
|
||||
void _verticalAnticausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
|
||||
|
||||
// perform 1D filtering with output with varrying spatial coefficient
|
||||
void _horizontalCausalFilter_Irregular(float *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(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const float *spatialConstantBuffer); // parallelized with TBB
|
||||
void _verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const float *spatialConstantBuffer); // parallelized with TBB
|
||||
void _horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const float *spatialConstantBuffer); // parallelized with TBB
|
||||
void _verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const float *spatialConstantBuffer); // parallelized with TBB
|
||||
void _verticalAnticausalFilter_Irregular_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd);
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ namespace cv
|
||||
float *outputFrame;
|
||||
unsigned int nbRows, nbColumns;
|
||||
float filterParam_a, filterParam_gain;
|
||||
public:
|
||||
public:
|
||||
Parallel_verticalAnticausalFilter_multGain(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a, const float gain)
|
||||
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a), filterParam_gain(gain){}
|
||||
|
||||
@@ -585,7 +585,7 @@ namespace cv
|
||||
for (register int IDpixel=r.start ; IDpixel!=r.end ; ++IDpixel, ++inputFramePTR, ++outputFramePTR)
|
||||
{
|
||||
float X0=*(localLuminancePTR++)*localLuminanceFactor+localLuminanceAddon;
|
||||
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
|
||||
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
|
||||
*(outputFramePTR) = (maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001f);
|
||||
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
|
||||
}
|
||||
@@ -593,7 +593,7 @@ namespace cv
|
||||
};
|
||||
|
||||
//////////////////////////////////////////
|
||||
/// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors)
|
||||
/// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors)
|
||||
class Parallel_horizontalAnticausalFilter_Irregular: public cv::ParallelLoopBody
|
||||
{
|
||||
private:
|
||||
|
@@ -966,7 +966,7 @@ void ChamferMatcher::Matching::computeDistanceTransform(Mat& edges_img, Mat& dis
|
||||
annotate_img.at<Vec2i>(y,x)[0]=x;
|
||||
annotate_img.at<Vec2i>(y,x)[1]=y;
|
||||
}
|
||||
|
||||
|
||||
uchar edge_val = edges_img.at<uchar>(y,x);
|
||||
if( (edge_val!=0) ) {
|
||||
q.push(std::make_pair(x,y));
|
||||
|
@@ -55,83 +55,83 @@ CvMeanShiftTracker::~CvMeanShiftTracker()
|
||||
|
||||
void CvMeanShiftTracker::newTrackingWindow(Mat image, Rect selection)
|
||||
{
|
||||
hist.release();
|
||||
int channels[] = { 0, 0 , 1, 1};
|
||||
float hrange[] = { 0, 180 };
|
||||
float srange[] = { 0, 1 };
|
||||
const float* ranges[] = {hrange, srange};
|
||||
hist.release();
|
||||
int channels[] = { 0, 0 , 1, 1};
|
||||
float hrange[] = { 0, 180 };
|
||||
float srange[] = { 0, 1 };
|
||||
const float* ranges[] = {hrange, srange};
|
||||
|
||||
cvtColor(image, hsv, CV_BGR2HSV);
|
||||
inRange(hsv, Scalar(0, 30, MIN(10, 256)), Scalar(180, 256, MAX(10, 256)), mask);
|
||||
cvtColor(image, hsv, CV_BGR2HSV);
|
||||
inRange(hsv, Scalar(0, 30, MIN(10, 256)), Scalar(180, 256, MAX(10, 256)), mask);
|
||||
|
||||
hue.create(hsv.size(), CV_8UC2);
|
||||
mixChannels(&hsv, 1, &hue, 1, channels, 2);
|
||||
hue.create(hsv.size(), CV_8UC2);
|
||||
mixChannels(&hsv, 1, &hue, 1, channels, 2);
|
||||
|
||||
Mat roi(hue, selection);
|
||||
Mat mskroi(mask, selection);
|
||||
int ch[] = {0, 1};
|
||||
int chsize[] = {32, 32};
|
||||
calcHist(&roi, 1, ch, mskroi, hist, 1, chsize, ranges);
|
||||
normalize(hist, hist, 0, 255, CV_MINMAX);
|
||||
Mat roi(hue, selection);
|
||||
Mat mskroi(mask, selection);
|
||||
int ch[] = {0, 1};
|
||||
int chsize[] = {32, 32};
|
||||
calcHist(&roi, 1, ch, mskroi, hist, 1, chsize, ranges);
|
||||
normalize(hist, hist, 0, 255, CV_MINMAX);
|
||||
|
||||
prev_trackwindow = selection;
|
||||
prev_trackwindow = selection;
|
||||
}
|
||||
|
||||
RotatedRect CvMeanShiftTracker::updateTrackingWindow(Mat image)
|
||||
{
|
||||
int channels[] = { 0, 0 , 1, 1};
|
||||
float hrange[] = { 0, 180 };
|
||||
float srange[] = { 0, 1 };
|
||||
const float* ranges[] = {hrange, srange};
|
||||
int channels[] = { 0, 0 , 1, 1};
|
||||
float hrange[] = { 0, 180 };
|
||||
float srange[] = { 0, 1 };
|
||||
const float* ranges[] = {hrange, srange};
|
||||
|
||||
cvtColor(image, hsv, CV_BGR2HSV);
|
||||
inRange(hsv, Scalar(0, 30, MIN(10, 256)), Scalar(180, 256, MAX(10, 256)), mask);
|
||||
hue.create(hsv.size(), CV_8UC2);
|
||||
mixChannels(&hsv, 1, &hue, 1, channels, 2);
|
||||
int ch[] = {0, 1};
|
||||
calcBackProject(&hue, 1, ch, hist, backproj, ranges);
|
||||
backproj &= mask;
|
||||
cvtColor(image, hsv, CV_BGR2HSV);
|
||||
inRange(hsv, Scalar(0, 30, MIN(10, 256)), Scalar(180, 256, MAX(10, 256)), mask);
|
||||
hue.create(hsv.size(), CV_8UC2);
|
||||
mixChannels(&hsv, 1, &hue, 1, channels, 2);
|
||||
int ch[] = {0, 1};
|
||||
calcBackProject(&hue, 1, ch, hist, backproj, ranges);
|
||||
backproj &= mask;
|
||||
|
||||
prev_trackbox = CamShift(backproj, prev_trackwindow, TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1));
|
||||
int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
|
||||
prev_trackwindow = Rect(prev_trackwindow.x - r, prev_trackwindow.y - r, prev_trackwindow.x + r,
|
||||
prev_trackwindow.y + r) & Rect(0, 0, cols, rows);
|
||||
prev_trackbox = CamShift(backproj, prev_trackwindow, TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1));
|
||||
int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
|
||||
prev_trackwindow = Rect(prev_trackwindow.x - r, prev_trackwindow.y - r, prev_trackwindow.x + r,
|
||||
prev_trackwindow.y + r) & Rect(0, 0, cols, rows);
|
||||
|
||||
prev_center.x = (float)(prev_trackwindow.x + prev_trackwindow.width / 2);
|
||||
prev_center.y = (float)(prev_trackwindow.y + prev_trackwindow.height / 2);
|
||||
prev_center.x = (float)(prev_trackwindow.x + prev_trackwindow.width / 2);
|
||||
prev_center.y = (float)(prev_trackwindow.y + prev_trackwindow.height / 2);
|
||||
|
||||
#ifdef DEBUG_HYTRACKER
|
||||
ellipse(image, prev_trackbox, Scalar(0, 0, 255), 1, CV_AA);
|
||||
ellipse(image, prev_trackbox, Scalar(0, 0, 255), 1, CV_AA);
|
||||
#endif
|
||||
|
||||
return prev_trackbox;
|
||||
return prev_trackbox;
|
||||
}
|
||||
|
||||
Mat CvMeanShiftTracker::getHistogramProjection(int type)
|
||||
{
|
||||
Mat ms_backproj_f(backproj.size(), type);
|
||||
backproj.convertTo(ms_backproj_f, type);
|
||||
return ms_backproj_f;
|
||||
Mat ms_backproj_f(backproj.size(), type);
|
||||
backproj.convertTo(ms_backproj_f, type);
|
||||
return ms_backproj_f;
|
||||
}
|
||||
|
||||
void CvMeanShiftTracker::setTrackingWindow(Rect window)
|
||||
{
|
||||
prev_trackwindow = window;
|
||||
prev_trackwindow = window;
|
||||
}
|
||||
|
||||
Rect CvMeanShiftTracker::getTrackingWindow()
|
||||
{
|
||||
return prev_trackwindow;
|
||||
return prev_trackwindow;
|
||||
}
|
||||
|
||||
RotatedRect CvMeanShiftTracker::getTrackingEllipse()
|
||||
{
|
||||
return prev_trackbox;
|
||||
return prev_trackbox;
|
||||
}
|
||||
|
||||
Point2f CvMeanShiftTracker::getTrackingCenter()
|
||||
{
|
||||
return prev_center;
|
||||
return prev_center;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -345,7 +345,7 @@ void Eigenfaces::train(InputArrayOfArrays _src, InputArray _local_labels) {
|
||||
Mat labels = _local_labels.getMat();
|
||||
// observations in row
|
||||
Mat data = asRowMatrix(_src, CV_64FC1);
|
||||
|
||||
|
||||
// number of samples
|
||||
int n = data.rows;
|
||||
// assert there are as much samples as labels
|
||||
@@ -359,7 +359,7 @@ void Eigenfaces::train(InputArrayOfArrays _src, InputArray _local_labels) {
|
||||
// clip number of components to be valid
|
||||
if((_num_components <= 0) || (_num_components > n))
|
||||
_num_components = n;
|
||||
|
||||
|
||||
// perform the PCA
|
||||
PCA pca(data, Mat(), CV_PCA_DATA_AS_ROW, _num_components);
|
||||
// copy the PCA results
|
||||
|
@@ -48,18 +48,18 @@
|
||||
using namespace cv;
|
||||
|
||||
CvFeatureTracker::CvFeatureTracker(CvFeatureTrackerParams _params) :
|
||||
params(_params)
|
||||
params(_params)
|
||||
{
|
||||
switch (params.feature_type)
|
||||
{
|
||||
case CvFeatureTrackerParams::SIFT:
|
||||
switch (params.feature_type)
|
||||
{
|
||||
case CvFeatureTrackerParams::SIFT:
|
||||
dd = Algorithm::create<Feature2D>("Feature2D.SIFT");
|
||||
if( dd.empty() )
|
||||
CV_Error(CV_StsNotImplemented, "OpenCV has been compiled without SIFT support");
|
||||
dd->set("nOctaveLayers", 5);
|
||||
dd->set("contrastThreshold", 0.04);
|
||||
dd->set("edgeThreshold", 10.7);
|
||||
case CvFeatureTrackerParams::SURF:
|
||||
case CvFeatureTrackerParams::SURF:
|
||||
dd = Algorithm::create<Feature2D>("Feature2D.SURF");
|
||||
if( dd.empty() )
|
||||
CV_Error(CV_StsNotImplemented, "OpenCV has been compiled without SURF support");
|
||||
@@ -67,10 +67,10 @@ CvFeatureTracker::CvFeatureTracker(CvFeatureTrackerParams _params) :
|
||||
dd->set("nOctaves", 3);
|
||||
dd->set("nOctaveLayers", 4);
|
||||
default:
|
||||
CV_Error(CV_StsBadArg, "Unknown feature type");
|
||||
}
|
||||
CV_Error(CV_StsBadArg, "Unknown feature type");
|
||||
}
|
||||
|
||||
matcher = new BFMatcher(NORM_L2);
|
||||
matcher = new BFMatcher(NORM_L2);
|
||||
}
|
||||
|
||||
CvFeatureTracker::~CvFeatureTracker()
|
||||
@@ -79,143 +79,143 @@ CvFeatureTracker::~CvFeatureTracker()
|
||||
|
||||
void CvFeatureTracker::newTrackingWindow(Mat image, Rect selection)
|
||||
{
|
||||
image.copyTo(prev_image);
|
||||
cvtColor(prev_image, prev_image_bw, CV_BGR2GRAY);
|
||||
prev_trackwindow = selection;
|
||||
prev_center.x = selection.x;
|
||||
prev_center.y = selection.y;
|
||||
ittr = 0;
|
||||
image.copyTo(prev_image);
|
||||
cvtColor(prev_image, prev_image_bw, CV_BGR2GRAY);
|
||||
prev_trackwindow = selection;
|
||||
prev_center.x = selection.x;
|
||||
prev_center.y = selection.y;
|
||||
ittr = 0;
|
||||
}
|
||||
|
||||
Rect CvFeatureTracker::updateTrackingWindow(Mat image)
|
||||
{
|
||||
if(params.feature_type == CvFeatureTrackerParams::OPTICAL_FLOW)
|
||||
return updateTrackingWindowWithFlow(image);
|
||||
else
|
||||
return updateTrackingWindowWithSIFT(image);
|
||||
if(params.feature_type == CvFeatureTrackerParams::OPTICAL_FLOW)
|
||||
return updateTrackingWindowWithFlow(image);
|
||||
else
|
||||
return updateTrackingWindowWithSIFT(image);
|
||||
}
|
||||
|
||||
Rect CvFeatureTracker::updateTrackingWindowWithSIFT(Mat image)
|
||||
{
|
||||
ittr++;
|
||||
vector<KeyPoint> prev_keypoints, curr_keypoints;
|
||||
vector<Point2f> prev_keys, curr_keys;
|
||||
Mat prev_desc, curr_desc;
|
||||
ittr++;
|
||||
vector<KeyPoint> prev_keypoints, curr_keypoints;
|
||||
vector<Point2f> prev_keys, curr_keys;
|
||||
Mat prev_desc, curr_desc;
|
||||
|
||||
Rect window = prev_trackwindow;
|
||||
Mat mask = Mat::zeros(image.size(), CV_8UC1);
|
||||
rectangle(mask, Point(window.x, window.y), Point(window.x + window.width,
|
||||
window.y + window.height), Scalar(255), CV_FILLED);
|
||||
Rect window = prev_trackwindow;
|
||||
Mat mask = Mat::zeros(image.size(), CV_8UC1);
|
||||
rectangle(mask, Point(window.x, window.y), Point(window.x + window.width,
|
||||
window.y + window.height), Scalar(255), CV_FILLED);
|
||||
|
||||
dd->operator()(prev_image, mask, prev_keypoints, prev_desc);
|
||||
dd->operator()(prev_image, mask, prev_keypoints, prev_desc);
|
||||
|
||||
window.x -= params.window_size;
|
||||
window.y -= params.window_size;
|
||||
window.width += params.window_size;
|
||||
window.height += params.window_size;
|
||||
rectangle(mask, Point(window.x, window.y), Point(window.x + window.width,
|
||||
window.y + window.height), Scalar(255), CV_FILLED);
|
||||
window.x -= params.window_size;
|
||||
window.y -= params.window_size;
|
||||
window.width += params.window_size;
|
||||
window.height += params.window_size;
|
||||
rectangle(mask, Point(window.x, window.y), Point(window.x + window.width,
|
||||
window.y + window.height), Scalar(255), CV_FILLED);
|
||||
|
||||
dd->operator()(image, mask, curr_keypoints, curr_desc);
|
||||
dd->operator()(image, mask, curr_keypoints, curr_desc);
|
||||
|
||||
if (prev_keypoints.size() > 4 && curr_keypoints.size() > 4)
|
||||
{
|
||||
//descriptor->compute(prev_image, prev_keypoints, prev_desc);
|
||||
//descriptor->compute(image, curr_keypoints, curr_desc);
|
||||
if (prev_keypoints.size() > 4 && curr_keypoints.size() > 4)
|
||||
{
|
||||
//descriptor->compute(prev_image, prev_keypoints, prev_desc);
|
||||
//descriptor->compute(image, curr_keypoints, curr_desc);
|
||||
|
||||
matcher->match(prev_desc, curr_desc, matches);
|
||||
matcher->match(prev_desc, curr_desc, matches);
|
||||
|
||||
for (int i = 0; i < (int)matches.size(); i++)
|
||||
{
|
||||
prev_keys.push_back(prev_keypoints[matches[i].queryIdx].pt);
|
||||
curr_keys.push_back(curr_keypoints[matches[i].trainIdx].pt);
|
||||
}
|
||||
for (int i = 0; i < (int)matches.size(); i++)
|
||||
{
|
||||
prev_keys.push_back(prev_keypoints[matches[i].queryIdx].pt);
|
||||
curr_keys.push_back(curr_keypoints[matches[i].trainIdx].pt);
|
||||
}
|
||||
|
||||
Mat T = findHomography(prev_keys, curr_keys, CV_LMEDS);
|
||||
Mat T = findHomography(prev_keys, curr_keys, CV_LMEDS);
|
||||
|
||||
prev_trackwindow.x += cvRound(T.at<double> (0, 2));
|
||||
prev_trackwindow.y += cvRound(T.at<double> (1, 2));
|
||||
}
|
||||
prev_trackwindow.x += cvRound(T.at<double> (0, 2));
|
||||
prev_trackwindow.y += cvRound(T.at<double> (1, 2));
|
||||
}
|
||||
|
||||
prev_center.x = prev_trackwindow.x;
|
||||
prev_center.y = prev_trackwindow.y;
|
||||
prev_image = image;
|
||||
return prev_trackwindow;
|
||||
prev_center.x = prev_trackwindow.x;
|
||||
prev_center.y = prev_trackwindow.y;
|
||||
prev_image = image;
|
||||
return prev_trackwindow;
|
||||
}
|
||||
|
||||
Rect CvFeatureTracker::updateTrackingWindowWithFlow(Mat image)
|
||||
{
|
||||
ittr++;
|
||||
Size subPixWinSize(10,10), winSize(31,31);
|
||||
Mat image_bw;
|
||||
TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);
|
||||
vector<uchar> status;
|
||||
vector<float> err;
|
||||
ittr++;
|
||||
Size subPixWinSize(10,10), winSize(31,31);
|
||||
Mat image_bw;
|
||||
TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);
|
||||
vector<uchar> status;
|
||||
vector<float> err;
|
||||
|
||||
cvtColor(image, image_bw, CV_BGR2GRAY);
|
||||
cvtColor(prev_image, prev_image_bw, CV_BGR2GRAY);
|
||||
cvtColor(image, image_bw, CV_BGR2GRAY);
|
||||
cvtColor(prev_image, prev_image_bw, CV_BGR2GRAY);
|
||||
|
||||
if (ittr == 1)
|
||||
{
|
||||
Mat mask = Mat::zeros(image.size(), CV_8UC1);
|
||||
rectangle(mask, Point(prev_trackwindow.x, prev_trackwindow.y), Point(
|
||||
prev_trackwindow.x + prev_trackwindow.width, prev_trackwindow.y
|
||||
+ prev_trackwindow.height), Scalar(255), CV_FILLED);
|
||||
goodFeaturesToTrack(image_bw, features[1], 500, 0.01, 20, mask, 3, 0, 0.04);
|
||||
cornerSubPix(image_bw, features[1], subPixWinSize, Size(-1, -1), termcrit);
|
||||
}
|
||||
else
|
||||
{
|
||||
calcOpticalFlowPyrLK(prev_image_bw, image_bw, features[0], features[1],
|
||||
status, err, winSize, 3, termcrit);
|
||||
if (ittr == 1)
|
||||
{
|
||||
Mat mask = Mat::zeros(image.size(), CV_8UC1);
|
||||
rectangle(mask, Point(prev_trackwindow.x, prev_trackwindow.y), Point(
|
||||
prev_trackwindow.x + prev_trackwindow.width, prev_trackwindow.y
|
||||
+ prev_trackwindow.height), Scalar(255), CV_FILLED);
|
||||
goodFeaturesToTrack(image_bw, features[1], 500, 0.01, 20, mask, 3, 0, 0.04);
|
||||
cornerSubPix(image_bw, features[1], subPixWinSize, Size(-1, -1), termcrit);
|
||||
}
|
||||
else
|
||||
{
|
||||
calcOpticalFlowPyrLK(prev_image_bw, image_bw, features[0], features[1],
|
||||
status, err, winSize, 3, termcrit);
|
||||
|
||||
Point2f feature0_center(0, 0);
|
||||
Point2f feature1_center(0, 0);
|
||||
int goodtracks = 0;
|
||||
for (int i = 0; i < (int)features[1].size(); i++)
|
||||
{
|
||||
if (status[i] == 1)
|
||||
{
|
||||
feature0_center.x += features[0][i].x;
|
||||
feature0_center.y += features[0][i].y;
|
||||
feature1_center.x += features[1][i].x;
|
||||
feature1_center.y += features[1][i].y;
|
||||
goodtracks++;
|
||||
}
|
||||
}
|
||||
Point2f feature0_center(0, 0);
|
||||
Point2f feature1_center(0, 0);
|
||||
int goodtracks = 0;
|
||||
for (int i = 0; i < (int)features[1].size(); i++)
|
||||
{
|
||||
if (status[i] == 1)
|
||||
{
|
||||
feature0_center.x += features[0][i].x;
|
||||
feature0_center.y += features[0][i].y;
|
||||
feature1_center.x += features[1][i].x;
|
||||
feature1_center.y += features[1][i].y;
|
||||
goodtracks++;
|
||||
}
|
||||
}
|
||||
|
||||
feature0_center.x /= goodtracks;
|
||||
feature0_center.y /= goodtracks;
|
||||
feature1_center.x /= goodtracks;
|
||||
feature1_center.y /= goodtracks;
|
||||
feature0_center.x /= goodtracks;
|
||||
feature0_center.y /= goodtracks;
|
||||
feature1_center.x /= goodtracks;
|
||||
feature1_center.y /= goodtracks;
|
||||
|
||||
prev_center.x += (feature1_center.x - feature0_center.x);
|
||||
prev_center.y += (feature1_center.y - feature0_center.y);
|
||||
prev_center.x += (feature1_center.x - feature0_center.x);
|
||||
prev_center.y += (feature1_center.y - feature0_center.y);
|
||||
|
||||
prev_trackwindow.x = (int)prev_center.x;
|
||||
prev_trackwindow.y = (int)prev_center.y;
|
||||
}
|
||||
prev_trackwindow.x = (int)prev_center.x;
|
||||
prev_trackwindow.y = (int)prev_center.y;
|
||||
}
|
||||
|
||||
swap(features[0], features[1]);
|
||||
image.copyTo(prev_image);
|
||||
return prev_trackwindow;
|
||||
swap(features[0], features[1]);
|
||||
image.copyTo(prev_image);
|
||||
return prev_trackwindow;
|
||||
}
|
||||
|
||||
void CvFeatureTracker::setTrackingWindow(Rect _window)
|
||||
{
|
||||
prev_trackwindow = _window;
|
||||
prev_trackwindow = _window;
|
||||
}
|
||||
|
||||
Rect CvFeatureTracker::getTrackingWindow()
|
||||
{
|
||||
return prev_trackwindow;
|
||||
return prev_trackwindow;
|
||||
}
|
||||
|
||||
Point2f CvFeatureTracker::getTrackingCenter()
|
||||
{
|
||||
Point2f center(0, 0);
|
||||
center.x = (float)(prev_center.x + prev_trackwindow.width/2.0);
|
||||
center.y = (float)(prev_center.y + prev_trackwindow.height/2.0);
|
||||
return center;
|
||||
Point2f center(0, 0);
|
||||
center.x = (float)(prev_center.x + prev_trackwindow.width/2.0);
|
||||
center.y = (float)(prev_center.y + prev_trackwindow.height/2.0);
|
||||
return center;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -81,24 +81,24 @@ ImageLogPolProjection::ImageLogPolProjection(const unsigned int nbRows, const un
|
||||
_transformTable(0),
|
||||
_irregularLPfilteredFrame(_filterOutput)
|
||||
{
|
||||
_inputDoubleNBpixels=nbRows*nbColumns*2;
|
||||
_selectedProjection = projection;
|
||||
_reductionFactor=0;
|
||||
_initOK=false;
|
||||
_usefullpixelIndex=0;
|
||||
_colorModeCapable=colorModeCapable;
|
||||
_inputDoubleNBpixels=nbRows*nbColumns*2;
|
||||
_selectedProjection = projection;
|
||||
_reductionFactor=0;
|
||||
_initOK=false;
|
||||
_usefullpixelIndex=0;
|
||||
_colorModeCapable=colorModeCapable;
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::allocating"<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::allocating"<<std::endl;
|
||||
#endif
|
||||
if (_colorModeCapable)
|
||||
{
|
||||
_tempBuffer.resize(nbRows*nbColumns*3);
|
||||
}
|
||||
if (_colorModeCapable)
|
||||
{
|
||||
_tempBuffer.resize(nbRows*nbColumns*3);
|
||||
}
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::done"<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::done"<<std::endl;
|
||||
#endif
|
||||
|
||||
clearAllBuffers();
|
||||
clearAllBuffers();
|
||||
}
|
||||
|
||||
// destructor
|
||||
@@ -111,9 +111,9 @@ ImageLogPolProjection::~ImageLogPolProjection()
|
||||
// reset buffers method
|
||||
void ImageLogPolProjection::clearAllBuffers()
|
||||
{
|
||||
_sampledFrame=0;
|
||||
_tempBuffer=0;
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
_sampledFrame=0;
|
||||
_tempBuffer=0;
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,327 +123,327 @@ void ImageLogPolProjection::clearAllBuffers()
|
||||
*/
|
||||
void ImageLogPolProjection::resize(const unsigned int NBrows, const unsigned int NBcolumns)
|
||||
{
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
initProjection(_reductionFactor, _samplingStrenght);
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
initProjection(_reductionFactor, _samplingStrenght);
|
||||
|
||||
// reset buffers method
|
||||
clearAllBuffers();
|
||||
// reset buffers method
|
||||
clearAllBuffers();
|
||||
|
||||
}
|
||||
|
||||
// init functions depending on the projection type
|
||||
bool ImageLogPolProjection::initProjection(const double reductionFactor, const double samplingStrenght)
|
||||
{
|
||||
switch(_selectedProjection)
|
||||
{
|
||||
case RETINALOGPROJECTION:
|
||||
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
case CORTEXLOGPOLARPROJECTION:
|
||||
return _initLogPolarCortexSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
default:
|
||||
std::cout<<"ImageLogPolProjection::no projection setted up... performing default retina projection... take care"<<std::endl;
|
||||
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
}
|
||||
switch(_selectedProjection)
|
||||
{
|
||||
case RETINALOGPROJECTION:
|
||||
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
case CORTEXLOGPOLARPROJECTION:
|
||||
return _initLogPolarCortexSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
default:
|
||||
std::cout<<"ImageLogPolProjection::no projection setted up... performing default retina projection... take care"<<std::endl;
|
||||
return _initLogRetinaSampling(reductionFactor, samplingStrenght);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -> private init functions dedicated to each projection
|
||||
bool ImageLogPolProjection::_initLogRetinaSampling(const double reductionFactor, const double samplingStrenght)
|
||||
{
|
||||
_initOK=false;
|
||||
_initOK=false;
|
||||
|
||||
if (_selectedProjection!=RETINALOGPROJECTION)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: could not initialize logPolar projection for a log projection system\n -> you probably chose the wrong init function, use initLogPolarCortexSampling() instead"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
if (reductionFactor<1.0)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
if (_selectedProjection!=RETINALOGPROJECTION)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: could not initialize logPolar projection for a log projection system\n -> you probably chose the wrong init function, use initLogPolarCortexSampling() instead"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
if (reductionFactor<1.0)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::initLogRetinaSampling: reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// compute image output size
|
||||
_outputNBrows=predictOutputSize(this->getNBrows(), reductionFactor);
|
||||
_outputNBcolumns=predictOutputSize(this->getNBcolumns(), reductionFactor);
|
||||
_outputNBpixels=_outputNBrows*_outputNBcolumns;
|
||||
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
|
||||
// compute image output size
|
||||
_outputNBrows=predictOutputSize(this->getNBrows(), reductionFactor);
|
||||
_outputNBcolumns=predictOutputSize(this->getNBcolumns(), reductionFactor);
|
||||
_outputNBpixels=_outputNBrows*_outputNBcolumns;
|
||||
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image resampling factor: "<<reductionFactor<<", strenght:"<<samplingStrenght<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image resampling factor: "<<reductionFactor<<", strenght:"<<samplingStrenght<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
|
||||
#endif
|
||||
|
||||
// setup progressive prefilter that will be applied BEFORE log sampling
|
||||
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
|
||||
// setup progressive prefilter that will be applied BEFORE log sampling
|
||||
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
|
||||
|
||||
// (re)create the image output buffer and transform table if the reduction factor changed
|
||||
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
|
||||
// (re)create the image output buffer and transform table if the reduction factor changed
|
||||
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
|
||||
|
||||
// specifiying new reduction factor after preliminar checks
|
||||
_reductionFactor=reductionFactor;
|
||||
_samplingStrenght=samplingStrenght;
|
||||
// specifiying new reduction factor after preliminar checks
|
||||
_reductionFactor=reductionFactor;
|
||||
_samplingStrenght=samplingStrenght;
|
||||
|
||||
// compute the rlim for symetric rows/columns sampling, then, the rlim is based on the smallest dimension
|
||||
_minDimension=(double)(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
|
||||
// compute the rlim for symetric rows/columns sampling, then, the rlim is based on the smallest dimension
|
||||
_minDimension=(double)(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
|
||||
|
||||
// input frame dimensions dependent log sampling:
|
||||
//double rlim=1.0/reductionFactor*(minDimension/2.0+samplingStrenght);
|
||||
// input frame dimensions dependent log sampling:
|
||||
//double rlim=1.0/reductionFactor*(minDimension/2.0+samplingStrenght);
|
||||
|
||||
// input frame dimensions INdependent log sampling:
|
||||
_azero=(1.0+reductionFactor*sqrt(samplingStrenght))/(reductionFactor*reductionFactor*samplingStrenght-1.0);
|
||||
_alim=(1.0+_azero)/reductionFactor;
|
||||
// input frame dimensions INdependent log sampling:
|
||||
_azero=(1.0+reductionFactor*sqrt(samplingStrenght))/(reductionFactor*reductionFactor*samplingStrenght-1.0);
|
||||
_alim=(1.0+_azero)/reductionFactor;
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: rlim= "<<rlim<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: alim= "<<alim<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: rlim= "<<rlim<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: alim= "<<alim<<std::endl;
|
||||
#endif
|
||||
|
||||
// get half frame size
|
||||
unsigned int halfOutputRows = _outputNBrows/2-1;
|
||||
unsigned int halfOutputColumns = _outputNBcolumns/2-1;
|
||||
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
|
||||
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
|
||||
// get half frame size
|
||||
unsigned int halfOutputRows = _outputNBrows/2-1;
|
||||
unsigned int halfOutputColumns = _outputNBcolumns/2-1;
|
||||
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
|
||||
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
|
||||
|
||||
// computing log sampling matrix by computing quarters of images
|
||||
// the original new image center (_filterOutput.getNBrows()/2, _filterOutput.getNBcolumns()/2) being at coordinate (_filterOutput.getNBrows()/(2*_reductionFactor), _filterOutput.getNBcolumns()/(2*_reductionFactor))
|
||||
// computing log sampling matrix by computing quarters of images
|
||||
// the original new image center (_filterOutput.getNBrows()/2, _filterOutput.getNBcolumns()/2) being at coordinate (_filterOutput.getNBrows()/(2*_reductionFactor), _filterOutput.getNBcolumns()/(2*_reductionFactor))
|
||||
|
||||
// -> use a temporary transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
|
||||
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
|
||||
_usefullpixelIndex=0;
|
||||
// -> use a temporary transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
|
||||
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
|
||||
_usefullpixelIndex=0;
|
||||
|
||||
double rMax=0;
|
||||
halfInputRows<halfInputColumns ? rMax=(double)(halfInputRows*halfInputRows):rMax=(double)(halfInputColumns*halfInputColumns);
|
||||
double rMax=0;
|
||||
halfInputRows<halfInputColumns ? rMax=(double)(halfInputRows*halfInputRows):rMax=(double)(halfInputColumns*halfInputColumns);
|
||||
|
||||
for (unsigned int idRow=0;idRow<halfOutputRows; ++idRow)
|
||||
{
|
||||
for (unsigned int idColumn=0;idColumn<halfOutputColumns; ++idColumn)
|
||||
{
|
||||
// get the pixel position in the original picture
|
||||
for (unsigned int idRow=0;idRow<halfOutputRows; ++idRow)
|
||||
{
|
||||
for (unsigned int idColumn=0;idColumn<halfOutputColumns; ++idColumn)
|
||||
{
|
||||
// get the pixel position in the original picture
|
||||
|
||||
// -> input frame dimensions dependent log sampling:
|
||||
//double scale = samplingStrenght/(rlim-(double)sqrt(idRow*idRow+idColumn*idColumn));
|
||||
// -> input frame dimensions dependent log sampling:
|
||||
//double scale = samplingStrenght/(rlim-(double)sqrt(idRow*idRow+idColumn*idColumn));
|
||||
|
||||
// -> input frame dimensions INdependent log sampling:
|
||||
double scale=getOriginalRadiusLength((double)sqrt((double)(idRow*idRow+idColumn*idColumn)));
|
||||
// -> input frame dimensions INdependent log sampling:
|
||||
double scale=getOriginalRadiusLength((double)sqrt((double)(idRow*idRow+idColumn*idColumn)));
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale2= "<<scale2<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale2= "<<scale2<<std::endl;
|
||||
#endif
|
||||
if (scale < 0) ///check it later
|
||||
scale = 10000;
|
||||
if (scale < 0) ///check it later
|
||||
scale = 10000;
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
// std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
|
||||
// std::cout<<"ImageLogPolProjection::initLogRetinaSampling: scale= "<<scale<<std::endl;
|
||||
#endif
|
||||
|
||||
unsigned int u=(unsigned int)floor((double)idRow*scale);
|
||||
unsigned int v=(unsigned int)floor((double)idColumn*scale);
|
||||
unsigned int u=(unsigned int)floor((double)idRow*scale);
|
||||
unsigned int v=(unsigned int)floor((double)idColumn*scale);
|
||||
|
||||
// manage border effects
|
||||
double length=u*u+v*v;
|
||||
double radiusRatio=sqrt(rMax/length);
|
||||
// manage border effects
|
||||
double length=u*u+v*v;
|
||||
double radiusRatio=sqrt(rMax/length);
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::(inputH, inputW)="<<halfInputRows<<", "<<halfInputColumns<<", Rmax2="<<rMax<<std::endl;
|
||||
std::cout<<"before ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
|
||||
std::cout<<"ratio ="<<radiusRatio<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::(inputH, inputW)="<<halfInputRows<<", "<<halfInputColumns<<", Rmax2="<<rMax<<std::endl;
|
||||
std::cout<<"before ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
|
||||
std::cout<<"ratio ="<<radiusRatio<<std::endl;
|
||||
#endif
|
||||
|
||||
if (radiusRatio < 1.0)
|
||||
{
|
||||
u=(unsigned int)floor(radiusRatio*double(u));
|
||||
v=(unsigned int)floor(radiusRatio*double(v));
|
||||
}
|
||||
if (radiusRatio < 1.0)
|
||||
{
|
||||
u=(unsigned int)floor(radiusRatio*double(u));
|
||||
v=(unsigned int)floor(radiusRatio*double(v));
|
||||
}
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"after ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::("<<(halfOutputRows-idRow)<<", "<<idColumn+halfOutputColumns<<") <- ("<<halfInputRows-u<<", "<<v+halfInputColumns<<")"<<std::endl;
|
||||
std::cout<<(halfOutputRows-idRow)+(halfOutputColumns+idColumn)*_outputNBrows<<" -> "<<(halfInputRows-u)+_filterOutput.getNBrows()*(halfInputColumns+v)<<std::endl;
|
||||
std::cout<<"after ==> ImageLogPolProjection::(u, v)="<<u<<", "<<v<<", r="<<u*u+v*v<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::("<<(halfOutputRows-idRow)<<", "<<idColumn+halfOutputColumns<<") <- ("<<halfInputRows-u<<", "<<v+halfInputColumns<<")"<<std::endl;
|
||||
std::cout<<(halfOutputRows-idRow)+(halfOutputColumns+idColumn)*_outputNBrows<<" -> "<<(halfInputRows-u)+_filterOutput.getNBrows()*(halfInputColumns+v)<<std::endl;
|
||||
#endif
|
||||
|
||||
if ((u<halfInputRows)&&(v<halfInputColumns))
|
||||
{
|
||||
if ((u<halfInputRows)&&(v<halfInputColumns))
|
||||
{
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"*** VALID ***"<<std::endl;
|
||||
std::cout<<"*** VALID ***"<<std::endl;
|
||||
#endif
|
||||
|
||||
// set pixel coordinate of the input picture in the transform table at the current log sampled pixel
|
||||
// 1st quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns+v);
|
||||
// 2nd quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns+v);
|
||||
// 3rd quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns-v);
|
||||
// 4td quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns-v);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set pixel coordinate of the input picture in the transform table at the current log sampled pixel
|
||||
// 1st quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns+v);
|
||||
// 2nd quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns+idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns+v);
|
||||
// 3rd quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows-idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows-u)+(halfInputColumns-v);
|
||||
// 4td quadrant
|
||||
tempTransformTable[_usefullpixelIndex++]=(halfOutputColumns-idColumn)+(halfOutputRows+idRow)*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]=_filterOutput.getNBcolumns()*(halfInputRows+u)+(halfInputColumns-v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (re)creating and filling the transform table
|
||||
_transformTable.resize(_usefullpixelIndex);
|
||||
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
|
||||
// (re)creating and filling the transform table
|
||||
_transformTable.resize(_usefullpixelIndex);
|
||||
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
|
||||
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: init done successfully"<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::initLogRetinaSampling: init done successfully"<<std::endl;
|
||||
#endif
|
||||
_initOK=true;
|
||||
return _initOK;
|
||||
_initOK=true;
|
||||
return _initOK;
|
||||
}
|
||||
|
||||
bool ImageLogPolProjection::_initLogPolarCortexSampling(const double reductionFactor, const double)
|
||||
{
|
||||
_initOK=false;
|
||||
_initOK=false;
|
||||
|
||||
if (_selectedProjection!=CORTEXLOGPOLARPROJECTION)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::could not initialize log projection for a logPolar projection system\n -> you probably chose the wrong init function, use initLogRetinaSampling() instead"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
if (_selectedProjection!=CORTEXLOGPOLARPROJECTION)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::could not initialize log projection for a logPolar projection system\n -> you probably chose the wrong init function, use initLogRetinaSampling() instead"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reductionFactor<1.0)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
if (reductionFactor<1.0)
|
||||
{
|
||||
std::cerr<<"ImageLogPolProjection::reduction factor must be superior to 0, skeeping initialisation..."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// compute the smallest image size
|
||||
unsigned int minDimension=(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
|
||||
// specifiying new reduction factor after preliminar checks
|
||||
_reductionFactor=reductionFactor;
|
||||
// compute image output size
|
||||
_outputNBrows=(unsigned int)((double)minDimension/reductionFactor);
|
||||
_outputNBcolumns=(unsigned int)((double)minDimension/reductionFactor);
|
||||
_outputNBpixels=_outputNBrows*_outputNBcolumns;
|
||||
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
|
||||
// compute the smallest image size
|
||||
unsigned int minDimension=(_filterOutput.getNBrows() < _filterOutput.getNBcolumns() ? _filterOutput.getNBrows() : _filterOutput.getNBcolumns());
|
||||
// specifiying new reduction factor after preliminar checks
|
||||
_reductionFactor=reductionFactor;
|
||||
// compute image output size
|
||||
_outputNBrows=(unsigned int)((double)minDimension/reductionFactor);
|
||||
_outputNBcolumns=(unsigned int)((double)minDimension/reductionFactor);
|
||||
_outputNBpixels=_outputNBrows*_outputNBcolumns;
|
||||
_outputDoubleNBpixels=_outputNBrows*_outputNBcolumns*2;
|
||||
|
||||
// get half frame size
|
||||
//unsigned int halfOutputRows = _outputNBrows/2-1;
|
||||
//unsigned int halfOutputColumns = _outputNBcolumns/2-1;
|
||||
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
|
||||
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
|
||||
// get half frame size
|
||||
//unsigned int halfOutputRows = _outputNBrows/2-1;
|
||||
//unsigned int halfOutputColumns = _outputNBcolumns/2-1;
|
||||
unsigned int halfInputRows = _filterOutput.getNBrows()/2-1;
|
||||
unsigned int halfInputColumns = _filterOutput.getNBcolumns()/2-1;
|
||||
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::Log resampled image size: "<<_outputNBrows<<"*"<<_outputNBcolumns<<std::endl;
|
||||
#endif
|
||||
|
||||
// setup progressive prefilter that will be applied BEFORE log sampling
|
||||
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
|
||||
// setup progressive prefilter that will be applied BEFORE log sampling
|
||||
setProgressiveFilterConstants_CentredAccuracy(0.f, 0.f, 0.99f);
|
||||
|
||||
// (re)create the image output buffer and transform table if the reduction factor changed
|
||||
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
|
||||
// (re)create the image output buffer and transform table if the reduction factor changed
|
||||
_sampledFrame.resize(_outputNBpixels*(1+(unsigned int)_colorModeCapable*2));
|
||||
|
||||
// create the radius and orientation axis and fill them, radius E [0;1], orientation E[-pi, pi]
|
||||
std::valarray<double> radiusAxis(_outputNBcolumns);
|
||||
double radiusStep=2.30/(double)_outputNBcolumns;
|
||||
for (unsigned int i=0;i<_outputNBcolumns;++i)
|
||||
{
|
||||
radiusAxis[i]=i*radiusStep;
|
||||
}
|
||||
std::valarray<double> orientationAxis(_outputNBrows);
|
||||
double orientationStep=-2.0*CV_PI/(double)_outputNBrows;
|
||||
for (unsigned int io=0;io<_outputNBrows;++io)
|
||||
{
|
||||
orientationAxis[io]=io*orientationStep;
|
||||
}
|
||||
// -> use a temporay transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
|
||||
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
|
||||
_usefullpixelIndex=0;
|
||||
// create the radius and orientation axis and fill them, radius E [0;1], orientation E[-pi, pi]
|
||||
std::valarray<double> radiusAxis(_outputNBcolumns);
|
||||
double radiusStep=2.30/(double)_outputNBcolumns;
|
||||
for (unsigned int i=0;i<_outputNBcolumns;++i)
|
||||
{
|
||||
radiusAxis[i]=i*radiusStep;
|
||||
}
|
||||
std::valarray<double> orientationAxis(_outputNBrows);
|
||||
double orientationStep=-2.0*CV_PI/(double)_outputNBrows;
|
||||
for (unsigned int io=0;io<_outputNBrows;++io)
|
||||
{
|
||||
orientationAxis[io]=io*orientationStep;
|
||||
}
|
||||
// -> use a temporay transform table which is bigger than the final one, we only report pixels coordinates that are included in the sampled picture
|
||||
std::valarray<unsigned int> tempTransformTable(2*_outputNBpixels); // the structure would be: (pixelInputCoordinate n)(pixelOutputCoordinate n)(pixelInputCoordinate n+1)(pixelOutputCoordinate n+1)
|
||||
_usefullpixelIndex=0;
|
||||
|
||||
//std::cout<<"ImageLogPolProjection::Starting cortex projection"<<std::endl;
|
||||
// compute transformation, get theta and Radius in reagrd of the output sampled pixel
|
||||
double diagonalLenght=sqrt((double)(_outputNBcolumns*_outputNBcolumns+_outputNBrows*_outputNBrows));
|
||||
for (unsigned int radiusIndex=0;radiusIndex<_outputNBcolumns;++radiusIndex)
|
||||
for(unsigned int orientationIndex=0;orientationIndex<_outputNBrows;++orientationIndex)
|
||||
{
|
||||
double x=1.0+sinh(radiusAxis[radiusIndex])*cos(orientationAxis[orientationIndex]);
|
||||
double y=sinh(radiusAxis[radiusIndex])*sin(orientationAxis[orientationIndex]);
|
||||
// get the input picture coordinate
|
||||
double R=diagonalLenght*sqrt(x*x+y*y)/(5.0+sqrt(x*x+y*y));
|
||||
double theta=atan2(y,x);
|
||||
// convert input polar coord into cartesian/C compatble coordinate
|
||||
unsigned int columnIndex=(unsigned int)(cos(theta)*R)+halfInputColumns;
|
||||
unsigned int rowIndex=(unsigned int)(sin(theta)*R)+halfInputRows;
|
||||
//std::cout<<"ImageLogPolProjection::R="<<R<<" / Theta="<<theta<<" / (x, y)="<<columnIndex<<", "<<rowIndex<<std::endl;
|
||||
if ((columnIndex<_filterOutput.getNBcolumns())&&(columnIndex>0)&&(rowIndex<_filterOutput.getNBrows())&&(rowIndex>0))
|
||||
{
|
||||
// set coordinate
|
||||
tempTransformTable[_usefullpixelIndex++]=radiusIndex+orientationIndex*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]= columnIndex+rowIndex*_filterOutput.getNBcolumns();
|
||||
}
|
||||
}
|
||||
//std::cout<<"ImageLogPolProjection::Starting cortex projection"<<std::endl;
|
||||
// compute transformation, get theta and Radius in reagrd of the output sampled pixel
|
||||
double diagonalLenght=sqrt((double)(_outputNBcolumns*_outputNBcolumns+_outputNBrows*_outputNBrows));
|
||||
for (unsigned int radiusIndex=0;radiusIndex<_outputNBcolumns;++radiusIndex)
|
||||
for(unsigned int orientationIndex=0;orientationIndex<_outputNBrows;++orientationIndex)
|
||||
{
|
||||
double x=1.0+sinh(radiusAxis[radiusIndex])*cos(orientationAxis[orientationIndex]);
|
||||
double y=sinh(radiusAxis[radiusIndex])*sin(orientationAxis[orientationIndex]);
|
||||
// get the input picture coordinate
|
||||
double R=diagonalLenght*sqrt(x*x+y*y)/(5.0+sqrt(x*x+y*y));
|
||||
double theta=atan2(y,x);
|
||||
// convert input polar coord into cartesian/C compatble coordinate
|
||||
unsigned int columnIndex=(unsigned int)(cos(theta)*R)+halfInputColumns;
|
||||
unsigned int rowIndex=(unsigned int)(sin(theta)*R)+halfInputRows;
|
||||
//std::cout<<"ImageLogPolProjection::R="<<R<<" / Theta="<<theta<<" / (x, y)="<<columnIndex<<", "<<rowIndex<<std::endl;
|
||||
if ((columnIndex<_filterOutput.getNBcolumns())&&(columnIndex>0)&&(rowIndex<_filterOutput.getNBrows())&&(rowIndex>0))
|
||||
{
|
||||
// set coordinate
|
||||
tempTransformTable[_usefullpixelIndex++]=radiusIndex+orientationIndex*_outputNBcolumns;
|
||||
tempTransformTable[_usefullpixelIndex++]= columnIndex+rowIndex*_filterOutput.getNBcolumns();
|
||||
}
|
||||
}
|
||||
|
||||
// (re)creating and filling the transform table
|
||||
_transformTable.resize(_usefullpixelIndex);
|
||||
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
|
||||
// (re)creating and filling the transform table
|
||||
_transformTable.resize(_usefullpixelIndex);
|
||||
memcpy(&_transformTable[0], &tempTransformTable[0], sizeof(unsigned int)*_usefullpixelIndex);
|
||||
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
_initOK=true;
|
||||
return true;
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
_initOK=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// action function
|
||||
std::valarray<float> &ImageLogPolProjection::runProjection(const std::valarray<float> &inputFrame, const bool colorMode)
|
||||
{
|
||||
if (_colorModeCapable&&colorMode)
|
||||
{
|
||||
// progressive filtering and storage of the result in _tempBuffer
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]); // warning, temporal issue may occur, if the temporal constant is not NULL !!!
|
||||
if (_colorModeCapable&&colorMode)
|
||||
{
|
||||
// progressive filtering and storage of the result in _tempBuffer
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]); // warning, temporal issue may occur, if the temporal constant is not NULL !!!
|
||||
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels(), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels());
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels(), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels());
|
||||
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels()*2, &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels()*2);
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame)+_filterOutput.getNBpixels()*2, &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_tempBuffer[0]+_filterOutput.getNBpixels()*2);
|
||||
|
||||
// applying image projection/resampling
|
||||
register unsigned int *transformTablePTR=&_transformTable[0];
|
||||
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
|
||||
{
|
||||
// applying image projection/resampling
|
||||
register unsigned int *transformTablePTR=&_transformTable[0];
|
||||
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
|
||||
{
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
|
||||
#endif
|
||||
_sampledFrame[*(transformTablePTR)]=_tempBuffer[*(transformTablePTR+1)];
|
||||
_sampledFrame[*(transformTablePTR)+_outputNBpixels]=_tempBuffer[*(transformTablePTR+1)+_filterOutput.getNBpixels()];
|
||||
_sampledFrame[*(transformTablePTR)+_outputDoubleNBpixels]=_tempBuffer[*(transformTablePTR+1)+_inputDoubleNBpixels];
|
||||
}
|
||||
_sampledFrame[*(transformTablePTR)]=_tempBuffer[*(transformTablePTR+1)];
|
||||
_sampledFrame[*(transformTablePTR)+_outputNBpixels]=_tempBuffer[*(transformTablePTR+1)+_filterOutput.getNBpixels()];
|
||||
_sampledFrame[*(transformTablePTR)+_outputDoubleNBpixels]=_tempBuffer[*(transformTablePTR+1)+_inputDoubleNBpixels];
|
||||
}
|
||||
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::runProjection: color image projection OK"<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::runProjection: color image projection OK"<<std::endl;
|
||||
#endif
|
||||
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
|
||||
}else
|
||||
{
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_irregularLPfilteredFrame[0]);
|
||||
// applying image projection/resampling
|
||||
register unsigned int *transformTablePTR=&_transformTable[0];
|
||||
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
|
||||
{
|
||||
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
|
||||
}else
|
||||
{
|
||||
_spatiotemporalLPfilter_Irregular(get_data(inputFrame), &_irregularLPfilteredFrame[0]);
|
||||
_spatiotemporalLPfilter_Irregular(&_irregularLPfilteredFrame[0], &_irregularLPfilteredFrame[0]);
|
||||
// applying image projection/resampling
|
||||
register unsigned int *transformTablePTR=&_transformTable[0];
|
||||
for (unsigned int i=0 ; i<_usefullpixelIndex ; i+=2, transformTablePTR+=2)
|
||||
{
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
|
||||
std::cout<<"i:"<<i<<"output(max="<<_outputNBpixels<<")="<<_transformTable[i]<<" / intput(max="<<_filterOutput.getNBpixels()<<")="<<_transformTable[i+1]<<std::endl;
|
||||
#endif
|
||||
_sampledFrame[*(transformTablePTR)]=_irregularLPfilteredFrame[*(transformTablePTR+1)];
|
||||
}
|
||||
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
|
||||
_sampledFrame[*(transformTablePTR)]=_irregularLPfilteredFrame[*(transformTablePTR+1)];
|
||||
}
|
||||
//normalizeGrayOutput_0_maxOutputValue(_sampledFrame, _outputNBpixels);
|
||||
#ifdef IMAGELOGPOLPROJECTION_DEBUG
|
||||
std::cout<<"ImageLogPolProjection::runProjection: gray level image projection OK"<<std::endl;
|
||||
std::cout<<"ImageLogPolProjection::runProjection: gray level image projection OK"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return _sampledFrame;
|
||||
return _sampledFrame;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,148 +1,148 @@
|
||||
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
std::vector<std::string> Directory::GetListFiles( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
list.clear();
|
||||
std::string path_f = path + "/" + exten;
|
||||
#ifdef WIN32
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
|
||||
hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_HIDDEN ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)
|
||||
{
|
||||
if (addPath)
|
||||
list.push_back(path + "/" + FindFileData.cFileName);
|
||||
else
|
||||
list.push_back(FindFileData.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(hFind, &FindFileData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
#else
|
||||
(void)addPath;
|
||||
DIR *dp;
|
||||
struct dirent *dirp;
|
||||
if((dp = opendir(path.c_str())) == NULL)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
while ((dirp = readdir(dp)) != NULL)
|
||||
{
|
||||
if (dirp->d_type == DT_REG)
|
||||
{
|
||||
if (exten.compare("*") == 0)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
else
|
||||
if (std::string(dirp->d_name).find(exten) != std::string::npos)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<std::string> Directory::GetListFolders( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
std::string path_f = path + "/" + exten;
|
||||
list.clear();
|
||||
#ifdef WIN32
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
|
||||
hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
|
||||
strcmp(FindFileData.cFileName, ".") != 0 &&
|
||||
strcmp(FindFileData.cFileName, "..") != 0)
|
||||
{
|
||||
if (addPath)
|
||||
list.push_back(path + "/" + FindFileData.cFileName);
|
||||
else
|
||||
list.push_back(FindFileData.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(hFind, &FindFileData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
#else
|
||||
(void)addPath;
|
||||
DIR *dp;
|
||||
struct dirent *dirp;
|
||||
if((dp = opendir(path_f.c_str())) == NULL)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
while ((dirp = readdir(dp)) != NULL)
|
||||
{
|
||||
if (dirp->d_type == DT_DIR &&
|
||||
strcmp(dirp->d_name, ".") != 0 &&
|
||||
strcmp(dirp->d_name, "..") != 0 )
|
||||
{
|
||||
if (exten.compare("*") == 0)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
else
|
||||
if (std::string(dirp->d_name).find(exten) != std::string::npos)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<std::string> Directory::GetListFilesR ( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list = Directory::GetListFiles(path, exten, addPath);
|
||||
|
||||
std::vector<std::string> dirs = Directory::GetListFolders(path, exten, addPath);
|
||||
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = dirs.begin(); it != dirs.end(); ++it)
|
||||
{
|
||||
std::vector<std::string> cl = Directory::GetListFiles(*it, exten, addPath);
|
||||
list.insert(list.end(), cl.begin(), cl.end());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
std::vector<std::string> Directory::GetListFiles( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
list.clear();
|
||||
std::string path_f = path + "/" + exten;
|
||||
#ifdef WIN32
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
|
||||
hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_HIDDEN ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM ||
|
||||
FindFileData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)
|
||||
{
|
||||
if (addPath)
|
||||
list.push_back(path + "/" + FindFileData.cFileName);
|
||||
else
|
||||
list.push_back(FindFileData.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(hFind, &FindFileData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
#else
|
||||
(void)addPath;
|
||||
DIR *dp;
|
||||
struct dirent *dirp;
|
||||
if((dp = opendir(path.c_str())) == NULL)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
while ((dirp = readdir(dp)) != NULL)
|
||||
{
|
||||
if (dirp->d_type == DT_REG)
|
||||
{
|
||||
if (exten.compare("*") == 0)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
else
|
||||
if (std::string(dirp->d_name).find(exten) != std::string::npos)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<std::string> Directory::GetListFolders( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
std::string path_f = path + "/" + exten;
|
||||
list.clear();
|
||||
#ifdef WIN32
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
|
||||
hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
|
||||
strcmp(FindFileData.cFileName, ".") != 0 &&
|
||||
strcmp(FindFileData.cFileName, "..") != 0)
|
||||
{
|
||||
if (addPath)
|
||||
list.push_back(path + "/" + FindFileData.cFileName);
|
||||
else
|
||||
list.push_back(FindFileData.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(hFind, &FindFileData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
#else
|
||||
(void)addPath;
|
||||
DIR *dp;
|
||||
struct dirent *dirp;
|
||||
if((dp = opendir(path_f.c_str())) == NULL)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
while ((dirp = readdir(dp)) != NULL)
|
||||
{
|
||||
if (dirp->d_type == DT_DIR &&
|
||||
strcmp(dirp->d_name, ".") != 0 &&
|
||||
strcmp(dirp->d_name, "..") != 0 )
|
||||
{
|
||||
if (exten.compare("*") == 0)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
else
|
||||
if (std::string(dirp->d_name).find(exten) != std::string::npos)
|
||||
list.push_back(static_cast<std::string>(dirp->d_name));
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<std::string> Directory::GetListFilesR ( const std::string& path, const std::string & exten, bool addPath )
|
||||
{
|
||||
std::vector<std::string> list = Directory::GetListFiles(path, exten, addPath);
|
||||
|
||||
std::vector<std::string> dirs = Directory::GetListFolders(path, exten, addPath);
|
||||
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = dirs.begin(); it != dirs.end(); ++it)
|
||||
{
|
||||
std::vector<std::string> cl = Directory::GetListFiles(*it, exten, addPath);
|
||||
list.insert(list.end(), cl.begin(), cl.end());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -47,8 +47,8 @@ static Mat argsort(InputArray _src, bool ascending=true)
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
if (src.rows != 1 && src.cols != 1) {
|
||||
string error_message = "Wrong shape of input matrix! Expected a matrix with one row or column.";
|
||||
CV_Error(CV_StsBadArg, error_message);
|
||||
string error_message = "Wrong shape of input matrix! Expected a matrix with one row or column.";
|
||||
CV_Error(CV_StsBadArg, error_message);
|
||||
}
|
||||
int flags = CV_SORT_EVERY_ROW+(ascending ? CV_SORT_ASCENDING : CV_SORT_DESCENDING);
|
||||
Mat sorted_indices;
|
||||
@@ -59,7 +59,7 @@ static Mat argsort(InputArray _src, bool ascending=true)
|
||||
static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) {
|
||||
// make sure the input data is a vector of matrices or vector of vector
|
||||
if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) {
|
||||
string error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >).";
|
||||
string error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >).";
|
||||
CV_Error(CV_StsBadArg, error_message);
|
||||
}
|
||||
// number of samples
|
||||
@@ -197,10 +197,10 @@ Mat subspaceProject(InputArray _W, InputArray _mean, InputArray _src) {
|
||||
src.convertTo(X, W.type());
|
||||
// safe to do, because of above assertion
|
||||
if(!mean.empty()) {
|
||||
for(int i=0; i<n; i++) {
|
||||
Mat r_i = X.row(i);
|
||||
subtract(r_i, mean.reshape(1,1), r_i);
|
||||
}
|
||||
for(int i=0; i<n; i++) {
|
||||
Mat r_i = X.row(i);
|
||||
subtract(r_i, mean.reshape(1,1), r_i);
|
||||
}
|
||||
}
|
||||
// finally calculate projection as Y = (X-mean)*W
|
||||
gemm(X, W, 1.0, Mat(), 0.0, Y);
|
||||
@@ -237,10 +237,10 @@ Mat subspaceReconstruct(InputArray _W, InputArray _mean, InputArray _src)
|
||||
gemm(Y, W, 1.0, Mat(), 0.0, X, GEMM_2_T);
|
||||
// safe to do because of above assertion
|
||||
if(!mean.empty()) {
|
||||
for(int i=0; i<n; i++) {
|
||||
Mat r_i = X.row(i);
|
||||
add(r_i, mean.reshape(1,1), r_i);
|
||||
}
|
||||
for(int i=0; i<n; i++) {
|
||||
Mat r_i = X.row(i);
|
||||
add(r_i, mean.reshape(1,1), r_i);
|
||||
}
|
||||
}
|
||||
return X;
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
|
||||
// warn if within-classes scatter matrix becomes singular
|
||||
if (N < D) {
|
||||
cout << "Warning: Less observations than feature dimension given!"
|
||||
<< "Computation will probably fail."
|
||||
<< "Computation will probably fail."
|
||||
<< endl;
|
||||
}
|
||||
// clip number of components to be a valid number
|
||||
@@ -1094,7 +1094,7 @@ void LDA::compute(InputArrayOfArrays _src, InputArray _lbls) {
|
||||
lda(_src.getMat(), _lbls);
|
||||
break;
|
||||
default:
|
||||
string error_message= format("InputArray Datatype %d is not supported.", _src.kind());
|
||||
string error_message= format("InputArray Datatype %d is not supported.", _src.kind());
|
||||
CV_Error(CV_StsBadArg, error_message);
|
||||
break;
|
||||
}
|
||||
|
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -84,36 +84,36 @@ MagnoRetinaFilter::MagnoRetinaFilter(const unsigned int NBrows, const unsigned i
|
||||
_localProcessBufferON(NBrows*NBcolumns),
|
||||
_localProcessBufferOFF(NBrows*NBcolumns)
|
||||
{
|
||||
_magnoYOutput=&_filterOutput;
|
||||
_magnoYsaturated=&_localBuffer;
|
||||
_magnoYOutput=&_filterOutput;
|
||||
_magnoYsaturated=&_localBuffer;
|
||||
|
||||
|
||||
clearAllBuffers();
|
||||
clearAllBuffers();
|
||||
|
||||
#ifdef IPL_RETINA_ELEMENT_DEBUG
|
||||
std::cout<<"MagnoRetinaFilter::Init IPL retina filter at specified frame size OK"<<std::endl;
|
||||
std::cout<<"MagnoRetinaFilter::Init IPL retina filter at specified frame size OK"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
MagnoRetinaFilter::~MagnoRetinaFilter()
|
||||
{
|
||||
#ifdef IPL_RETINA_ELEMENT_DEBUG
|
||||
std::cout<<"MagnoRetinaFilter::Delete IPL retina filter OK"<<std::endl;
|
||||
std::cout<<"MagnoRetinaFilter::Delete IPL retina filter OK"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// function that clears all buffers of the object
|
||||
void MagnoRetinaFilter::clearAllBuffers()
|
||||
{
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
_previousInput_ON=0;
|
||||
_previousInput_OFF=0;
|
||||
_amacrinCellsTempOutput_ON=0;
|
||||
_amacrinCellsTempOutput_OFF=0;
|
||||
_magnoXOutputON=0;
|
||||
_magnoXOutputOFF=0;
|
||||
_localProcessBufferON=0;
|
||||
_localProcessBufferOFF=0;
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
_previousInput_ON=0;
|
||||
_previousInput_OFF=0;
|
||||
_amacrinCellsTempOutput_ON=0;
|
||||
_amacrinCellsTempOutput_OFF=0;
|
||||
_magnoXOutputON=0;
|
||||
_magnoXOutputOFF=0;
|
||||
_localProcessBufferON=0;
|
||||
_localProcessBufferOFF=0;
|
||||
|
||||
}
|
||||
|
||||
@@ -124,31 +124,31 @@ void MagnoRetinaFilter::clearAllBuffers()
|
||||
*/
|
||||
void MagnoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
|
||||
{
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
_previousInput_ON.resize(NBrows*NBcolumns);
|
||||
_previousInput_OFF.resize(NBrows*NBcolumns);
|
||||
_amacrinCellsTempOutput_ON.resize(NBrows*NBcolumns);
|
||||
_amacrinCellsTempOutput_OFF.resize(NBrows*NBcolumns);
|
||||
_magnoXOutputON.resize(NBrows*NBcolumns);
|
||||
_magnoXOutputOFF.resize(NBrows*NBcolumns);
|
||||
_localProcessBufferON.resize(NBrows*NBcolumns);
|
||||
_localProcessBufferOFF.resize(NBrows*NBcolumns);
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
_previousInput_ON.resize(NBrows*NBcolumns);
|
||||
_previousInput_OFF.resize(NBrows*NBcolumns);
|
||||
_amacrinCellsTempOutput_ON.resize(NBrows*NBcolumns);
|
||||
_amacrinCellsTempOutput_OFF.resize(NBrows*NBcolumns);
|
||||
_magnoXOutputON.resize(NBrows*NBcolumns);
|
||||
_magnoXOutputOFF.resize(NBrows*NBcolumns);
|
||||
_localProcessBufferON.resize(NBrows*NBcolumns);
|
||||
_localProcessBufferOFF.resize(NBrows*NBcolumns);
|
||||
|
||||
// to be sure, relink buffers
|
||||
_magnoYOutput=&_filterOutput;
|
||||
_magnoYsaturated=&_localBuffer;
|
||||
// to be sure, relink buffers
|
||||
_magnoYOutput=&_filterOutput;
|
||||
_magnoYsaturated=&_localBuffer;
|
||||
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
// reset all buffers
|
||||
clearAllBuffers();
|
||||
}
|
||||
|
||||
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=(float)exp(-1.0f/amacrinCellsTemporalCutFrequency);
|
||||
// the first set of parameters is dedicated to the low pass filtering property of the ganglion cells
|
||||
BasicRetinaFilter::setLPfilterParameters(parasolCells_beta, parasolCells_tau, parasolCells_k, 0);
|
||||
// the second set of parameters is dedicated to the ganglion cells output intergartion for their local adaptation property
|
||||
BasicRetinaFilter::setLPfilterParameters(0, localAdaptIntegration_tau, localAdaptIntegration_k, 1);
|
||||
_temporalCoefficient=(float)exp(-1.0f/amacrinCellsTemporalCutFrequency);
|
||||
// the first set of parameters is dedicated to the low pass filtering property of the ganglion cells
|
||||
BasicRetinaFilter::setLPfilterParameters(parasolCells_beta, parasolCells_tau, parasolCells_k, 0);
|
||||
// the second set of parameters is dedicated to the ganglion cells output intergartion for their local adaptation property
|
||||
BasicRetinaFilter::setLPfilterParameters(0, localAdaptIntegration_tau, localAdaptIntegration_k, 1);
|
||||
}
|
||||
|
||||
void MagnoRetinaFilter::_amacrineCellsComputing(const float *OPL_ON, const float *OPL_OFF)
|
||||
@@ -156,55 +156,55 @@ void MagnoRetinaFilter::_amacrineCellsComputing(const float *OPL_ON, const float
|
||||
#ifdef MAKE_PARALLEL
|
||||
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_amacrineCellsComputing(OPL_ON, OPL_OFF, &_previousInput_ON[0], &_previousInput_OFF[0], &_amacrinCellsTempOutput_ON[0], &_amacrinCellsTempOutput_OFF[0], _temporalCoefficient));
|
||||
#else
|
||||
register const float *OPL_ON_PTR=OPL_ON;
|
||||
register const float *OPL_OFF_PTR=OPL_OFF;
|
||||
register float *previousInput_ON_PTR= &_previousInput_ON[0];
|
||||
register float *previousInput_OFF_PTR= &_previousInput_OFF[0];
|
||||
register float *amacrinCellsTempOutput_ON_PTR= &_amacrinCellsTempOutput_ON[0];
|
||||
register float *amacrinCellsTempOutput_OFF_PTR= &_amacrinCellsTempOutput_OFF[0];
|
||||
register const float *OPL_ON_PTR=OPL_ON;
|
||||
register const float *OPL_OFF_PTR=OPL_OFF;
|
||||
register float *previousInput_ON_PTR= &_previousInput_ON[0];
|
||||
register float *previousInput_OFF_PTR= &_previousInput_OFF[0];
|
||||
register float *amacrinCellsTempOutput_ON_PTR= &_amacrinCellsTempOutput_ON[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 */
|
||||
float magnoXonPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR);
|
||||
*(amacrinCellsTempOutput_ON_PTR++)=((float)(magnoXonPixelResult>0))*magnoXonPixelResult;
|
||||
/* Compute ON and OFF amacrin cells high pass temporal filter */
|
||||
float magnoXonPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_ON_PTR+ *OPL_ON_PTR-*previousInput_ON_PTR);
|
||||
*(amacrinCellsTempOutput_ON_PTR++)=((float)(magnoXonPixelResult>0))*magnoXonPixelResult;
|
||||
|
||||
float magnoXoffPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR);
|
||||
*(amacrinCellsTempOutput_OFF_PTR++)=((float)(magnoXoffPixelResult>0))*magnoXoffPixelResult;
|
||||
float magnoXoffPixelResult = _temporalCoefficient*(*amacrinCellsTempOutput_OFF_PTR+ *OPL_OFF_PTR-*previousInput_OFF_PTR);
|
||||
*(amacrinCellsTempOutput_OFF_PTR++)=((float)(magnoXoffPixelResult>0))*magnoXoffPixelResult;
|
||||
|
||||
/* prepare next loop */
|
||||
*(previousInput_ON_PTR++)=*(OPL_ON_PTR++);
|
||||
*(previousInput_OFF_PTR++)=*(OPL_OFF_PTR++);
|
||||
/* prepare next loop */
|
||||
*(previousInput_ON_PTR++)=*(OPL_ON_PTR++);
|
||||
*(previousInput_OFF_PTR++)=*(OPL_OFF_PTR++);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// launch filter that runs all the IPL filter
|
||||
const std::valarray<float> &MagnoRetinaFilter::runFilter(const std::valarray<float> &OPL_ON, const std::valarray<float> &OPL_OFF)
|
||||
{
|
||||
// Compute the high pass temporal filter
|
||||
_amacrineCellsComputing(get_data(OPL_ON), get_data(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);
|
||||
// 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]);
|
||||
// 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 float *magnoYOutput= &(*_magnoYOutput)[0];
|
||||
register float *magnoXOutputON_PTR= &_magnoXOutputON[0];
|
||||
register float *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0];
|
||||
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
|
||||
*(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++);
|
||||
/* Compute MagnoY */
|
||||
register float *magnoYOutput= &(*_magnoYOutput)[0];
|
||||
register float *magnoXOutputON_PTR= &_magnoXOutputON[0];
|
||||
register float *magnoXOutputOFF_PTR= &_magnoXOutputOFF[0];
|
||||
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
|
||||
*(magnoYOutput++)=*(magnoXOutputON_PTR++)+*(magnoXOutputOFF_PTR++);
|
||||
|
||||
return (*_magnoYOutput);
|
||||
return (*_magnoYOutput);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -89,18 +89,18 @@ ParvoRetinaFilter::ParvoRetinaFilter(const unsigned int NBrows, const unsigned i
|
||||
_bipolarCellsOutputOFF(NBrows*NBcolumns),
|
||||
_localAdaptationOFF(NBrows*NBcolumns)
|
||||
{
|
||||
// link to the required local parent adaptation buffers
|
||||
_localAdaptationON=&_localBuffer;
|
||||
_parvocellularOutputONminusOFF=&_filterOutput;
|
||||
// (*_localAdaptationON)=&_localBuffer;
|
||||
// (*_parvocellularOutputONminusOFF)=&(BasicRetinaFilter::TemplateBuffer);
|
||||
// link to the required local parent adaptation buffers
|
||||
_localAdaptationON=&_localBuffer;
|
||||
_parvocellularOutputONminusOFF=&_filterOutput;
|
||||
// (*_localAdaptationON)=&_localBuffer;
|
||||
// (*_parvocellularOutputONminusOFF)=&(BasicRetinaFilter::TemplateBuffer);
|
||||
|
||||
// init: set all the values to 0
|
||||
clearAllBuffers();
|
||||
// init: set all the values to 0
|
||||
clearAllBuffers();
|
||||
|
||||
|
||||
#ifdef OPL_RETINA_ELEMENT_DEBUG
|
||||
std::cout<<"ParvoRetinaFilter::Init OPL retina filter at specified frame size OK\n"<<std::endl;
|
||||
std::cout<<"ParvoRetinaFilter::Init OPL retina filter at specified frame size OK\n"<<std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -109,7 +109,7 @@ ParvoRetinaFilter::~ParvoRetinaFilter()
|
||||
{
|
||||
|
||||
#ifdef OPL_RETINA_ELEMENT_DEBUG
|
||||
std::cout<<"ParvoRetinaFilter::Delete OPL retina filter OK"<<std::endl;
|
||||
std::cout<<"ParvoRetinaFilter::Delete OPL retina filter OK"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -120,14 +120,14 @@ ParvoRetinaFilter::~ParvoRetinaFilter()
|
||||
// function that clears all buffers of the object
|
||||
void ParvoRetinaFilter::clearAllBuffers()
|
||||
{
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
_photoreceptorsOutput=0;
|
||||
_horizontalCellsOutput=0;
|
||||
_parvocellularOutputON=0;
|
||||
_parvocellularOutputOFF=0;
|
||||
_bipolarCellsOutputON=0;
|
||||
_bipolarCellsOutputOFF=0;
|
||||
_localAdaptationOFF=0;
|
||||
BasicRetinaFilter::clearAllBuffers();
|
||||
_photoreceptorsOutput=0;
|
||||
_horizontalCellsOutput=0;
|
||||
_parvocellularOutputON=0;
|
||||
_parvocellularOutputOFF=0;
|
||||
_bipolarCellsOutputON=0;
|
||||
_bipolarCellsOutputOFF=0;
|
||||
_localAdaptationOFF=0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,32 +137,32 @@ void ParvoRetinaFilter::clearAllBuffers()
|
||||
*/
|
||||
void ParvoRetinaFilter::resize(const unsigned int NBrows, const unsigned int NBcolumns)
|
||||
{
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
_photoreceptorsOutput.resize(NBrows*NBcolumns);
|
||||
_horizontalCellsOutput.resize(NBrows*NBcolumns);
|
||||
_parvocellularOutputON.resize(NBrows*NBcolumns);
|
||||
_parvocellularOutputOFF.resize(NBrows*NBcolumns);
|
||||
_bipolarCellsOutputON.resize(NBrows*NBcolumns);
|
||||
_bipolarCellsOutputOFF.resize(NBrows*NBcolumns);
|
||||
_localAdaptationOFF.resize(NBrows*NBcolumns);
|
||||
BasicRetinaFilter::resize(NBrows, NBcolumns);
|
||||
_photoreceptorsOutput.resize(NBrows*NBcolumns);
|
||||
_horizontalCellsOutput.resize(NBrows*NBcolumns);
|
||||
_parvocellularOutputON.resize(NBrows*NBcolumns);
|
||||
_parvocellularOutputOFF.resize(NBrows*NBcolumns);
|
||||
_bipolarCellsOutputON.resize(NBrows*NBcolumns);
|
||||
_bipolarCellsOutputOFF.resize(NBrows*NBcolumns);
|
||||
_localAdaptationOFF.resize(NBrows*NBcolumns);
|
||||
|
||||
// link to the required local parent adaptation buffers
|
||||
_localAdaptationON=&_localBuffer;
|
||||
_parvocellularOutputONminusOFF=&_filterOutput;
|
||||
// link to the required local parent adaptation buffers
|
||||
_localAdaptationON=&_localBuffer;
|
||||
_parvocellularOutputONminusOFF=&_filterOutput;
|
||||
|
||||
// clean buffers
|
||||
clearAllBuffers();
|
||||
// clean buffers
|
||||
clearAllBuffers();
|
||||
}
|
||||
|
||||
// change the parameters of the filter
|
||||
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
|
||||
setLPfilterParameters(beta1, tau1, k1);
|
||||
// init horizontal cells low pass filter
|
||||
setLPfilterParameters(beta2, tau2, k2, 1);
|
||||
// init parasol ganglion cells low pass filter (default parameters)
|
||||
setLPfilterParameters(0, tau1, k1, 2);
|
||||
// init photoreceptors low pass filter
|
||||
setLPfilterParameters(beta1, tau1, k1);
|
||||
// init horizontal cells low pass filter
|
||||
setLPfilterParameters(beta2, tau2, k2, 1);
|
||||
// init parasol ganglion cells low pass filter (default parameters)
|
||||
setLPfilterParameters(0, tau1, k1, 2);
|
||||
|
||||
}
|
||||
|
||||
@@ -172,59 +172,59 @@ void ParvoRetinaFilter::setOPLandParvoFiltersParameters(const float beta1, const
|
||||
// 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();
|
||||
_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]);
|
||||
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]);
|
||||
_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];
|
||||
//// 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);
|
||||
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
|
||||
*(parvocellularOutputONminusOFF_PTR++)= (*(parvocellularOutputON_PTR++)-*(parvocellularOutputOFF_PTR++));
|
||||
}
|
||||
return (*_parvocellularOutputONminusOFF);
|
||||
}
|
||||
|
||||
void ParvoRetinaFilter::_OPL_OnOffWaysComputing() // WARNING : this method requires many buffer accesses, parallelizing can increase bandwith & core efficacy
|
||||
{
|
||||
// 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
|
||||
// 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
|
||||
|
||||
#ifdef MAKE_PARALLEL
|
||||
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_OPL_OnOffWaysComputing(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], &_bipolarCellsOutputON[0], &_bipolarCellsOutputOFF[0], &_parvocellularOutputON[0], &_parvocellularOutputOFF[0]));
|
||||
#else
|
||||
float *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0];
|
||||
float *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0];
|
||||
float *bipolarCellsON_PTR = &_bipolarCellsOutputON[0];
|
||||
float *bipolarCellsOFF_PTR = &_bipolarCellsOutputOFF[0];
|
||||
float *parvocellularOutputON_PTR= &_parvocellularOutputON[0];
|
||||
float *parvocellularOutputOFF_PTR= &_parvocellularOutputOFF[0];
|
||||
// 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
|
||||
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
|
||||
{
|
||||
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
|
||||
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
|
||||
float isPositive=(float) (pixelDifference>0.0f);
|
||||
float *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0];
|
||||
float *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0];
|
||||
float *bipolarCellsON_PTR = &_bipolarCellsOutputON[0];
|
||||
float *bipolarCellsOFF_PTR = &_bipolarCellsOutputOFF[0];
|
||||
float *parvocellularOutputON_PTR= &_parvocellularOutputON[0];
|
||||
float *parvocellularOutputOFF_PTR= &_parvocellularOutputOFF[0];
|
||||
// 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
|
||||
for (register unsigned int IDpixel=0 ; IDpixel<_filterOutput.getNBpixels() ; ++IDpixel)
|
||||
{
|
||||
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
|
||||
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
|
||||
float isPositive=(float) (pixelDifference>0.0f);
|
||||
|
||||
// ON and OFF channels writing step
|
||||
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
|
||||
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
|
||||
}
|
||||
// ON and OFF channels writing step
|
||||
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
|
||||
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -108,113 +108,113 @@ class ParvoRetinaFilter: public BasicRetinaFilter
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* constructor parameters are only linked to image input size
|
||||
* @param NBrows: number of rows of the input image
|
||||
* @param NBcolumns: number of columns of the input image
|
||||
*/
|
||||
ParvoRetinaFilter(const unsigned int NBrows=480, const unsigned int NBcolumns=640);
|
||||
/**
|
||||
* constructor parameters are only linked to image input size
|
||||
* @param NBrows: number of rows of the input image
|
||||
* @param NBcolumns: number of columns of the input image
|
||||
*/
|
||||
ParvoRetinaFilter(const unsigned int NBrows=480, const unsigned int NBcolumns=640);
|
||||
|
||||
/**
|
||||
* standard desctructor
|
||||
*/
|
||||
virtual ~ParvoRetinaFilter();
|
||||
/**
|
||||
* standard desctructor
|
||||
*/
|
||||
virtual ~ParvoRetinaFilter();
|
||||
|
||||
/**
|
||||
* resize method, keeps initial parameters, all buffers are flushed
|
||||
* @param NBrows: number of rows of the input image
|
||||
* @param NBcolumns: number of columns of the input image
|
||||
*/
|
||||
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
|
||||
/**
|
||||
* resize method, keeps initial parameters, all buffers are flushed
|
||||
* @param NBrows: number of rows of the input image
|
||||
* @param NBcolumns: number of columns of the input image
|
||||
*/
|
||||
void resize(const unsigned int NBrows, const unsigned int NBcolumns);
|
||||
|
||||
/**
|
||||
* function that clears all buffers of the object
|
||||
*/
|
||||
void clearAllBuffers();
|
||||
/**
|
||||
* function that clears all buffers of the object
|
||||
*/
|
||||
void clearAllBuffers();
|
||||
|
||||
/**
|
||||
* setup the OPL and IPL parvo channels
|
||||
* @param beta1: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, the amplitude is boosted but it should only be used for values rescaling... if needed
|
||||
* @param tau1: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
|
||||
* @param k1: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
|
||||
* @param beta2: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
|
||||
* @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)
|
||||
*/
|
||||
void setOPLandParvoFiltersParameters(const float beta1, const float tau1, const float k1, const float beta2, const float tau2, const float k2);
|
||||
/**
|
||||
* setup the OPL and IPL parvo channels
|
||||
* @param beta1: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, the amplitude is boosted but it should only be used for values rescaling... if needed
|
||||
* @param tau1: the time constant of the first order low pass filter of the photoreceptors, use it to cut high temporal frequencies (noise or fast motion), unit is frames, typical value is 1 frame
|
||||
* @param k1: the spatial constant of the first order low pass filter of the photoreceptors, use it to cut high spatial frequencies (noise or thick contours), unit is pixels, typical value is 1 pixel
|
||||
* @param beta2: gain of the horizontal cells network, if 0, then the mean value of the output is zero, if the parameter is near 1, then, the luminance is not filtered and is still reachable at the output, typicall value is 0
|
||||
* @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)
|
||||
*/
|
||||
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)
|
||||
* @param tau: time constant of the filter (unit is frame for video processing)
|
||||
* @param k: spatial constant of the filter (unit is pixels)
|
||||
*/
|
||||
void setGanglionCellsLocalAdaptationLPfilterParameters(const float tau, const float k){BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);}; // change the parameters of the filter
|
||||
/**
|
||||
* 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 k: spatial constant of the filter (unit is pixels)
|
||||
*/
|
||||
void setGanglionCellsLocalAdaptationLPfilterParameters(const float tau, const float k){BasicRetinaFilter::setLPfilterParameters(0, tau, k, 2);}; // change the parameters of the filter
|
||||
|
||||
|
||||
/**
|
||||
* launch filter that runs the OPL spatiotemporal filtering and optionally finalizes IPL Pagno filter (model of the Parvocellular channel of the Inner Plexiform Layer of the retina)
|
||||
* @param inputFrame: the input image to be processed, this can be the direct gray level input frame, but a better efficacy is expected if the input is preliminary processed by the photoreceptors local adaptation possible to acheive with the help of a BasicRetinaFilter object
|
||||
* @param useParvoOutput: set true if the final IPL filtering step has to be computed (local contrast enhancement)
|
||||
* @return the processed Parvocellular channel output (updated only if useParvoOutput is true)
|
||||
* @details: in any case, after this function call, photoreceptors and horizontal cells output are updated, use getPhotoreceptorsLPfilteringOutput() and getHorizontalCellsOutput() to get them
|
||||
* 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()
|
||||
*/
|
||||
const std::valarray<float> &runFilter(const std::valarray<float> &inputFrame, const bool useParvoOutput=true); // output return is _parvocellularOutputONminusOFF
|
||||
/**
|
||||
* launch filter that runs the OPL spatiotemporal filtering and optionally finalizes IPL Pagno filter (model of the Parvocellular channel of the Inner Plexiform Layer of the retina)
|
||||
* @param inputFrame: the input image to be processed, this can be the direct gray level input frame, but a better efficacy is expected if the input is preliminary processed by the photoreceptors local adaptation possible to acheive with the help of a BasicRetinaFilter object
|
||||
* @param useParvoOutput: set true if the final IPL filtering step has to be computed (local contrast enhancement)
|
||||
* @return the processed Parvocellular channel output (updated only if useParvoOutput is true)
|
||||
* @details: in any case, after this function call, photoreceptors and horizontal cells output are updated, use getPhotoreceptorsLPfilteringOutput() and getHorizontalCellsOutput() to get them
|
||||
* 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()
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
inline const std::valarray<float> &getPhotoreceptorsLPfilteringOutput() const {return _photoreceptorsOutput;};
|
||||
/**
|
||||
* @return the output of the photoreceptors filtering step (high cut frequency spatio-temporal low pass filter)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
inline const std::valarray<float> &getHorizontalCellsOutput() const { return _horizontalCellsOutput;};
|
||||
/**
|
||||
* @return the output of the photoreceptors filtering step (low cut frequency spatio-temporal low pass filter)
|
||||
*/
|
||||
inline const std::valarray<float> &getHorizontalCellsOutput() const { return _horizontalCellsOutput;};
|
||||
|
||||
/**
|
||||
* @return the output Parvocellular ON channel of the retina model
|
||||
*/
|
||||
inline const std::valarray<float> &getParvoON() const {return _parvocellularOutputON;};
|
||||
/**
|
||||
* @return the output Parvocellular ON channel of the retina model
|
||||
*/
|
||||
inline const std::valarray<float> &getParvoON() const {return _parvocellularOutputON;};
|
||||
|
||||
/**
|
||||
* @return the output Parvocellular OFF channel of the retina model
|
||||
*/
|
||||
inline const std::valarray<float> &getParvoOFF() const {return _parvocellularOutputOFF;};
|
||||
/**
|
||||
* @return the output Parvocellular OFF channel of the retina model
|
||||
*/
|
||||
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
|
||||
*/
|
||||
inline const std::valarray<float> &getBipolarCellsON() const {return _bipolarCellsOutputON;};
|
||||
/**
|
||||
* @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<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
|
||||
*/
|
||||
inline const std::valarray<float> &getBipolarCellsOFF() const {return _bipolarCellsOutputOFF;};
|
||||
/**
|
||||
* @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<float> &getBipolarCellsOFF() const {return _bipolarCellsOutputOFF;};
|
||||
|
||||
/**
|
||||
* @return the photoreceptors's temporal constant
|
||||
*/
|
||||
inline float getPhotoreceptorsTemporalConstant(){return this->_filteringCoeficientsTable[2];};
|
||||
/**
|
||||
* @return the photoreceptors's temporal constant
|
||||
*/
|
||||
inline float getPhotoreceptorsTemporalConstant(){return this->_filteringCoeficientsTable[2];};
|
||||
|
||||
/**
|
||||
* @return the horizontal cells' temporal constant
|
||||
*/
|
||||
inline float getHcellsTemporalConstant(){return this->_filteringCoeficientsTable[5];};
|
||||
/**
|
||||
* @return the horizontal cells' temporal constant
|
||||
*/
|
||||
inline float getHcellsTemporalConstant(){return this->_filteringCoeficientsTable[5];};
|
||||
|
||||
private:
|
||||
// template buffers
|
||||
std::valarray <float>_photoreceptorsOutput;
|
||||
std::valarray <float>_horizontalCellsOutput;
|
||||
std::valarray <float>_parvocellularOutputON;
|
||||
std::valarray <float>_parvocellularOutputOFF;
|
||||
std::valarray <float>_bipolarCellsOutputON;
|
||||
std::valarray <float>_bipolarCellsOutputOFF;
|
||||
std::valarray <float>_localAdaptationOFF;
|
||||
std::valarray <float> *_localAdaptationON;
|
||||
TemplateBuffer<float> *_parvocellularOutputONminusOFF;
|
||||
// private functions
|
||||
void _OPL_OnOffWaysComputing();
|
||||
// template buffers
|
||||
std::valarray <float>_photoreceptorsOutput;
|
||||
std::valarray <float>_horizontalCellsOutput;
|
||||
std::valarray <float>_parvocellularOutputON;
|
||||
std::valarray <float>_parvocellularOutputOFF;
|
||||
std::valarray <float>_bipolarCellsOutputON;
|
||||
std::valarray <float>_bipolarCellsOutputOFF;
|
||||
std::valarray <float>_localAdaptationOFF;
|
||||
std::valarray <float> *_localAdaptationON;
|
||||
TemplateBuffer<float> *_parvocellularOutputONminusOFF;
|
||||
// private functions
|
||||
void _OPL_OnOffWaysComputing();
|
||||
|
||||
#ifdef MAKE_PARALLEL
|
||||
/******************************************************
|
||||
@@ -226,31 +226,31 @@ private:
|
||||
class Parallel_OPL_OnOffWaysComputing: public cv::ParallelLoopBody
|
||||
{
|
||||
private:
|
||||
float *photoreceptorsOutput, *horizontalCellsOutput, *bipolarCellsON, *bipolarCellsOFF, *parvocellularOutputON, *parvocellularOutputOFF;
|
||||
float *photoreceptorsOutput, *horizontalCellsOutput, *bipolarCellsON, *bipolarCellsOFF, *parvocellularOutputON, *parvocellularOutputOFF;
|
||||
public:
|
||||
Parallel_OPL_OnOffWaysComputing(float *photoreceptorsOutput_PTR, float *horizontalCellsOutput_PTR, float *bipolarCellsON_PTR, float *bipolarCellsOFF_PTR, float *parvocellularOutputON_PTR, float *parvocellularOutputOFF_PTR)
|
||||
:photoreceptorsOutput(photoreceptorsOutput_PTR), horizontalCellsOutput(horizontalCellsOutput_PTR), bipolarCellsON(bipolarCellsON_PTR), bipolarCellsOFF(bipolarCellsOFF_PTR), parvocellularOutputON(parvocellularOutputON_PTR), parvocellularOutputOFF(parvocellularOutputOFF_PTR) {}
|
||||
|
||||
|
||||
virtual void operator()( const Range& r ) const {
|
||||
// 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
|
||||
float *photoreceptorsOutput_PTR= photoreceptorsOutput+r.start;
|
||||
float *horizontalCellsOutput_PTR= horizontalCellsOutput+r.start;
|
||||
float *bipolarCellsON_PTR = bipolarCellsON+r.start;
|
||||
float *bipolarCellsOFF_PTR = bipolarCellsOFF+r.start;
|
||||
float *parvocellularOutputON_PTR= parvocellularOutputON+r.start;
|
||||
float *parvocellularOutputOFF_PTR= parvocellularOutputOFF+r.start;
|
||||
// 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
|
||||
float *photoreceptorsOutput_PTR= photoreceptorsOutput+r.start;
|
||||
float *horizontalCellsOutput_PTR= horizontalCellsOutput+r.start;
|
||||
float *bipolarCellsON_PTR = bipolarCellsON+r.start;
|
||||
float *bipolarCellsOFF_PTR = bipolarCellsOFF+r.start;
|
||||
float *parvocellularOutputON_PTR= parvocellularOutputON+r.start;
|
||||
float *parvocellularOutputOFF_PTR= parvocellularOutputOFF+r.start;
|
||||
|
||||
for (register int IDpixel=r.start ; IDpixel!=r.end ; ++IDpixel)
|
||||
{
|
||||
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
|
||||
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
|
||||
float isPositive=(float) (pixelDifference>0.0f);
|
||||
{
|
||||
float pixelDifference = *(photoreceptorsOutput_PTR++) -*(horizontalCellsOutput_PTR++);
|
||||
// test condition to allow write pixelDifference in ON or OFF buffer and 0 in the over
|
||||
float isPositive=(float) (pixelDifference>0.0f);
|
||||
|
||||
// ON and OFF channels writing step
|
||||
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
|
||||
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
|
||||
}
|
||||
// ON and OFF channels writing step
|
||||
*(parvocellularOutputON_PTR++)=*(bipolarCellsON_PTR++) = isPositive*pixelDifference;
|
||||
*(parvocellularOutputOFF_PTR++)=*(bipolarCellsOFF_PTR++)= (isPositive-1.0f)*pixelDifference;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
@@ -1,55 +1,55 @@
|
||||
/*#******************************************************************************
|
||||
** IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
**
|
||||
**
|
||||
** By downloading, copying, installing or using the software you agree to this license.
|
||||
** If you do not agree to this license, do not download, install,
|
||||
** copy or use the software.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** HVStools : interfaces allowing OpenCV users to integrate Human Vision System models. Presented models originate from Jeanny Herault's original research and have been reused and adapted by the author&collaborators for computed vision applications since his thesis with Alice Caplier at Gipsa-Lab.
|
||||
** Use: extract still images & image sequences features, from contours details to motion spatio-temporal features, etc. for high level visual scene analysis. Also contribute to image enhancement/compression such as tone mapping.
|
||||
**
|
||||
**
|
||||
** Maintainers : Listic lab (code author current affiliation & applications) and Gipsa Lab (original research origins & applications)
|
||||
**
|
||||
**
|
||||
** Creation - enhancement process 2007-2011
|
||||
** Author: Alexandre Benoit (benoit.alexandre.vision@gmail.com), LISTIC lab, Annecy le vieux, France
|
||||
**
|
||||
**
|
||||
** Theses algorithm have been developped by Alexandre BENOIT since his thesis with Alice Caplier at Gipsa-Lab (www.gipsa-lab.inpg.fr) and the research he pursues at LISTIC Lab (www.listic.univ-savoie.fr).
|
||||
** Refer to the following research paper for more information:
|
||||
** Benoit A., Caplier A., Durette B., Herault, J., "USING HUMAN VISUAL SYSTEM MODELING FOR BIO-INSPIRED LOW LEVEL IMAGE PROCESSING", Elsevier, Computer Vision and Image Understanding 114 (2010), pp. 758-773, DOI: http://dx.doi.org/10.1016/j.cviu.2010.01.011
|
||||
** This work have been carried out thanks to Jeanny Herault who's research and great discussions are the basis of all this work, please take a look at his book:
|
||||
** Vision: Images, Signals and Neural Networks: Models of Neural Processing in Visual Perception (Progress in Neural Processing),By: Jeanny Herault, ISBN: 9814273686. WAPI (Tower ID): 113266891.
|
||||
**
|
||||
**
|
||||
** The retina filter includes the research contributions of phd/research collegues from which code has been redrawn by the author :
|
||||
** _take a look at the retinacolor.hpp module to discover Brice Chaix de Lavarene color mosaicing/demosaicing and the reference paper:
|
||||
** ====> B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007). "Efficient demosaicing through recursive filtering", IEEE International Conference on Image Processing ICIP 2007
|
||||
** _take a look at imagelogpolprojection.hpp to discover retina spatial log sampling which originates from Barthelemy Durette phd with Jeanny Herault. A Retina / V1 cortex projection is also proposed and originates from Jeanny's discussions.
|
||||
** ====> more informations in the above cited Jeanny Heraults's book.
|
||||
**
|
||||
**
|
||||
** License Agreement
|
||||
** For Open Source Computer Vision Library
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
** Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved.
|
||||
**
|
||||
**
|
||||
** For Human Visual System tools (hvstools)
|
||||
** Copyright (C) 2007-2011, LISTIC Lab, Annecy le Vieux and GIPSA Lab, Grenoble, France, all rights reserved.
|
||||
**
|
||||
**
|
||||
** Third party copyrights are property of their respective owners.
|
||||
**
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
**
|
||||
** * Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
**
|
||||
** * Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
**
|
||||
**
|
||||
** * The name of the copyright holders may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** This software is provided by the copyright holders and contributors "as is" and
|
||||
** any express or implied warranties, including, but not limited to, the implied
|
||||
** warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
@@ -311,7 +311,7 @@ namespace cv
|
||||
const float *imageGradient;
|
||||
unsigned int nbRows, nbColumns;
|
||||
float filterParam_gain;
|
||||
public:
|
||||
public:
|
||||
Parallel_adaptiveVerticalAnticausalFilter_multGain(float *bufferToProcess, const float *imageGrad, const unsigned int nbRws, const unsigned int nbCols, const float gain)
|
||||
:outputFrame(bufferToProcess), imageGradient(imageGrad), nbRows(nbRws), nbColumns(nbCols), filterParam_gain(gain){}
|
||||
|
||||
|
@@ -366,17 +366,17 @@ bool solveSystem( const Mat& C, const Mat& dI_dt, double detThreshold, Mat& ksi
|
||||
eCt = eC.transpose();
|
||||
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> A, B, eksi;
|
||||
|
||||
A = eCt * eC;
|
||||
double det = A.determinant();
|
||||
|
||||
A = eCt * eC;
|
||||
double det = A.determinant();
|
||||
if( fabs (det) < detThreshold || cvIsNaN(det) || cvIsInf(det) )
|
||||
return false;
|
||||
|
||||
|
||||
B = -eCt * edI_dt;
|
||||
|
||||
eksi = A.ldlt().solve(B);
|
||||
eigen2cv( eksi, ksi );
|
||||
|
||||
|
||||
#else
|
||||
Mat A = C.t() * C;
|
||||
|
||||
|
@@ -123,7 +123,7 @@ Size SelfSimDescriptor::getGridSize( Size imgSize, Size winStride ) const
|
||||
// TODO: optimized with SSE2
|
||||
void SelfSimDescriptor::SSD(const Mat& img, Point pt, Mat& ssd) const
|
||||
{
|
||||
int x, y, dx, dy, r0 = largeSize/2, r1 = smallSize/2;
|
||||
int x, y, dx, dy, r0 = largeSize/2, r1 = smallSize/2;
|
||||
int step = (int)img.step;
|
||||
for( y = -r0; y <= r0; y++ )
|
||||
{
|
||||
@@ -148,7 +148,7 @@ void SelfSimDescriptor::SSD(const Mat& img, Point pt, Mat& ssd) const
|
||||
void SelfSimDescriptor::compute(const Mat& img, vector<float>& descriptors, Size winStride,
|
||||
const vector<Point>& locations) const
|
||||
{
|
||||
CV_Assert( img.depth() == CV_8U );
|
||||
CV_Assert( img.depth() == CV_8U );
|
||||
|
||||
winStride.width = std::max(winStride.width, 1);
|
||||
winStride.height = std::max(winStride.height, 1);
|
||||
@@ -189,32 +189,32 @@ void SelfSimDescriptor::compute(const Mat& img, vector<float>& descriptors, Size
|
||||
|
||||
SSD(img, pt, ssd);
|
||||
|
||||
// Determine in the local neighborhood the largest difference and use for normalization
|
||||
float var_noise = 1000.f;
|
||||
// Determine in the local neighborhood the largest difference and use for normalization
|
||||
float var_noise = 1000.f;
|
||||
for( y = -1; y <= 1 ; y++ )
|
||||
for( x = -1 ; x <= 1 ; x++ )
|
||||
for( x = -1 ; x <= 1 ; x++ )
|
||||
var_noise = std::max(var_noise, ssd.at<float>(largeSize/2+y, largeSize/2+x));
|
||||
|
||||
for( j = 0; j <= fsize; j++ )
|
||||
feature[j] = FLT_MAX;
|
||||
|
||||
// Derive feature vector before exp(-x) computation
|
||||
// Idea: for all x,a >= 0, a=const. we have:
|
||||
// max [ exp( -x / a) ] = exp ( -min(x) / a )
|
||||
// Thus, determine min(ssd) and store in feature[...]
|
||||
for( y = 0; y < ssd.rows; y++ )
|
||||
// Derive feature vector before exp(-x) computation
|
||||
// Idea: for all x,a >= 0, a=const. we have:
|
||||
// max [ exp( -x / a) ] = exp ( -min(x) / a )
|
||||
// Thus, determine min(ssd) and store in feature[...]
|
||||
for( y = 0; y < ssd.rows; y++ )
|
||||
{
|
||||
const schar *mappingMaskPtr = mappingMask.ptr<schar>(y);
|
||||
const float *ssdPtr = ssd.ptr<float>(y);
|
||||
for( x = 0 ; x < ssd.cols; x++ )
|
||||
const schar *mappingMaskPtr = mappingMask.ptr<schar>(y);
|
||||
const float *ssdPtr = ssd.ptr<float>(y);
|
||||
for( x = 0 ; x < ssd.cols; x++ )
|
||||
{
|
||||
int index = mappingMaskPtr[x];
|
||||
feature[index] = std::min(feature[index], ssdPtr[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var_noise = -1.f/var_noise;
|
||||
for( j = 0; j < fsize; j++ )
|
||||
for( j = 0; j < fsize; j++ )
|
||||
feature0[j] = feature[j]*var_noise;
|
||||
Mat _f(1, fsize, CV_32F, feature0);
|
||||
cv::exp(_f, _f);
|
||||
|
0
modules/contrib/src/stereovar.cpp
Executable file → Normal file
0
modules/contrib/src/stereovar.cpp
Executable file → Normal file
@@ -72,8 +72,8 @@
|
||||
|
||||
|
||||
//// If a parallelization method is available then, you should define MAKE_PARALLEL, in the other case, the classical serial code will be used
|
||||
#define MAKE_PARALLEL
|
||||
// ==> then include required includes
|
||||
#define MAKE_PARALLEL
|
||||
// ==> then include required includes
|
||||
#ifdef MAKE_PARALLEL
|
||||
|
||||
// ==> declare usefull generic tools
|
||||
|
Reference in New Issue
Block a user