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
00155 vector<int> indices_pp;
00156 vector<int> indices_keys;
00157
00158 findClosestPoints(surf.keys, pixelpoints, indices_keys, indices_pp);
00159
00160
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
00171 const string key_file = path + "/" + name + ".key.gz";
00172 final_surf.Save(key_file);
00173
00174
00175 const string map_file = path + "/" + name + "_2d3d.txt";
00176
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.;
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
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