libeblearntools
|
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_ */