libeblearntools
/home/rex/ebltrunk/tools/libeblearntools/include/camera.hpp
00001 /***************************************************************************
00002  *   Copyright (C) 2010 by Pierre Sermanet   *
00003  *   pierre.sermanet@gmail.com   *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source 
00014  *       Initiative (http://www.opensource.org) must display the 
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef CAMERA_HPP_
00034 #define CAMERA_HPP_
00035 
00036 #include <iomanip>
00037 
00038 namespace ebl {
00039 
00041   // constructors & initializations
00042 
00043   template <typename Tdata>
00044   camera<Tdata>::camera(int height_, int width_, std::ostream &o,
00045                         std::ostream &e)
00046     : height(height_), width(width_), bresize(false), mresize(true),
00047       resize_mode(0), frame_id_(0),
00048       grabbed(false), wid(0), recording_name("video"), record_cnt(0),
00049       fps_grab(0.0), audio_filename(""), out(o), err(e), cntfps(0),
00050       narrow_dim(-1), narrow_size(-1), narrow_off(-1), grayscale(false) {
00051     // decide if we resize input or not
00052     if ((height != -1) && (width != -1))
00053       bresize = true;
00054     tfps.start(); // timer for computing fps
00055   }
00056 
00057   template <typename Tdata>
00058   camera<Tdata>::~camera() {
00059   }
00060   
00062   // grabbin
00063   
00064   template <typename Tdata>
00065   string camera<Tdata>::grab_filename() {
00066     string err;
00067     eblerror("not implemented");
00068     return err;
00069   }
00070   
00071   template <typename Tdata>
00072   void camera<Tdata>::next() {
00073     eblerror("not implemented");
00074   }
00075   
00076   template <typename Tdata>
00077   void camera<Tdata>::previous() {
00078     eblerror("not implemented");
00079   }
00080   
00081   template <typename Tdata>
00082   bool camera<Tdata>::empty() {
00083     return false; // never empty by default
00084   }
00085   
00086   template <typename Tdata>
00087   void camera<Tdata>::skip(uint n) {
00088     eblerror("not implemented");
00089   }
00090   
00091   template <typename Tdata>
00092   void camera<Tdata>::set_input_narrow(int dim, int size, int off) {
00093     narrow_dim = dim;
00094     narrow_size = size;
00095     narrow_off = off;    
00096   }
00097   
00098   template <typename Tdata>
00099   void camera<Tdata>::set_grayscale() {
00100     grayscale = true;
00101   }
00102   
00104   // video recording
00105     
00106   template <typename Tdata>
00107   bool camera<Tdata>::start_recording(uint window_id, const char *name) {
00108     wid = window_id;
00109     record_cnt = 0;
00110     if (name)
00111       recording_name = name;
00112     // add timestamp to name
00113     recording_name += "_";
00114     recording_name += tstamp();
00115     // create directory
00116     mkdir_full(recording_name);
00117     return true;
00118   }
00119 
00120   template <typename Tdata>
00121   bool camera<Tdata>::record_frame() {
00122 #ifdef __GUI__
00123     ostringstream oss;
00124     oss << recording_name << "/frame_";
00125     oss << setfill('0') << setw(6) << record_cnt << ".png";
00126     save_window(oss.str().c_str());
00127     out << "saved " << oss.str() << endl;
00128     record_cnt++;
00129 #endif
00130     return true;
00131   }
00132     
00133   template <typename Tdata>
00134   bool camera<Tdata>::stop_recording(float fps, const char *root) {
00135     if (record_cnt == 0)
00136       return false;
00137     string rname;
00138     if (root) {
00139       rname += root;
00140       rname += "/";
00141     }
00142     rname += recording_name;
00143     ostringstream oss;
00144     uint optimal_bitrate = 50 * 25 * frame.dim(0) * frame.dim(1) / 256;
00145     ostringstream options;
00146     string codec = "msmpeg4v2";
00147     options << "vbitrate=" << optimal_bitrate << ":mbd=2:keyint=132:";
00148     options << "vqblur=1.0:cmp=2:subcmp=2:dia=2:mv0:last_pred=3";
00149     // pass 1
00150     oss << "mencoder \"mf://" << rname;
00151     oss << "/*.png\" -mf type=png:fps=" << fps;
00152     oss << " -ovc lavc";
00153     oss << " -lavcopts vcodec=" << codec << ":vpass=1:" << options.str();
00154     oss << " -o /dev/null ";
00155     int ret = std::system(oss.str().c_str());
00156     if (ret < 0)
00157       return false;
00158     // pass 2
00159     oss.str("");
00160     oss << "mencoder \"mf://" << rname;
00161     oss << "/*.png\" -mf type=png:fps=" << fps;
00162     oss << " -ovc lavc";
00163     oss << " -lavcopts vcodec=" << codec << ":vpass=2:" << options.str();
00164     if (audio_filename != "") {
00165       oss << " -audiofile " << audio_filename;
00166       oss << " -oac mp3lame -lameopts cbr:br=32 ";
00167     }
00168     oss << " -o " << rname << ".avi ";
00169     ret = std::system(oss.str().c_str());
00170     if (ret < 0)
00171       return false;
00172     out << "Saved " << rname << ".avi";
00173     out << " at " << fps << " fps." << endl;
00174     return true;
00175   }
00176 
00178   // info
00179   
00180   template <typename Tdata>
00181   float camera<Tdata>::fps() {
00182     return fps_grab;
00183   }
00184 
00185   template <typename Tdata>
00186   uint camera<Tdata>::frame_id() {
00187     return frame_id_;
00188   }
00189   
00190   template <typename Tdata>
00191   string camera<Tdata>::frame_name() {
00192     ostringstream name;
00193     name << "frame_" << frame_id_;
00194     return name.str();
00195   }
00196   
00197   template <typename Tdata>
00198   string camera<Tdata>::frame_fullname() {
00199     return frame_name();
00200   }
00201   
00202   template <typename Tdata>
00203   int camera<Tdata>::remaining() {
00204     return -1;
00205   }
00206   
00207   template <typename Tdata>
00208   int camera<Tdata>::size() {
00209     return -1;
00210   }
00211   
00213   // internal methods
00214   
00215   template <typename Tdata>
00216   inline idx<Tdata> camera<Tdata>::postprocess() {
00217     fps_ms_elapsed = tfps.elapsed_milliseconds();
00218     cntfps++;
00219     if (narrow_dim >= 0)
00220       frame = frame.narrow(narrow_dim, narrow_size, narrow_off);
00221     if (fps_ms_elapsed > 1000) {
00222       fps_grab = cntfps * 1000 / (float) fps_ms_elapsed;
00223       tfps.restart(); // restart timer
00224       cntfps = 0; // reset counter
00225     }
00226     if (!bresize)
00227       return frame; // return original frame
00228     else { // or return a resized frame
00229       if (mresize)
00230         return image_mean_resize(frame, height, width, resize_mode);
00231       else
00232         return image_resize(frame, height, width, resize_mode);
00233     }
00234   }
00235   
00236 } // end namespace ebl
00237 
00238 #endif /* CAMERA_HPP_ */