contrib/mul/mfpf/tools/mfpf_build_finder.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Tool to build a finder from a set of training images
00004 // \author Tim Cootes
00005 // Builds a model of patch around a given point.
00006 // For simplicity, assumes fixed scale and orientation across all data.
00007 // Input data file format:
00008 // \code
00009 // patch_builder: mfpf_norm_corr2d_builder { ni: 11 nj: 11 }
00010 // pt_index: 31 // Which point to use
00011 // res_level: 1
00012 // model_path: patch_model.bfs
00013 //
00014 // image_dir: ../images/
00015 // points_dir: ../points/
00016 // images: {
00017 //   image1.pts : image1.jpg
00018 //   image2.pts : image2.jpg
00019 // }
00020 // \endcode
00021 
00022 #include <mbl/mbl_parse_colon_pairs_list.h>
00023 #include <mbl/mbl_read_props.h>
00024 #include <mbl/mbl_exception.h>
00025 
00026 #include <vul/vul_arg.h>
00027 #include <vul/vul_string.h>
00028 #include <vsl/vsl_quick_file.h>
00029 #include <vsl/vsl_binary_loader.h>
00030 
00031 #include <mfpf/mfpf_point_finder.h>
00032 #include <mfpf/mfpf_point_finder_builder.h>
00033 #include <mfpf/mfpf_add_all_loaders.h>
00034 
00035 #include <vil/vil_load.h>
00036 #include <vil/vil_save.h>
00037 #include <vil/vil_convert.h>
00038 #include <vimt/vimt_image_2d_of.h>
00039 #include <vimt/vimt_image_pyramid.h>
00040 #include <vimt/vimt_gaussian_pyramid_builder_2d.h>
00041 
00042 #include <msm/msm_points.h>
00043 #include <vcl_cmath.h>
00044 #include <vcl_cassert.h>
00045 #include <vcl_sstream.h>
00046 
00047 //: Structure to hold parameters
00048 struct tool_params
00049 {
00050   //: Path to which to save the model
00051   vcl_string model_path;
00052 
00053   //: Resolution level at which to build model
00054   unsigned res_level;
00055 
00056   //: Index of point to use to train model
00057   unsigned pt_index;
00058 
00059   //: Object to build patch model
00060   vcl_auto_ptr<mfpf_point_finder_builder> patch_builder;
00061 
00062   //: Image directory
00063   vcl_string image_dir;
00064 
00065   //: Points directory
00066   vcl_string points_dir;
00067 
00068   //: List of image filenames
00069   vcl_vector<vcl_string> image_names;
00070 
00071   //: List of points filenames
00072   vcl_vector<vcl_string> points_names;
00073 
00074   // Constructor to set defaults
00075   tool_params();
00076 
00077   //: Parse named text file to read in data
00078   //  Throws a upf_exception_parse_error if fails
00079   void read_from_file(const vcl_string& path);
00080 };
00081 
00082 tool_params::tool_params()
00083 {
00084 }
00085 
00086 //: Parse named text file to read in data
00087 //  Throws a upf_exception_parse_error if fails
00088 void tool_params::read_from_file(const vcl_string& path)
00089 {
00090   vcl_ifstream ifs(path.c_str());
00091   if (!ifs)
00092   {
00093     vcl_string error_msg = "Failed to open file: "+path;
00094     throw (mbl_exception_parse_error(error_msg));
00095   }
00096 
00097   mbl_read_props_type props;
00098   props = mbl_read_props_ws(ifs);
00099 
00100   model_path=props.get_required_property("model_path");
00101   image_dir=props.get_required_property("image_dir");
00102   points_dir=props.get_required_property("points_dir");
00103 
00104   mbl_parse_colon_pairs_list(props.get_required_property("images"),
00105                              points_names,image_names);
00106 
00107   res_level = vul_string_atoi(props.get_optional_property("res_level","0"));
00108   pt_index = vul_string_atoi(props.get_optional_property("pt_index","0"));
00109 
00110   vcl_string builder_str= props.get_required_property("patch_builder");
00111   vcl_istringstream iss(builder_str);
00112   patch_builder = mfpf_point_finder_builder::create_from_stream(iss);
00113 
00114   try {
00115     mbl_read_props_look_for_unused_props(
00116       "::read_from_file", props, mbl_read_props_type());
00117   }
00118   catch (mbl_exception_unused_props& e)
00119   {
00120     throw (mbl_exception_parse_error(e.what()));
00121   }
00122 }
00123 
00124 void print_usage()
00125 {
00126   vcl_cout<<"mfpf_build_finder -p param_file\n"
00127           <<"Tool to build a finder from a set of training images\n"
00128           <<vcl_endl;
00129 }
00130 
00131 int main(int argc, char** argv)
00132 {
00133   vul_arg<vcl_string> param_path("-p","Parameter filename");
00134 
00135   vul_arg_parse(argc,argv);
00136 
00137   if (param_path()=="")
00138   {
00139     print_usage();
00140     return 0;
00141   }
00142 
00143   mfpf_add_all_loaders();
00144 
00145   tool_params params;
00146   try { params.read_from_file(param_path()); }
00147   catch (mbl_exception_parse_error& e)
00148   {
00149     vcl_cerr<<"Error: "<<e.what()<<vcl_endl;
00150     return 1;
00151   }
00152 
00153   unsigned n_images = params.image_names.size();
00154 
00155   vimt_gaussian_pyramid_builder_2d<float> pyr_builder;
00156 
00157   params.patch_builder->set_step_size(vcl_pow(2.0,double(params.res_level)));
00158   params.patch_builder->clear(n_images);
00159 
00160   vgl_vector_2d<double> u(1,0);  // Default to unit scale and fixed angle
00161 
00162   for (unsigned i=0;i<n_images;++i)
00163   {
00164     // Load in image
00165     vil_image_view<vxl_byte> byte_image;
00166     vcl_string image_path = params.image_dir+"/"+params.image_names[i];
00167     byte_image = vil_load(image_path.c_str());
00168     if (byte_image.size()==0)
00169     {
00170       vcl_cerr<<"Failed to load in image from "<<image_path<<vcl_endl;
00171       return 2;
00172     }
00173 
00174     // Convert to float image and build pyramid
00175     vimt_image_2d_of<float> image;
00176     if (byte_image.nplanes()==1)
00177       vil_convert_cast(byte_image,image.image());
00178     else
00179       vil_convert_planes_to_grey(byte_image,image.image());
00180 
00181     vimt_image_pyramid image_pyr;
00182     pyr_builder.build(image_pyr,image);
00183 
00184     assert(int(params.res_level)<=image_pyr.hi());
00185 
00186     // Select relevant level from pyramid
00187     const vimt_image_2d_of<float>& imageL
00188       = static_cast<const vimt_image_2d_of<float>&>(image_pyr(params.res_level));
00189 
00190     // Load in points
00191     msm_points points;
00192     vcl_string points_path = params.points_dir + "/"
00193                            + params.points_names[i];
00194 
00195     if (!points.read_text_file(points_path))
00196     {
00197       vcl_cerr<<"Failed to load points from "<<points_path<<vcl_endl;
00198       return 3;
00199     }
00200 
00201     vgl_point_2d<double> p = points[params.pt_index];
00202 
00203     params.patch_builder->add_example(imageL,p,u);
00204   }
00205 
00206   // Create and build a model
00207   mfpf_point_finder *finder = params.patch_builder->new_finder();
00208   params.patch_builder->build(*finder);
00209 
00210   vcl_cout<<"Finder: "<<*finder<<vcl_endl;
00211 
00212   vsl_quick_file_save(finder,params.model_path);
00213 
00214   vimt_image_2d_of<vxl_byte> model_image;
00215   finder->get_image_of_model(model_image);
00216   vcl_string patch_image_path = "./model_patch.jpg";
00217   if (vil_save(model_image.image(),patch_image_path.c_str()))
00218     vcl_cout<<"Saved patch image to "<<patch_image_path<<vcl_endl;
00219 
00220   delete finder;
00221 
00222   return 0;
00223 }
00224