libeblearntools
/home/rex/ebltrunk/tools/libeblearntools/include/camera_directory.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_DIRECTORY_HPP_
00034 #define CAMERA_DIRECTORY_HPP_
00035 
00036 #include <sstream>
00037 
00038 namespace ebl {
00039 
00041   // constructors & initializations
00042 
00043   template <typename Tdata>
00044   camera_directory<Tdata>::camera_directory(const char *dir,
00045                                             int height_, int width_,
00046                                             bool randomize_, uint npasses_,
00047                                             std::ostream &o, std::ostream &e,
00048                                             const char *pattern, 
00049                                             const list<string> *files)
00050     : camera<Tdata>(height_, width_, o, e), indir(dir),
00051       randomize(randomize_), npasses(npasses_), file_pattern(pattern) {
00052     if (npasses == 0)
00053       eblerror("number of passes must be >= 1");
00054     out << "Initializing directory camera from: " << dir << endl;
00055     if (files && files->size() > 0) { // file names specified by hand
00056       // build list and check each file exists
00057       fl = new files_list;
00058       for (list<string>::const_iterator i = files->begin(); i != files->end();
00059            ++i) {
00060         string fullname;
00061         fullname << dir << "/" << *i;
00062         if (file_exists(fullname)) {
00063           fl->push_back(stringpair(string(dir), *i));
00064         } else
00065           e << "warning: file not found: " << fullname << endl;
00066       }
00067       if (fl->size() == 0) {
00068         err << "warning: No images in image list were found: "
00069              << *files << endl;
00070         err << "Looking for other images..." << endl;
00071         if (!read_directory(dir)) eblerror( "No images found in " << dir);
00072       }
00073     } else { // search all files matching pattern
00074       if (!read_directory(dir)) eblerror( "No images found in " << dir);
00075     }
00076     cout << "Found " << fl->size() << " images in " << indir << endl;
00077     if (randomize)
00078       out << "Image list is randomized." << endl;
00079     if (npasses > 1)
00080       out << "Image list will be used " << npasses << " times." << endl;
00081     flsize = fl->size() * npasses;
00082     fli = fl->begin(); // initialize iterator to beginning
00083   }
00084 
00085   template <typename Tdata>
00086   camera_directory<Tdata>::camera_directory(int height_, int width_,
00087                                             bool randomize_, uint npasses_,
00088                                             std::ostream &o, std::ostream &e,
00089                                             const char *pattern)
00090     : camera<Tdata>(height_, width_, o, e),
00091       randomize(randomize_), npasses(npasses_), file_pattern(pattern) {
00092     if (npasses == 0)
00093       eblerror("number of passes must be >= 1");
00094   }
00095 
00096   template <typename Tdata>
00097   bool camera_directory<Tdata>::read_directory(const char *dir) {
00098     out << "Image search pattern: " << file_pattern << " in " << dir << endl;
00099     string directory = dir;
00100     if (directory[directory.length() - 1] != '/')
00101       directory += '/';
00102     indir = directory;
00103     // // first count number of images, to allocate list and speed up
00104     // uint n = count_files(directory, file_pattern);
00105     // if (fl) delete fl;
00106     // fl = new files_list(n);
00107     // get all file names
00108     fl = find_files(directory, file_pattern, NULL,
00109                     randomize ? false : true, true, randomize);
00110     if (!fl) {
00111       err << "invalid directory: " << dir << endl;
00112       eblerror("invalid directory");
00113       return false;
00114     }
00115     return true;
00116   }
00117   
00118   template <typename Tdata>
00119   camera_directory<Tdata>::~camera_directory() {
00120     if (fl)
00121       delete fl;
00122   }
00123   
00125   // frame grabbing
00126 
00127   template <typename Tdata>
00128   void camera_directory<Tdata>::next() {
00129     if (empty())
00130       eblerror("cannot grab images on empty list");
00131     fdir = fli->first; // directory
00132     fname = fli->second; // file name
00133     frame_name_ = fname;
00134     if (fdir.size() > indir.size()) {
00135       subdir = fdir.substr(indir.size());
00136       frame_name_ = "";
00137       frame_name_ << subdir << "/" << fname;
00138     }
00139     //cout << "fname: " << fname << " fdir: " << fdir << " subdir: " << subdir << endl;
00140     //    ostringstream fn("");
00141     if (fdir[fdir.length() - 1] != '/')
00142       fdir += "/";
00143 //     if (strcmp(fdir.c_str(), ""))
00144 //       fn << fdir;
00145 //     fn << fname; // << "_" << frame_id_;
00146 //     frame_name_ = fn.str();
00147 //     if (strcmp(fdir.c_str(), "")) {
00148 //       size_t npos = frame_name_.length() - fdir.length();
00149 //       frame_name_ = frame_name_.substr(fdir.length(), npos);
00150 //     }
00151 //     for (size_t i = 0; i < frame_name_.length(); ++i)
00152 //       if (frame_name_[i] == '/')
00153 //      frame_name_[i] = '_';
00154     fli++; // move to next element
00155     frame_id_++;
00156   }
00157 
00158   template <typename Tdata>
00159   void camera_directory<Tdata>::previous() {
00160     if (empty())
00161       eblerror("cannot grab images on empty list");
00162     // move to previous element
00163     fli--;
00164     frame_id_--;
00165     // set names
00166     fdir = fli->first; // directory
00167     fname = fli->second; // file name
00168     frame_name_ = fname;
00169     if (fdir.size() > indir.size()) {
00170       subdir = fdir.substr(indir.size());
00171       frame_name_ = "";
00172       frame_name_ << subdir << "/" << fname;
00173     }
00174     if (fdir[fdir.length() - 1] != '/')
00175       fdir += "/";
00176   }
00177 
00178   template <typename Tdata>
00179   string camera_directory<Tdata>::grab_filename() {
00180     next();
00181     out << frame_id_ << "/" << flsize << ": grabbing ";
00182     out << fdir << fname << endl;
00183     oss.str(""); oss << fdir << "/" << fname;
00184     return oss.str();
00185   }
00186 
00187   template <typename Tdata>
00188   idx<Tdata> camera_directory<Tdata>::grab() {
00189     next();
00190     out << frame_id_ << "/" << flsize << ": grabbing ";
00191     out << fdir << fname << endl;
00192     oss.str(""); oss << fdir << "/" << fname;
00193     try {
00194       frame = load_image<Tdata>(oss.str());
00195     } catch (const string &e) {
00196       err << "failed to load image " << oss.str() << " (" << e << "). "
00197           << "Trying next image..." << endl;
00198       frame_id_++;
00199       return grab();
00200     }
00201     return this->postprocess();
00202   }
00203 
00204   template <typename Tdata>
00205   void camera_directory<Tdata>::skip(uint n) {
00206     if (n == 0) return ;
00207     uint i;
00208     for (i = 0; i < n; ++i) {
00209       if (empty()) {
00210         i--;
00211         break ;
00212       }
00213       fli++;
00214       frame_id_++;
00215     }
00216     cout << "Skipped " << i << " frames." << endl;
00217   }
00218     
00219   template <typename Tdata>
00220   bool camera_directory<Tdata>::empty() {
00221     if (!fl)
00222       eblerror("directory not initialized");
00223     if (fli == fl->end()) {
00224       if (npasses > 0) {
00225         npasses--;
00226         if (npasses > 0)
00227           fli = fl->begin(); // reset to begining.
00228       }
00229       if (npasses == 0) // we did all passes, stop.
00230         return true;
00231     }
00232     return false;
00233   }
00234     
00235   template <typename Tdata>
00236   string camera_directory<Tdata>::frame_name() {
00237     return frame_name_;
00238   }
00239   
00240   template <typename Tdata>
00241   string camera_directory<Tdata>::frame_fullname() {
00242     string full;
00243     full << fdir << fname;
00244     return full;
00245   }
00246   
00247   template <typename Tdata>
00248   string camera_directory<Tdata>::get_subdir() {
00249     return subdir;
00250   }
00251   
00252   template <typename Tdata>
00253   int camera_directory<Tdata>::remaining() {
00254     return (int) (flsize - frame_id_);
00255   }
00256   
00257   template <typename Tdata>
00258   int camera_directory<Tdata>::size() {
00259     return (int) flsize;
00260   }
00261   
00262 } // end namespace ebl
00263 
00264 #endif /* CAMERA_DIRECTORY_HPP_ */