LoEMD.H

Go to the documentation of this file.
00001 /**
00002    \file  Robots/LoBot/io/LoEMD.H
00003    \brief A generic class implementing a Reichardt Elementary Motion
00004    Detector.
00005 
00006    This file defines a class that implements an Elementary Motion
00007    Detector using two inputs, viz., a left and a right (though it could
00008    just as well be up and down instead or any other pair of opposing
00009    directions). The EMD expects to be given a direction vector and
00010    returns a scaled version of this vector to indicate the current motion
00011    from its inputs.
00012 */
00013 
00014 // //////////////////////////////////////////////////////////////////// //
00015 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00016 // by the University of Southern California (USC) and the iLab at USC.  //
00017 // See http://iLab.usc.edu for information about this project.          //
00018 // //////////////////////////////////////////////////////////////////// //
00019 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00020 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00021 // in Visual Environments, and Applications'' by Christof Koch and      //
00022 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00023 // pending; application number 09/912,225 filed July 23, 2001; see      //
00024 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00025 // //////////////////////////////////////////////////////////////////// //
00026 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00027 //                                                                      //
00028 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00029 // redistribute it and/or modify it under the terms of the GNU General  //
00030 // Public License as published by the Free Software Foundation; either  //
00031 // version 2 of the License, or (at your option) any later version.     //
00032 //                                                                      //
00033 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00034 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00035 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00036 // PURPOSE.  See the GNU General Public License for more details.       //
00037 //                                                                      //
00038 // You should have received a copy of the GNU General Public License    //
00039 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00040 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00041 // Boston, MA 02111-1307 USA.                                           //
00042 // //////////////////////////////////////////////////////////////////// //
00043 //
00044 // Primary maintainer for this file: mviswana usc edu
00045 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/io/LoEMD.H $
00046 // $Id: LoEMD.H 13037 2010-03-23 01:00:53Z mviswana $
00047 //
00048 
00049 #ifndef LOBOT_ELEMENTARY_MOTION_DETECTOR_DOT_H
00050 #define LOBOT_ELEMENTARY_MOTION_DETECTOR_DOT_H
00051 
00052 //------------------------------ HEADERS --------------------------------
00053 
00054 // lobot headers
00055 #include "Robots/LoBot/misc/LoVector.H"
00056 #include "Robots/LoBot/util/LoMath.H"
00057 
00058 //----------------------------- NAMESPACE -------------------------------
00059 
00060 namespace lobot {
00061 
00062 //------------------------- CLASS DEFINITION ----------------------------
00063 
00064 /**
00065    \class lobot::EMD
00066    \brief A generic Elementary Motion Detector.
00067 
00068    This class implements the notion of an Elementary Motion Detector. It
00069    takes two inputs (left and right, though they could be a pair of any
00070    opposing directions) and performs the Reichardt EMD computation to
00071    assess the "amount" of motion in left or right directions (negative
00072    amounts mean leftward motion whereas positive amounts indicate
00073    rightwards motion). This scalar quantity is vectorized by scaling a
00074    direction vector provided to the EMD on its creation.
00075 
00076    Like all templates, this one too implies an interface for its type
00077    parameters. Specifically, the EMD's input type is required to
00078    implement a value() function that returns floating point number
00079    indicating the current level of whatever activity it measures.
00080 */
00081 template<typename input_type>
00082 class EMD {
00083    // Prevent copy and assignment
00084    EMD(const EMD&) ;
00085    EMD& operator=(const EMD&) ;
00086 
00087    /// An Elementary Motion Detector is built from a pair of adjacent
00088    /// inputs.
00089    const input_type& m_left ;
00090    const input_type& m_right ;
00091 
00092    /// For the EMD to work, we need to keep track of both the input
00093    /// values from the previous time step.
00094    float m_left_prev, m_right_prev ;
00095 
00096    /// The EMD is setup to point along a certain direction.
00097    Vector m_direction ;
00098 
00099 public:
00100    /// Clients must specify the left and right (up/down, whatever) inputs
00101    /// and also supply a direction vector for the EMD. The direction
00102    /// vector is specified as an angle in degrees.
00103    EMD(const input_type& left, const input_type& right, float angle) ;
00104 
00105    /// This method uses the latest values from the EMD's left and right
00106    /// inputs and computes the vector representing the total motion.
00107    Vector update() ;
00108 
00109    /// Destructor
00110    virtual ~EMD() ;
00111 } ;
00112 
00113 // Initialization
00114 template<typename input_type>
00115 EMD<input_type>::
00116 EMD(const input_type& left, const input_type& right, float angle)
00117    : m_left(left),   m_right(right),
00118      m_left_prev(0), m_right_prev(0),
00119      m_direction(cos(angle), sin(angle))
00120 {}
00121 
00122 // EMD update
00123 template<typename input_type>
00124 Vector EMD<input_type>::update()
00125 {
00126    const float L = m_left.value() ;
00127    const float R = m_right.value() ;
00128    const float M = m_left_prev * R - L * m_right_prev ;
00129 
00130    m_left_prev  = L ;
00131    m_right_prev = R ;
00132 
00133    //return M * m_direction ; // FIXME: should this be abs(M) * m_direction?
00134    return abs(M) * m_direction ; // FIXME: should not be abs(M) * m_direction?
00135 }
00136 
00137 // Clean-up
00138 template<typename input_type>
00139 EMD<input_type>::~EMD()
00140 {}
00141 
00142 //---------------------- POINTER SPECIALIZATION -------------------------
00143 
00144 // Full specialization for void pointers
00145 template<>
00146 class EMD<void*> {
00147    // Prevent copy and assignment
00148    EMD(const EMD&) ;
00149    EMD& operator=(const EMD&) ;
00150 
00151    // The left and right inputs of the EMD
00152    const void* m_left ;
00153    const void* m_right ;
00154 
00155    // The previous values of the two inputs
00156    float m_left_prev, m_right_prev ;
00157 
00158    // The EMD's direction vector
00159    Vector m_direction ;
00160 
00161 protected:
00162    // Constructor
00163    EMD(const void* left, const void* right, float angle) ;
00164 
00165    // The EMD computation method
00166    Vector update() ;
00167 
00168    // Derived classes must supply this methods for retrieving the current
00169    // input value from the specified input.
00170    virtual float value(const void* input) = 0 ;
00171 
00172 public:
00173    // Destructor
00174    virtual ~EMD() ;
00175 } ;
00176 
00177 // Initialization
00178 EMD<void*>::
00179 EMD(const void* left, const void* right, float angle)
00180    : m_left(left),   m_right(right),
00181      m_left_prev(0), m_right_prev(0),
00182      m_direction(cos(angle), sin(angle))
00183 {}
00184 
00185 // EMD update
00186 Vector EMD<void*>::update()
00187 {
00188    const float L = value(m_left) ;
00189    const float R = value(m_right) ;
00190    const float M = m_left_prev * R - L * m_right_prev ;
00191 
00192    m_left_prev  = L ;
00193    m_right_prev = R ;
00194 
00195    //return M * m_direction ; // FIXME: should this be abs(M) * m_direction?
00196    return abs(M) * m_direction ; // FIXME: should not be abs(M) * m_direction?
00197 }
00198 
00199 // Clean-up
00200 EMD<void*>::~EMD()
00201 {}
00202 
00203 // Partial specialization for non-void pointers
00204 template<typename input_type>
00205 class EMD<input_type*> : private EMD<void*> {
00206    // Handy type to have around in a derived class
00207    typedef EMD<void*> base ;
00208 
00209    // Prevent copy and assignment
00210    EMD(const EMD&) ;
00211    EMD& operator=(const EMD&) ;
00212 
00213 public:
00214    // Constructor
00215    EMD(const input_type* left, const input_type* right, float angle) ;
00216 
00217    // Destructor
00218    ~EMD() ;
00219 
00220    // EMD update
00221    Vector update() {return base::update() ;}
00222 
00223 protected:
00224    // Override required of derived class
00225    float value(const void* input) ;
00226 } ;
00227 
00228 // Initialization
00229 template<typename input_type>
00230 EMD<input_type*>::
00231 EMD(const input_type* left, const input_type* right, float angle)
00232    : base(reinterpret_cast<const void*>(left),
00233           reinterpret_cast<const void*>(right),
00234           angle)
00235 {}
00236 
00237 // EMD update
00238 template<typename input_type>
00239 float EMD<input_type*>::value(const void* input)
00240 {
00241    return (reinterpret_cast<const input_type*>(input))->value() ;
00242 }
00243 
00244 // Destructor
00245 template<typename input_type>
00246 EMD<input_type*>::~EMD()
00247 {}
00248 
00249 //-----------------------------------------------------------------------
00250 
00251 } // end of namespace encapsulating this file's definitions
00252 
00253 #endif
00254 
00255 /* So things look consistent in everyone's emacs... */
00256 /* Local Variables: */
00257 /* indent-tabs-mode: nil */
00258 /* End: */
Generated on Sun May 8 08:41:30 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3