00001
00002 #include "strk_snippet_extractor_process.h"
00003 #include <vcl_fstream.h>
00004 #include <vcl_iostream.h>
00005 #include <vcl_vector.h>
00006 #include <vgl/vgl_point_2d.h>
00007 #include <vidl_vil1/vidl_vil1_movie.h>
00008 #include <vidl_vil1/vidl_vil1_clip.h>
00009 #include <vidl_vil1/vidl_vil1_io.h>
00010 #include <vsol/vsol_box_2d.h>
00011 #include <vtol/vtol_face_2d.h>
00012 #include <bsol/bsol_algs.h>
00013 #include <brip/brip_roi.h>
00014 #include <brip/brip_vil1_float_ops.h>
00015 #include <strk/strk_io.h>
00016
00017 strk_snippet_extractor_process::strk_snippet_extractor_process()
00018 {
00019 failure_ = false;
00020 first_frame_ = true;
00021 margin_frac_ = 0.1;
00022 track_file_ = "";
00023 snippet_directory_= "";
00024 }
00025
00026 strk_snippet_extractor_process::~strk_snippet_extractor_process()
00027 {
00028 }
00029
00030 bool strk_snippet_extractor_process::execute()
00031 {
00032 if (failure_)
00033 return false;
00034 if (this->get_N_input_images()!=1)
00035 {
00036 vcl_cout << "In strk_snippet_extractor_process::execute() -"
00037 << " not exactly one input image\n";
00038 failure_ = true;
00039 return false;
00040 }
00041 static unsigned int n_frames = 0;
00042 vil1_image img = vpro_video_process::get_input_image(0);
00043 input_images_.clear();
00044 if (first_frame_)
00045 {
00046 n_frames = tracked_rois_.size();
00047 unsigned int w = img.width(), h = img.height();
00048 for (unsigned int i=0; i<n_frames; ++i)
00049 tracked_rois_[i]->set_image_bounds(w, h);
00050 first_frame_ = false;
00051 }
00052 int frame_index = this->frame_index();
00053 int offset = frame_index-start_frame_;
00054 if (offset<0||offset>=(int)n_frames)
00055 {
00056 failure_ = true;
00057 return false;
00058 }
00059 brip_vil1_float_ops::chip(img, tracked_rois_[offset], output_image_);
00060 tracked_snippets_.push_back(output_image_);
00061 return true;
00062 }
00063
00064 bool strk_snippet_extractor_process::
00065 extract_rois(vcl_vector<vtol_face_2d_sptr> const & tracked_faces)
00066 {
00067 for (vcl_vector<vtol_face_2d_sptr>::const_iterator fit = tracked_faces.begin();fit != tracked_faces.end(); ++fit)
00068 {
00069 vsol_box_2d_sptr bb = (*fit)->get_bounding_box(), expanded_box;
00070 double diameter = (bb->width()+bb->height())/2.0;
00071
00072 if (!bsol_algs::box_with_margin(bb, margin_frac_*diameter, expanded_box))
00073 return false;
00074 brip_roi_sptr roi = new brip_roi();
00075 roi->add_region(expanded_box);
00076 tracked_rois_.push_back(roi);
00077 }
00078 return true;
00079 }
00080
00081 bool strk_snippet_extractor_process::
00082 set_input_file(vcl_string const& track_file_name)
00083 {
00084 start_frame_ = 0;
00085 track_file_ = track_file_name;
00086 if (track_file_=="")
00087 return false;
00088 vcl_ifstream str(track_file_.c_str());
00089 if (!str)
00090 {
00091 vcl_cout << "In strk_snippet_extractor_process::set_input_file() -"
00092 << " could not open file " << track_file_ << '\n';
00093 return false;
00094 }
00095 unsigned int n_frames = 0;
00096 vcl_vector<vgl_point_2d<double> > cogs;
00097 vcl_vector<vtol_face_2d_sptr> tracked_faces;
00098 if (!strk_io::read_track_data(str, start_frame_, n_frames,
00099 cogs, tracked_faces))
00100 {
00101 str.close();
00102 return false;
00103 }
00104 end_frame_ = start_frame_+n_frames -1;
00105 str.close();
00106 if (!extract_rois(tracked_faces))
00107 return false;
00108 return true;
00109 }
00110
00111 void
00112 strk_snippet_extractor_process::set_snippet_directory(vcl_string const& snip_dir)
00113 {
00114 snippet_directory_ = snip_dir;
00115 }
00116
00117 bool strk_snippet_extractor_process::finish()
00118 {
00119 if (!tracked_snippets_.size())
00120 return false;
00121 vidl_vil1_clip_sptr clip = new vidl_vil1_clip(tracked_snippets_);
00122 vidl_vil1_movie_sptr mov= new vidl_vil1_movie();
00123 mov->add_clip(clip);
00124 if (!vidl_vil1_io::save(mov.ptr(), snippet_directory_.c_str(), "tiff")){
00125 vcl_cout << "In strk_snippet_extractor_process::finish()"
00126 << " - failed to save video" << vcl_endl;
00127 return false;
00128 }
00129 tracked_snippets_.clear();
00130 return true;
00131 }