/* * CERT_Task.h * * Author: Andrew Salamon * Date: Mon August 13, 2007 * * Copyright (c) 2007 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 __CERT_TASK_H__ #define __CERT_TASK_H__ #include #include #include #include #include #include #include "FeatureAlignment.hpp" #include "objectWithFeatures.hpp" #include "interpolate.h" #include "rimage.h" namespace CERT { class Plugin; class PluginResults; class Parameters { public: Parameters(); // Fill these in in the constructor std::string SourceCertVersion; std::string SourceMPTVersion; class SVM_Attributes { public: std::string category; std::string directory; std::string filename; // The name of the matlab file used to generate the xml files std::string date; std::string version; std::vector< std::string > auLabels; }; std::map< std::string, SVM_Attributes > SVM_Params; ///< From mp_SVMWeights. Key is the category name. std::vector< Plugin > plugins; ///< Plugins that might be processed. Individual plugins can be disabled. // This will get all of the SVM_Attributes info from mp_SVMWeights and fill in the labels. void fillCategory( const std::string &cat, const std::vector< std::string > labels ); // we might want accessors to make it easier to get the SVM_Attributes pieces: std::string directoryForCategory( const std::string &cat ); // { // if( SVM_Params.count( cat ) > 0 ) // return SVM_Params[ cat ].directory; // return ""; // } // Interpolator parameters float eye_top_rate; float eye_len_rate; // won't apply when using featuredetector // FeatureDector parameters: bool useSequences; // Are we using the sequence optimization? Matrix2d defaultFaceBox; // Currently set in mp_FDEyes::setCERT3_3_FaceBox() FeatureAlignment::alignment_method alignment; // Alignment used. std::vector< std::string > featurePaths; // There doesn't seem to be any other way to know which feature data we're using, so just store the paths used to load the features. }; /** This class will represent a task in CERT, probably one image or video frame. * It contains all the information that CERT would need to calculate AU's, along with * all of the results. * Not designed to work with the older Eyefinder, only the FeatureDetector. */ class Task { public: // As a minimum we need an image and either a filename or a frame number // Even for images read from disc, frame number can be used to sort the results Task( RImage &img, const std::string &_filename, const Parameters *_params = NULL ); Task( RImage &img, int _frame, const Parameters *_params = NULL ); Task( const Task &other ); ~Task(); Task &operator=( const Task &other ); void clear(); typedef enum { notReady, ready, running, finished, done // This means everyone is done with this task object, even the controller/data handler/etc. Can safely be cleared } taskState; taskState getState() { return state; } // Error handling // Possible errors: // No face found // Not enough features found // Other exception (hopefully with a message) bool ok(); // true if there were no errors // a method to return all errors? // // other accessors needed, read/write: // img // filename // params // frame // // other accessors needed, read only: // state // results // frequencies // faces // fdFaces // face boxes // face patches // bestFaceIndex // Serialization related types and methods typedef enum { unknown = -1, begin = 0, text = begin, binary, xml, end } filetype; static std::string extensionForFiletype( filetype ftype ); static filetype filetypeFromName( const std::string &filename ); void save( std::ostream &os, filetype type = xml ); void restore( std::istream &is, filetype type = xml ); private: boost::shared_ptr params; // probably shared with numerous other tasks. taskState state; std::string filename; int frame; RImage image; // use boost dates for these? // possible date time stamps: image/frame stamp, task created, task started, task finished //boost::posix_time::ptime image; //boost::posix_time::ptime created(microsec_clock::local_time()); // set during constructor //boost::posix_time::ptime started; // set during state change: ready->running //boost::posix_time::ptime finished; // set during state change: running->finished // Results std::map< std::string, PluginResults > results; std::map< std::string, mp_AUResults > frequencies; // Facefinder results: std::vector< TSquare > faces; // FeatureDector results: std::vector< ObjectWithFeatures > fdFaces; std::vector< CFourCoordinates > rotatedFaceBoxes; ///< The actual boxes used to do rotation/cropping. std::vector< RImage > facePatches; ///< Always save face patches? Seems like it would be worth it. int bestFaceIndex; ///< Index into various face vectors of the 'best' (usually largest) face. }; class PluginResults { public: // We can't have a pointer to the plugin itself, since results may be transmitted from place to place // and we probably won't want to be sending the plugins themselves. // const Plugin *plugin; const std::string pluginID; std::vector results; double results_for_label( string label ); }; class Plugin { public: typedef enum { noStep = 0, features, afterFaces, SVM, frequencies } stepType; std::string name; std::string id; std::string type; ///< During what stage of the CERT processing does this plugin run. bool enabled; std::vector labels; processTask( Task &_task ) = 0; ///< Must be overridden in a sub-class. }; } // end namespace CERT #endif