/* * mp_Gabor * * Author: Andrew Salamon * Date: Thu Apr 20 2006 * * This class is an adaptor between the mp_alignEyesMex and the interpolator that does the image * rotation. Primarily it does some setup, calls the interpolator, then does some teardown. * Arguments: * pixels: input image (full size) * patchSize: size (width and height) for the rotated face image * xl, xr, yl, yr: eye coordinates * Return value: * The rotated and cropped face. It was allocated with new, so needs to be deleted when the caller is done with it. * * Copyright (c) 2006 Machine Perception Laboratory * University of California San Diego. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 2. 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. * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __MP_GABOR_H__ #define __MP_GABOR_H__ #include #include #include #include "rimage.h" #include "mp_AUResults.h" extern "C" { #include } //typedef complex myComplex; typedef std::complex myComplex; //typedef fftw_complex myComplex; void printVector( std::vector &results ); // Prints the vector on a single line to std out void printStringVector( std::vector &results ); /** MP_Gabor duplicates the functionality of CERT's Gabor_jetF function and SVM weighting. * It takes a 96x96 aligned face patch and calculates Action Unit values for * eight different AU's (1, 2, 4, 5, 10, 12, 14, 20). Individual steps in the process can be run (probably * only useful for debugging) or the entire thing can be run with one call. * * Steps: * -# normalize(); * -# fft(); * -# kernelMultiply( ni-3, mu-1 ); * -# ifft(); * -# fftshift(); * -# complexConjugateTranspose( intermediate, patchWidth, patchHeight ); * -# abs(); * -# svmWeight( ni, mu ); * * Steps 3-8 are done inside a loop with different ni and mu values. * * Answers from each step can be obtained using: *
  • 1: getPixels() or getDoublePixels() *
  • 2: getImgStar() *
  • 3-6: getMatrix() *
  • 7: getAbs() *
  • 8: getAU() *
*/ class MP_Gabor { public: MP_Gabor( const RImage &_pixels, int width, int height, bool _sub_proc = false ); virtual ~MP_Gabor(); bool CERT_Gabor(); // Duplicates the CERT Gabor_jetF function, plus the outer loop from CERT.m. Returns false if any weights failed to load. // This block of methods should be private, but some are being used for automated testing. void normalize(); // Duplicates the Matlab function mat2gray void fft(); // Matlab: fft2() void *kernelMultiply( int ni, int mu ); // Element by element multiply of intermediate and a Gabor kernel, Matlab: .* void ifft(); // Matlab: ifft2() void fftshift(); // Matlab: fftshift() void complexConjugateTranspose( myComplex *fft, int width, int height ); // Matlab: ' void abs(); // Matlab: abs() void postGaborNormalize(); // Gwen's post gabor normalization std::vector svmWeight( int ni, int mu, std::string weightsCategory ); // Matlab: yhat=yhat+gx*squeeze(W(ni,mu,:,:)); RImage &getPixels(); RImage &getDoublePixels(); myComplex *getMatrix(); ///< Get the current results, except after the normalize(), fft() and abs() steps. myComplex *getImgStar(); ///< Get the results after the fft() step. double *getAbs(); ///< Results after the abs() step. virtual void setPixels( const RImage &newImage ); // resets everything void setImgStar( myComplex *_img_star ); ///< For use by a threaded version of this class bool getLoadError() { return loadError; } void loadAllSVMWeights(); int getWidth(); int getHeight(); void setNi( unsigned int min, unsigned int max ); ///< Used to run multiple gabors on the same data in separate threads. void operator()(); ///< simply calls CERT_Gabor(). virtual void clearYhat(); protected: bool sub_proc; RImage pixels; RImage dblPixels; int patchWidth; int patchHeight; bool normalized; fftw_plan fftPlan; fftw_plan ifftPlan; myComplex *img_star; myComplex *intermediate; double *absTemp; bool loadError; ///< Set to true if any svm weight file fails to load. unsigned int minNi; unsigned int maxNi; void fftFill( myComplex *fft, int width, int height ); void kernelLoop(); private: MP_Gabor( const MP_Gabor& ); MP_Gabor &operator=( const MP_Gabor& ); // Support for SVM weight plugins protected: std::vector< std::string > categories; std::map< std::string, std::vector > catResults; std::map< std::string, mp_AUResults > frequencies; public: /// Which categories of SVM weights will be run. This is the same string passed to mp_SVMWeights. virtual void setCategories( std::vector< std::string > &_categories ); virtual void addCategory( std::string cat ); virtual void removeCategory( std::string cat ); virtual std::map< std::string, std::vector > resultsForCategories(); virtual std::vector resultsForCategory( const std::string &cat ); virtual std::map< std::string, mp_AUResults > getFrequencies(); virtual mp_AUResults &frequenciesForCategory( const std::string &cat ); }; #endif