extractSurf.cpp
Go to the documentation of this file.
00001 
00035 #include <iostream>
00036 #include <fstream>
00037 #include <opencv/cv.h>
00038 #include <opencv/highgui.h>
00039 #include <string>
00040 #include <vector>
00041 
00042 #include "Mask.h"
00043 
00044 #include "DUtils.h"
00045 #include "DUtilsCV.h"
00046 #include "DVision.h"
00047 
00048 typedef DVision::PixelPointFile::PixelPoint PixelPoint;
00049 typedef DVision::SurfSet SurfSet;
00050 
00051 using namespace std;
00052 
00053 void treatDirectory(const std::string &img_dir, const float fast_th);
00054 
00055 void removeSurfPoints(SurfSet &surf, const vector<unsigned int> &i_remove);
00056 
00057 void findClosestPoints(vector<cv::KeyPoint> &keys, 
00058   const vector<PixelPoint> &pixelpoints, 
00059   vector<int> &indices_keys,
00060   vector<int> &indices_pp);
00061 
00062 void getPoints(const SurfSet &surf, const vector<PixelPoint> &pixelpoints, 
00063   const vector<int> &indices_keys, const vector<int> &indices_pp, 
00064   SurfSet &final_surf, vector<PixelPoint> &final_pixelpoints);
00065 
00066 void saveGlobalIndices(const std::string &filename, 
00067   const vector<int> &indices2d, 
00068   const vector<PixelPoint> &pixelpoints);
00069 
00070 // ----------------------------------------------------------------------------
00071 
00072 int main(int argc, char *argv[])
00073 {
00074 
00075   if(argc < 2)
00076   {
00077     cout << "Usage: " << argv[0] << " <img dir> [SURF th = 400]"
00078       << endl;
00079     return 1;
00080   }
00081 
00082   string img_dir = argv[1];
00083   float surf_th = 400.f;
00084   if(argc >= 3) surf_th = atof(argv[2]);
00085   
00086   try
00087   {
00088     treatDirectory(img_dir, surf_th);
00089   }
00090   catch(std::string ex)
00091   {
00092     cout << ex << endl;
00093   }
00094 
00095   return 0;
00096 
00097 }
00098 
00099 // ---------------------------------------------------------------------------- 
00100 
00101 void treatDirectory(const std::string &img_dir, const float surf_th)
00102 {
00103   const int MARGIN = 5;
00104   
00105   vector<string> img_files = 
00106     DUtils::FileFunctions::Dir(img_dir.c_str(), ".jpg", true);
00107   
00108   cout << "-- " << img_files.size() << " images read" << endl; 
00109   
00110   for(unsigned int i = 0; i < img_files.size(); ++i)
00111   {
00112     const string& img_file = img_files[i];
00113     
00114     cout << img_file << "..." << endl;
00115     
00116     string path, name, ext;
00117     DUtils::FileFunctions::FileParts(img_file, path, name, ext);
00118     
00119     const string pp_file = path + "/" + name + "_points.txt";
00120     const string mask_file = path + "/" + name + "_mask.png";
00121     
00122     vector<PixelPoint> pixelpoints;
00123     DVision::PixelPointFile::readFile(pp_file, pixelpoints);
00124     
00125     cout << "-- " << pixelpoints.size() << " PixelPoints read from "
00126       << pp_file << endl;
00127     
00128     cv::Mat im = cv::imread(img_file, 0);
00129     
00130     if(im.empty())
00131     {
00132       throw string("Could not open image ") + img_file;
00133     }
00134     
00135     DVision::SurfSet surf;
00136     surf.Extract(im, surf_th, false);
00137     
00138     cout << "-- " << surf.size() << " SURF keypoints extracted" << endl;
00139     
00140     vector<unsigned int> i_out;
00141     
00142     Mask mask(mask_file.c_str());
00143     
00144     if(mask.empty())
00145     {
00146       throw string("Could not open mask ") + mask_file;
00147     }
00148     
00149     mask.shrink(MARGIN);
00150     mask.getPointsOutsideMask(surf.keys, i_out);
00151     
00152     removeSurfPoints(surf, i_out);
00153 
00154     // associate each fast keypoint with a 3d point
00155     vector<int> indices_pp; // indices of the pixelpoint vector
00156     vector<int> indices_keys;
00157     
00158     findClosestPoints(surf.keys, pixelpoints, indices_keys, indices_pp);
00159     
00160     // create final surfset and pixel points
00161     DVision::SurfSet final_surf;
00162     vector<PixelPoint> final_pixelpoints;
00163     
00164     getPoints(surf, pixelpoints, indices_keys, indices_pp, final_surf,
00165       final_pixelpoints);
00166     
00167     cout << "-- " << final_pixelpoints.size() << " final PixelPoints "
00168       "associated to SURF features" << endl;
00169     
00170     // save surviving surf
00171     const string key_file = path + "/" + name + ".key.gz";
00172     final_surf.Save(key_file);
00173     
00174     // save surviving plypoints
00175     const string map_file = path + "/" + name + "_2d3d.txt";
00176     // global indices of 3d features
00177     saveGlobalIndices(map_file, indices_pp, pixelpoints);
00178   }
00179 
00180 }
00181 
00182 // ----------------------------------------------------------------------------
00183 
00184 void removeSurfPoints(SurfSet &surf, const vector<unsigned int> &i_remove)
00185 {
00186   const int L = surf.GetDescriptorLength();
00187   
00188   vector<unsigned int> i_remove_desc;
00189   i_remove_desc.reserve(i_remove.size() * L);
00190   
00191   for(unsigned int i = 0; i < i_remove.size(); ++i)
00192   {
00193     int idx = i_remove[i];
00194     
00195     for(int j = 0; j < L; ++j)
00196     {
00197       i_remove_desc.push_back(idx * L + j);
00198     }
00199   }
00200   
00201   DUtils::STL::removeIndices(surf.keys, i_remove, true);
00202   DUtils::STL::removeIndices(surf.laplacians, i_remove, true);
00203   DUtils::STL::removeIndices(surf.descriptors, i_remove_desc, true);
00204 }
00205 
00206 // ----------------------------------------------------------------------------
00207 
00208 void findClosestPoints(vector<cv::KeyPoint> &keys, 
00209   const vector<PixelPoint> &pixelpoints, 
00210   vector<int> &indices_keys,
00211   vector<int> &indices_pp)
00212 {
00213   const double MAX_DIST = 2.; // px
00214   
00215   indices_keys.clear();
00216   indices_pp.clear();
00217   
00218   for(unsigned int i_k = 0; i_k < keys.size(); ++i_k)
00219   {
00220     const cv::KeyPoint &k = keys[i_k];
00221     
00222     double best_d = 1e9;
00223     int best_pp = -1;
00224     
00225     for(unsigned int i_pp = 0; i_pp < pixelpoints.size(); ++i_pp)
00226     {
00227       const PixelPoint &p = pixelpoints[i_pp];
00228       
00229       double sqd = (k.pt.x - p.u)*(k.pt.x - p.u) + (k.pt.y - p.v)*(k.pt.y - p.v);
00230       
00231       if(sqd < best_d)
00232       {
00233         best_d = sqd;
00234         best_pp = i_pp;
00235       }
00236     }
00237     
00238     if(best_pp > -1 && sqrt(best_d) <= MAX_DIST)
00239     {
00240       // check this points was not already set
00241       if(indices_pp.end() == find(indices_pp.begin(), indices_pp.end(), best_pp))
00242       {
00243         indices_pp.push_back(best_pp);
00244         indices_keys.push_back(i_k);
00245       }
00246     }
00247   }
00248   
00249 }
00250 
00251 // ----------------------------------------------------------------------------
00252 
00253 void getPoints(const SurfSet &surf, const vector<PixelPoint> &pixelpoints, 
00254   const vector<int> &indices_keys, const vector<int> &indices_pp, 
00255   SurfSet &final_surf, vector<PixelPoint> &final_pixelpoints)
00256 {
00257   final_surf.keys.clear();
00258   final_surf.laplacians.clear();
00259   final_surf.descriptors.clear();
00260   final_pixelpoints.clear();
00261   
00262   const int L = surf.GetDescriptorLength();
00263   
00264   vector<int>::const_iterator it;
00265   
00266   for(it = indices_keys.begin(); it != indices_keys.end(); ++it)
00267   {
00268     int idx = *it;
00269     final_surf.keys.push_back( surf.keys[idx] );
00270     final_surf.laplacians.push_back( surf.laplacians[idx] );
00271     
00272     for(int j = 0; j < L; ++j)
00273     {
00274       final_surf.descriptors.push_back( surf.descriptors[idx * L + j] );
00275     }
00276   }
00277   
00278   for(it = indices_pp.begin(); it != indices_pp.end(); ++it)
00279   {
00280     int idx = *it;
00281     final_pixelpoints.push_back(pixelpoints[idx]);
00282   }
00283   
00284 }
00285 
00286 // ----------------------------------------------------------------------------
00287 
00288 void saveGlobalIndices(const std::string &filename, 
00289   const vector<int> &indices2d, 
00290   const vector<PixelPoint> &pixelpoints)
00291 {
00292   fstream f(filename.c_str(), ios::out);
00293   
00294   f << indices2d.size() << endl;
00295   
00296   vector<int>::const_iterator iit;
00297   for(iit = indices2d.begin(); iit != indices2d.end(); ++iit)
00298   {
00299     int i3d = pixelpoints[*iit].idx;
00300     f << (iit - indices2d.begin()) << " " << i3d << endl;
00301   }
00302   
00303   f.close();
00304 }
00305 
00306 // ----------------------------------------------------------------------------
00307 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:08