📄 sift-driver.cpp
字号:
// file: sift-driver.cpp// author: Andrea Vedaldi// description: SIFT command line utility implementation// AUTORIGTHS#include<sift.hpp>#include<string>#include<iostream>#include<iomanip>#include<fstream>#include<sstream>#include<algorithm>extern "C" {#include<getopt.h>#if defined (VL_MAC)#include<libgen.h>#else#include<string.h>#endif#include<assert.h>}using namespace std ;size_t const not_found = numeric_limits<size_t>::max() - 1 ;// case insensitive character comparisoninlinebool ciIsEqual(char a, char b){ return tolower((char unsigned)a) == tolower((char unsigned)b);}// case insensitive extension removalstringremoveExtension(string name, string ext){ string::iterator pos = find_end(name.begin(),name.end(),ext.begin(),ext.end(),ciIsEqual) ; // make sure the occurence is at the end if(pos+ext.size() == name.end()) { return name.substr(0, pos-name.begin()) ; } else { return name ; }}// to manipulate keypoint liststypedef vector<pair<VL::Sift::Keypoint,VL::float_t> > Keypoints ;bool cmpKeypoints (Keypoints::value_type const&a, Keypoints::value_type const&b) { // return a.first.o < b.first.o ; return a.first.sigma < b.first.sigma ;}intmain(int argc, char** argv){ int first = -1 ; int octaves = -1 ; int levels = 3 ; float threshold = 0.04f / levels / 2.0f ; float edgeThreshold = 10.0f; int nodescr = 0 ; int noorient = 0 ; int stableorder = 0 ; int savegss = 0 ; int verbose = 0 ; int binary = 0 ; int haveKeypoints = 0 ; string outputFilenamePrefix ; string outputFilename ; string descriptorsFilename ; string keypointsFilename ; static struct option longopts[] = { { "verbose", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { "output", required_argument, NULL, 'o' }, { "prefix", required_argument, NULL, 'p' }, { "first-octave", required_argument, NULL, 'f' }, { "keypoints", required_argument, NULL, 'k' }, { "octaves", required_argument, NULL, 'O' }, { "levels", required_argument, NULL, 'S' }, { "threshold", required_argument, NULL, 't' }, { "edge-threshold", required_argument, NULL, 'e' }, { "binary", no_argument, NULL, 'b' }, { "no-descriptors", no_argument, &nodescr, 1 }, { "no-orientations", no_argument, &noorient, 1 }, { "stable-order", no_argument, &stableorder, 1 }, { "save-gss", no_argument, &savegss, 1 }, { NULL, 0, NULL, 0 } }; int ch ; try { while ( (ch = getopt_long(argc, argv, "hvftebk:p:o:O:S:", longopts, NULL)) != -1) { switch (ch) { case '?' : VL_THROW("Invalid option '"<<argv[optind-1]<<"'.") ; break; case ':' : VL_THROW("Missing option argument for '"<<argv[optind-1]<<"'.") ; break; case 'h' : std::cout << argv[0] << " [--verbose|=v] [--help|-h]" << endl << " [--output|-o NAME] [--prefix|-p PREFIX] [--binary|-b] [--save-gss] " << endl << " [--no-descriptors] [--no-orientations] " << endl << " [--levels|-S NUMBER] [--octaves|-O NUMBER] [--first-octave|-f NUMBER] " << endl << " [--threshold|-t NUMBER] [--edge-threshold|-e NUMBER] " << endl << " IMAGE [IMAGE2 ...]" << endl << endl << "* Options *" <<endl << " --verbose Be verbose"<<endl << " --help Print this message"<<endl << " --output=NAME Write to this file"<<endl << " --prefix=PREFIX Derive output filename prefixing this string to the input file"<<endl << " --binary Write descriptors to a separate file in binary format"<<endl << " --keypoints=FILE Reads keypoint frames from here; do not run SIFT detector" << endl << " --save-gss Save Gaussian scale space on disk" << endl << " --octaves=O Number of octaves" << endl << " --levels=S Number of levels per octave" << endl << " --first-octave=MINO Index of the first octave" << endl << " --threshold=THR Keypoint strength threhsold" << endl << " --edge-threshold=THR On-edge threshold" << endl << " --no-descriptors Do not compute descriptors" << endl << " --no-orientations Do not compute orientations" << endl << " --stable-order Do not reorder keypoints" << endl << endl << " * Examples *" << endl << argv[0] << " [OPTS...] image.pgm" << endl << argv[0] << " [OPTS...] image.pgm --output=file.key" << endl << argv[0] << " [OPTS...] image.pgm --keypoints=frames.key" << endl << argv[0] << " [OPTS...] *.pgm --prefix=/tmp/" << endl << argv[0] << " [OPTS...] *.pgm --prefix=/tmp/ --binary" << endl << endl << " * This build: " ;#if defined VL_USEFASTMATH std::cout << "has fast approximate math" ;#else std::cout << "has slow accurate math" ;#endif std::cout << " (fp datatype is '" << VL_EXPAND_AND_STRINGIFY(VL_FASTFLOAT) << "') *"<<endl ; return 0 ; case 'v' : // verbose verbose = 1 ; break ; case 'f': // first octave { std::istringstream iss(optarg) ; iss >> first ; if( iss.fail() ) VL_THROW("Invalid argument '" << optarg << "'.") ; } break ; case 'O' : // octaves { std::istringstream iss(optarg) ; iss >> octaves ; if( iss.fail() ) VL_THROW("Invalid argument '" << optarg << "'.") ; if( octaves < 1 ) { VL_THROW("Number of octaves cannot be smaller than one."); } } break ; case 'S' : // levels { std::istringstream iss(optarg) ; iss >> levels ; if( iss.fail() ) VL_THROW("Invalid argument '" << optarg << "'.") ; if( levels < 1 ) { VL_THROW("Number of levels cannot be smaller than one.") ; } } break ; case 't' : // threshold { std::istringstream iss(optarg) ; iss >> threshold ; if( iss.fail() ) VL_THROW("Invalid argument '" << optarg << "'.") ; } break ; case 'e' : // edge-threshold { std::istringstream iss(optarg) ; iss >> edgeThreshold ; if( iss.fail() ) VL_THROW("Invalid argument '" << optarg << "'.") ; } break ; case 'o' : // output filename { outputFilename = std::string(optarg) ; break ; } case 'p' : // output prefix { outputFilenamePrefix = std::string(optarg) ; break ; } case 'k' : // keypoint file { keypointsFilename = std::string(optarg) ; haveKeypoints = 1 ; break ; } case 'b' : // binary output of descriptors { binary = 1 ; break ; } case 0 : // all other options break ; default: assert(false) ; } } argc -= optind; argv += optind; // check for argument consistency if(argc == 0) VL_THROW("No input image specfied.") ; if(outputFilename.size() != 0 && (argc > 1 | binary)) { VL_THROW("--output cannot be used with multiple images or --binary.") ; } if(outputFilename.size() !=0 && outputFilenamePrefix.size() !=0) { VL_THROW("--output cannot be used in combination with --prefix.") ; } } catch( VL::Exception const & e ) { std::cerr<<"error: "<<e.msg<<std::endl ; exit(1) ; } // ----------------------------------------------------------------- // Loop over input images // ----------------------------------------------------------------- while( argc > 0 ) { string name(argv[0]) ; try { VL::PgmBuffer buffer ; // compute the output filenames: // // 1) if --output is specified, then we just use the one provided // by the user // // 2) if --output is not specified, we derive the output filename // from the input filename by // - removing the extension part from the output filename // - and if outputFilenamePrefix is non void, removing // the directory part and prefixing outputFilenamePrefix. // // 3) in any case we derive the binary descriptor filename by // removing from the output filename the .key extension (if any) // and adding a .desc extension. //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -