00001
00002
00003
00004
00005
00006
00007 #include "sift.hpp"
00008 #include "sift-driver.hpp"
00009
00010 #include<string>
00011 #include<iostream>
00012 #include<iomanip>
00013 #include<fstream>
00014 #include<sstream>
00015 #include<algorithm>
00016 #include <memory>
00017 #include <stdint.h>
00018
00019 extern "C" {
00020 #include<getopt.h>
00021 #if defined (VL_MAC)
00022 #include<libgen.h>
00023 #else
00024 #include<string.h>
00025 #endif
00026 #include<assert.h>
00027 }
00028
00029 #include "libgen_emu.h"
00030
00031 #ifndef no_argument
00032 #define no_argument NO_ARG
00033 #endif
00034 #ifndef required_argument
00035 #define required_argument REQUIRED_ARG
00036 #endif
00037
00038 using namespace std ;
00039
00040 size_t const not_found = numeric_limits<size_t>::max() - 1 ;
00041
00042
00043
00044
00045
00046
00047
00048
00049 inline
00050 bool ciIsEqual(char a, char b)
00051 {
00052 return
00053 tolower((char unsigned)a) ==
00054 tolower((char unsigned)b) ;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064 string
00065 removeExtension(string name, string ext)
00066 {
00067 string::iterator pos =
00068 find_end(name.begin(),name.end(),ext.begin(),ext.end(),ciIsEqual) ;
00069
00070
00071 if(pos+ext.size() == name.end()) {
00072 return name.substr(0, pos-name.begin()) ;
00073 } else {
00074 return name ;
00075 }
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 std::ostream&
00090 insertDescriptor(std::ostream& os,
00091 VL::float_t const * descr_pt,
00092 bool binary,
00093 bool fp,
00094 int* numKeypoints,
00095 vector<double>* keyValues,
00096 bool outGood)
00097 {
00098 (*numKeypoints)++;
00099
00100 #define RAW_CONST_PT(x) reinterpret_cast<char const*>(x)
00101 #define RAW_PT(x) reinterpret_cast<char*>(x)
00102
00103 if( fp ) {
00104
00105
00106 VL::float32_t fdescr_pt [128] ;
00107 for(int i = 0 ; i < 128 ; ++i){
00108 fdescr_pt[i] = VL::float32_t( descr_pt[i]) ;
00109 keyValues->push_back((double)(fdescr_pt[i]));
00110 }
00111
00112 if( binary ) {
00113
00114
00115
00116
00117 short int const word = 0x0001 ;
00118 bool little_endian = RAW_CONST_PT(&word)[0] ;
00119
00120
00121
00122
00123
00124 if( little_endian ) {
00125 for(int i = 0 ; i < 128 ; ++i) {
00126 VL::float32_t tmp = fdescr_pt[ i ] ;
00127 char* pt = RAW_PT(fdescr_pt + i) ;
00128 char* spt = RAW_PT(&tmp) ;
00129 pt[0] = spt[3] ;
00130 pt[1] = spt[2] ;
00131 pt[2] = spt[1] ;
00132 pt[3] = spt[0] ;
00133 }
00134 }
00135 if (outGood) os.write( RAW_PT(fdescr_pt), 128 * sizeof(VL::float32_t) ) ;
00136
00137 } else {
00138
00139 if (outGood)
00140 for(int i = 0 ; i < 128 ; ++i)
00141 os << ' '
00142 << fdescr_pt[i] ;
00143 }
00144
00145 } else {
00146
00147 VL::uint8_t idescr_pt [128] ;
00148
00149 for(int i = 0 ; i < 128 ; ++i){
00150 idescr_pt[i] = uint8_t(float_t(512) * descr_pt[i]) ;
00151 keyValues->push_back((double)(idescr_pt[i]));
00152 }
00153
00154 if( binary ) {
00155
00156 if (outGood) os.write( RAW_PT(idescr_pt), 128) ;
00157
00158 } else {
00159 if (outGood)
00160 for(int i = 0 ; i < 128 ; ++i)
00161 os << ' '
00162 << uint32_t( idescr_pt[i] ) ;
00163 }
00164 }
00165 return os ;
00166 }
00167
00168 std::ostream&
00169 insertDescriptor(std::ostream& os,
00170 VL::float_t const * descr_pt,
00171 bool binary,
00172 bool fp,
00173 int* numKeypoints,
00174 vector<double>* keyValues)
00175 {
00176 return insertDescriptor(os, descr_pt, binary, fp, numKeypoints, keyValues, true);
00177 }
00178
00179
00180 typedef vector<pair<VL::Sift::Keypoint,VL::float_t> > Keypoints ;
00181
00182
00183 bool cmpKeypoints (Keypoints::value_type const&a,
00184 Keypoints::value_type const&b) {
00185 return a.first.sigma < b.first.sigma ;
00186 }
00187
00188
00189
00190
00191 VL::Sift*
00192 siftdriver(int argc, char** argv, int* numKeypoints, vector<double>* keyValues, vector< vector< vector<int> > >& gaussianSpace)
00193 {
00194 return siftdriver(argc, argv, numKeypoints, keyValues, gaussianSpace, NULL, 0, 0);
00195 }
00196
00197 VL::Sift*
00198 siftdriver(int argc, char** argv, int* numKeypoints, vector<double>* keyValues, vector< vector< vector<int> > >& gaussianSpace, VL::pixel_t* data, int width, int height)
00199 {
00200
00201
00202
00203 if (numKeypoints) *numKeypoints = 0;
00204
00205 VL::Sift* sift = NULL;
00206
00207 int first = -1 ;
00208 int octaves = -1 ;
00209 int levels = 3 ;
00210 float threshold = 0.04f / levels / 2.0f ;
00211 float edgeThreshold = 10.0f;
00212 float magnif = 1.5f ;
00213 int nodescr = 0 ;
00214 int noorient = 0 ;
00215 int stableorder = 0 ;
00216 int savegss = 0 ;
00217 int verbose = 0 ;
00218 int binary = 0 ;
00219 int haveKeypoints = 0 ;
00220 int unnormalized = 0 ;
00221 int fp = 0 ;
00222
00223
00224
00225 int imageProvided = 0;
00226 string outputFilenamePrefix ;
00227 string outputFilename ;
00228 string descriptorsFilename ;
00229 string keypointsFilename ;
00230
00231 struct option longopts[] = {
00232 { "verbose", no_argument, NULL, 'v' },
00233 { "help", no_argument, NULL, 'h' },
00234 { "output", required_argument, NULL, 'o' },
00235 { "prefix", required_argument, NULL, 'p' },
00236 { "first-octave", required_argument, NULL, 'f' },
00237 { "keypoints", required_argument, NULL, 'k' },
00238 { "octaves", required_argument, NULL, 'O' },
00239 { "levels", required_argument, NULL, 'S' },
00240 { "threshold", required_argument, NULL, 't' },
00241 { "edge-threshold", required_argument, NULL, 'e' },
00242 { "magnif", required_argument, NULL, 'm' },
00243 { "binary", no_argument, NULL, 'b' },
00244 { "no-descriptors", no_argument, &nodescr, 1 },
00245 { "no-orientations", no_argument, &noorient, 1 },
00246 { "stable-order", no_argument, &stableorder, 1 },
00247 { "save-gss", no_argument, &savegss, 1 },
00248 { "unnormalized", no_argument, &unnormalized, 1 },
00249 { "floating-point", no_argument, &fp, 1 },
00250 { "image-provided", no_argument, &imageProvided, 1 },
00251 { NULL, 0, NULL, 0 }
00252 };
00253
00254 int ch ;
00255
00256 try {
00257 optind = 0;
00258 opterr = 1;
00259 while ( (ch = getopt_long(argc, argv, "vho:p:f:k:O:S:t:e:b", longopts, NULL)) != -1 ) {
00260 switch (ch) {
00261
00262 case '?' :
00263 VL_THROW("Invalid option '"<<argv[optind-1]<<"'.") ;
00264 std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
00265 break;
00266
00267 case ':' :
00268 VL_THROW("Missing argument of option '"<<argv[optind-1]<<"'.") ;
00269 break;
00270
00271 case 'h' :
00272 std::cout
00273 << argv[0] << " [--verbose|=v] [--help|-h]" << endl
00274 << " [--output|-o NAME] [--prefix|-p PREFIX] [--binary|-b] [--save-gss] " << endl
00275 << " [--no-descriptors] [--no-orientations] " << endl
00276 << " [--levels|-S NUMBER] [--octaves|-O NUMBER] [--first-octave|-f NUMBER] " << endl
00277 << " [--threshold|-t NUMBER] [--edge-threshold|-e NUMBER] " << endl
00278 << " [--floating-point] [--unnormalized] " << endl
00279 << " IMAGE [IMAGE2 ...]" << endl
00280 << endl
00281 << "* Options *" << endl
00282 << " --verbose Be verbose"<< endl
00283 << " --help Print this message"<<endl
00284 << " --output=NAME Write to this file"<<endl
00285 << " --prefix=PREFIX Derive output filename prefixing this string to the input file"<<endl
00286 << " --binary Write descriptors to a separate file in binary format"<<endl
00287 << " --keypoints=FILE Reads keypoint frames from here; do not run SIFT detector" << endl
00288 << " --save-gss Save Gaussian scale space on disk" << endl
00289 << " --octaves=O Number of octaves" << endl
00290 << " --levels=S Number of levels per octave" << endl
00291 << " --first-octave=MINO Index of the first octave" << endl
00292 << " --threshold=THR Keypoint strength threhsold" << endl
00293 << " --magnif=MAG Keypoint magnification" << endl
00294 << " --edge-threshold=THR On-edge threshold" << endl
00295 << " --no-descriptors Do not compute descriptors" << endl
00296 << " --no-orientations Do not compute orientations" << endl
00297 << " --stable-order Do not reorder keypoints" << endl
00298 << " --unnormalzied Do not normalize descriptors" << endl
00299 << " --floating-point Save floating point descriptors" << endl
00300 << endl
00301 << " * Examples *" << endl
00302 << argv[0] << " [OPTS...] image.pgm" << endl
00303 << argv[0] << " [OPTS...] image.pgm --output=file.key" << endl
00304 << argv[0] << " [OPTS...] image.pgm --keypoints=frames.key" << endl
00305 << argv[0] << " [OPTS...] *.pgm --prefix=/tmp/" << endl
00306 << argv[0] << " [OPTS...] *.pgm --prefix=/tmp/ --binary" << endl
00307 << endl
00308 << " * This build: " ;
00309 #if defined VL_USEFASTMATH
00310 std::cout << "has fast approximate math" ;
00311 #else
00312 std::cout << "has slow accurate math" ;
00313 #endif
00314 std::cout << " (fp datatype is '"
00315 << VL_EXPAND_AND_STRINGIFY(VL_FASTFLOAT)
00316 << "') *"<<endl ;
00317 return NULL ;
00318
00319 case 'v' :
00320 verbose = 1 ;
00321 break ;
00322
00323 case 'f':
00324 {
00325 std::istringstream iss(optarg) ;
00326 iss >> first ;
00327 if( iss.fail() )
00328 VL_THROW("Invalid argument '" << optarg << "'.") ;
00329 }
00330 break ;
00331
00332 case 'O' :
00333 {
00334 std::istringstream iss(optarg) ;
00335 iss >> octaves ;
00336 if( iss.fail() )
00337 VL_THROW("Invalid argument '" << optarg << "'.") ;
00338 if( octaves < 1 ) {
00339 VL_THROW("The number of octaves cannot be smaller than one.");
00340 }
00341 }
00342 break ;
00343
00344 case 'S' :
00345 {
00346 std::istringstream iss(optarg) ;
00347 iss >> levels ;
00348 if( iss.fail() )
00349 VL_THROW("Invalid argument '" << optarg << "'.") ;
00350 if( levels < 1 ) {
00351 VL_THROW("The number of levels cannot be smaller than one.") ;
00352 }
00353 }
00354 break ;
00355
00356 case 't' :
00357 {
00358 std::istringstream iss(optarg) ;
00359 iss >> threshold ;
00360 if( iss.fail() )
00361 VL_THROW("Invalid argument '" << optarg << "'.") ;
00362 }
00363 break ;
00364
00365 case 'e' :
00366 {
00367 std::istringstream iss(optarg) ;
00368 iss >> edgeThreshold ;
00369 if( iss.fail() )
00370 VL_THROW("Invalid argument '" << optarg << "'.") ;
00371 }
00372 break ;
00373
00374 case 'm' :
00375 {
00376 std::istringstream iss(optarg) ;
00377 iss >> magnif ;
00378 if( iss.fail() )
00379 VL_THROW("Invalid argument '" << optarg << "'.") ;
00380 }
00381 break ;
00382
00383
00384 case 'o' :
00385 {
00386 outputFilename = std::string(optarg) ;
00387 break ;
00388 }
00389
00390 case 'p' :
00391 {
00392 outputFilenamePrefix = std::string(optarg) ;
00393 break ;
00394 }
00395
00396 case 'k' :
00397 {
00398 keypointsFilename = std::string(optarg) ;
00399 haveKeypoints = 1 ;
00400 break ;
00401 }
00402
00403 case 'b' :
00404 {
00405 binary = 1 ;
00406 break ;
00407 }
00408
00409 case 0 :
00410 break ;
00411
00412 default:
00413 assert(false) ;
00414 }
00415 }
00416
00417 argc -= optind;
00418 argv += optind;
00419
00420
00421 if(argc == 0) VL_THROW("No input image specfied.") ;
00422 if(outputFilename.size() != 0 && ((argc > 1) | binary)) {
00423 VL_THROW("--output cannot be used with multiple images or --binary.") ;
00424 }
00425
00426 if(outputFilename.size() !=0 &&
00427 outputFilenamePrefix.size() !=0) {
00428 VL_THROW("--output cannot be used in combination with --prefix.") ;
00429 }
00430
00431
00432 }
00433 catch( VL::Exception const & e ) {
00434 cerr << "siftpp: error: "
00435 << e.msg
00436 << endl ;
00437 return NULL ;
00438 }
00439
00440
00441
00442
00443 while( (imageProvided == 0 && argc > 0) || imageProvided == 1 ) {
00444
00445 string name(argv[0]) ;
00446
00447 try {
00448 VL::PgmBuffer buffer ;
00449 buffer.data = NULL;
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 if(outputFilename.size() == 0) {
00467
00468 outputFilename = name ;
00469
00470
00471
00472 if(outputFilenamePrefix.size() != 0) {
00473 outputFilename = outputFilenamePrefix +
00474 std::string(libgenEmu_basename(outputFilename.c_str())) ;
00475 }
00476
00477
00478 outputFilename = removeExtension(outputFilename, ".pgm") ;
00479 outputFilename += ".key" ;
00480 }
00481
00482
00483 descriptorsFilename = removeExtension(outputFilename, ".key") ;
00484 descriptorsFilename += ".desc" ;
00485
00486
00487
00488
00489 verbose && cout
00490 << "siftpp: loading PGM image '" << name << "' ..."
00491 << flush;
00492
00493
00494
00495
00496 if (imageProvided == 0){
00497 try {
00498 ifstream in(name.c_str(), ios::binary) ;
00499 if(! in.good()) VL_THROW("Could not open '"<<name<<"'.") ;
00500 extractPgm(in, buffer) ;
00501 }
00502 catch(VL::Exception const& e) {
00503 throw VL::Exception("PGM read error: "+e.msg) ;
00504 }
00505 }else if (imageProvided == 1){
00506 createPgmBufferFromArray(width, height, data, buffer);
00507 imageProvided = 2;
00508 }
00509
00510
00511
00512
00513
00514 verbose && cout
00515 << " read "
00516 << buffer.width <<" x "
00517 << buffer.height <<" pixels"
00518 << endl ;
00519
00520
00521
00522
00523 verbose && cout
00524 << "siftpp: computing Gaussian scale space"
00525 << endl ;
00526
00527 int O = octaves ;
00528 int const S = levels ;
00529 int const omin = first ;
00530 float const sigman = .5f ;
00531 float const sigma0 = 1.6f * powf(2.0f, 1.0f / S) ;
00532
00533
00534
00535 if(O < 1) {
00536 O = std::max
00537 (int
00538 (std::floor
00539 (log2
00540 ((float)std::min(buffer.width,buffer.height))) - omin -3), 1) ;
00541 }
00542
00543 verbose && cout
00544 << "siftpp: number of octaves : " << O << endl
00545 << "siftpp: first octave : " << omin << endl
00546 << "siftpp: levels per octave : " << S
00547 << endl ;
00548
00549
00550 if (sift) delete sift;
00551 sift = new VL::Sift(buffer.data, buffer.width, buffer.height,
00552 sigman, sigma0,
00553 O, S,
00554 omin, -1, S+1) ;
00555
00556 verbose && cout
00557 << "siftpp: Gaussian scale space completed"
00558 << endl ;
00559
00560
00561
00562
00563
00564 if(savegss) {
00565 verbose && cout<<"siftpp: saving Gaussian scale space"<<endl ;
00566
00567 string imageBasename = removeExtension(outputFilename, ".key") ;
00568
00569 for(int o = omin ; o < omin + O ; ++o) {
00570 for(int s = 0 ; s < S ; ++s) {
00571
00572 ostringstream suffix ;
00573 suffix<<'.'<<o<<'.'<<s<<".pgm" ;
00574 string imageFilename = imageBasename + suffix.str() ;
00575
00576 verbose && cout
00577 << "siftpp: octave " << setw(3) << o
00578 << " level " << setw(3) << s
00579 << " to '" << imageFilename
00580 << "' ..." << flush ;
00581
00582 ofstream fout(imageFilename.c_str(), ios::binary) ;
00583 if(!fout.good())
00584 VL_THROW("Could not open '"<<imageFilename<<'\'') ;
00585
00586 VL::insertPgm(fout,
00587 sift->getLevel(o,s),
00588 sift->getOctaveWidth(o),
00589 sift->getOctaveHeight(o)) ;
00590 fout.close() ;
00591
00592 verbose && cout
00593 << " done." << endl ;
00594 }
00595 }
00596 }
00597
00598
00599
00600 for(int o = omin ; o < omin + O ; ++o) {
00601 vector< vector<int> > octaveGaussianSpace;
00602 int octaveWidth = sift->getOctaveWidth(o);
00603 int octaveHeight = sift->getOctaveHeight(o);
00604 for(int s = 0 ; s < S ; ++s) {
00605 vector<int> levelGaussianSpace;
00606 VL::pixel_t* levelSpace = sift->getLevel(o,s);
00607 levelGaussianSpace.push_back(octaveWidth);
00608 levelGaussianSpace.push_back(octaveHeight);
00609 for (int levelRow = 0; levelRow < octaveHeight; levelRow++){
00610 for (int levelCol = 0; levelCol < octaveWidth; levelCol++){
00611 float tempFloat = (std::max(std::min(*levelSpace++, 1.0f),0.f) * 255.0f);
00612 int tempInt = (int)(tempFloat+0.5);
00613 levelGaussianSpace.push_back(tempInt);
00614 }
00615 }
00616 octaveGaussianSpace.push_back(levelGaussianSpace);
00617 }
00618 gaussianSpace.push_back(octaveGaussianSpace);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 if( ! haveKeypoints ) {
00630
00631 verbose && cout
00632 << "siftpp: running detector "<< endl
00633 << "siftpp: threshold : " << threshold << endl
00634 << "siftpp: edge-threshold : " << edgeThreshold
00635 << endl ;
00636
00637 sift->detectKeypoints(threshold, edgeThreshold) ;
00638
00639 verbose && cout
00640 << "siftpp: detector completed with "
00641 << sift->keypointsEnd() - sift->keypointsBegin()
00642 << " keypoints"
00643 << endl ;
00644 }
00645
00646
00647
00648
00649
00650
00651 sift->setNormalizeDescriptor( ! unnormalized ) ;
00652 sift->setMagnification( magnif ) ;
00653
00654 if( verbose ) {
00655 cout << "siftpp: " ;
00656 if( ! noorient & nodescr) cout << "computing keypoint orientations" ;
00657 if( noorient & ! nodescr) cout << "computing keypoint descriptors" ;
00658 if( ! noorient & ! nodescr) cout << "computing orientations and descriptors" ;
00659 if( noorient & nodescr) cout << "finalizing" ;
00660 cout << endl ;
00661 }
00662
00663 {
00664
00665 ofstream out(outputFilename.c_str(), ios::binary) ;
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 int outGood = out.good();
00679 if( ! outGood ) {
00680 verbose && cout << "Could not open output file '" << outputFilename << "'.";
00681 }
00682
00683
00684 verbose && cout
00685 << "siftpp: write keypoints to : '" << outputFilename << "'" << endl
00686 << "siftpp: floating point descr. : " << (fp ? "yes" : "no") << endl
00687 << "siftpp: binary descr. : " << (binary ? "yes" : "no") << endl
00688 << "siftpp: unnormalized descr. : " << (unnormalized ? "yes" : "no") << endl
00689 << "siftpp: descr. magnif. : " << setprecision(3) << magnif
00690 << endl ;
00691
00692 if (outGood) out.flags(ios::fixed) ;
00693
00694
00695 auto_ptr<ifstream> keypointsIn_pt ;
00696
00697 if( haveKeypoints ) {
00698 keypointsIn_pt = auto_ptr<ifstream>
00699 (new ifstream(keypointsFilename.c_str(), ios::binary)) ;
00700
00701 if( ! keypointsIn_pt->good() )
00702 VL_THROW("Could not open keypoints file '"
00703 << keypointsFilename
00704 << "'.") ;
00705
00706 verbose && cout
00707 << "siftpp: read keypoints from : '"
00708 << keypointsFilename << "'"
00709 << endl ;
00710 }
00711
00712
00713 auto_ptr<ofstream> descriptorsOut_pt ;
00714
00715 if( binary ) {
00716 descriptorsOut_pt = auto_ptr<ofstream>
00717 (new ofstream(descriptorsFilename.c_str(), ios::binary)) ;
00718
00719 if( ! descriptorsOut_pt->good() )
00720 VL_THROW("Could not open descriptors file '"
00721 << descriptorsFilename
00722 << "'.") ;
00723
00724 verbose && cout
00725 << "siftpp: write descriptors to : '"
00726 << descriptorsFilename << "'"
00727 << endl ;
00728 }
00729
00730 if( haveKeypoints ) {
00731
00732
00733
00734 Keypoints keypoints ;
00735
00736 while( !keypointsIn_pt->eof() ) {
00737 VL::float_t x,y,sigma,th ;
00738
00739
00740 (*keypointsIn_pt)
00741 >> x
00742 >> y
00743 >> sigma
00744 >> th ;
00745
00746
00747 (*keypointsIn_pt).ignore(numeric_limits<streamsize>::max(),'\n') ;
00748
00749
00750 if( keypointsIn_pt->eof() ) break ;
00751
00752
00753 if( ! keypointsIn_pt->good() )
00754 VL_THROW("Error reading keypoints file.") ;
00755
00756
00757 VL::Sift::Keypoint key
00758 = sift->getKeypoint(x,y,sigma) ;
00759
00760 Keypoints::value_type entry ;
00761 entry.first = key ;
00762 entry.second = th ;
00763 keypoints.push_back(entry) ;
00764 }
00765
00766
00767 if(! stableorder)
00768 sort(keypoints.begin(), keypoints.end(), cmpKeypoints) ;
00769
00770
00771 for(Keypoints::const_iterator iter = keypoints.begin() ;
00772 iter != keypoints.end() ;
00773 ++iter) {
00774 VL::Sift::Keypoint const& key = iter->first ;
00775 VL::float_t th = iter->second ;
00776
00777
00778 if (outGood)
00779 out << setprecision(2) << key.x << " "
00780 << setprecision(2) << key.y << " "
00781 << setprecision(2) << key.sigma << " "
00782 << setprecision(3) << th ;
00783 keyValues->push_back(key.x);
00784 keyValues->push_back(key.y);
00785 keyValues->push_back(key.sigma);
00786 keyValues->push_back(th);
00787 keyValues->push_back(key.is);
00788 keyValues->push_back(key.o);
00789
00790
00791 VL::float_t descr [128] ;
00792 sift->computeKeypointDescriptor(descr, key, th) ;
00793
00794
00795 if( descriptorsOut_pt.get() ) {
00796 ostream& os = *descriptorsOut_pt.get() ;
00797 insertDescriptor(os, descr, true, fp, numKeypoints, keyValues) ;
00798 } else {
00799 insertDescriptor(out, descr, false, fp, numKeypoints, keyValues, outGood) ;
00800 }
00801
00802
00803 if (outGood) out << endl ;
00804 }
00805
00806 } else {
00807
00808
00809
00810
00811 for( VL::Sift::KeypointsConstIter iter = sift->keypointsBegin() ;
00812 iter != sift->keypointsEnd() ; ++iter ) {
00813
00814
00815 VL::float_t angles [4] ;
00816 int nangles ;
00817 if( ! noorient ) {
00818 nangles = sift->computeKeypointOrientations(angles, *iter) ;
00819 } else {
00820 nangles = 1;
00821 angles[0] = VL::float_t(0) ;
00822 }
00823
00824
00825 for(int a = 0 ; a < nangles ; ++a) {
00826
00827 if (outGood)
00828 out << setprecision(2) << iter->x << ' '
00829 << setprecision(2) << iter->y << ' '
00830 << setprecision(2) << iter->sigma << ' '
00831 << setprecision(3) << angles[a] ;
00832 keyValues->push_back(iter->x);
00833 keyValues->push_back(iter->y);
00834 keyValues->push_back(iter->sigma);
00835 keyValues->push_back(angles[a]);
00836 keyValues->push_back(iter->is);
00837 keyValues->push_back(iter->o);
00838
00839
00840
00841 VL::float_t descr_pt [128] ;
00842 sift->computeKeypointDescriptor(descr_pt, *iter, angles[a]) ;
00843
00844
00845
00846
00847
00848
00849 if( ! nodescr ) {
00850 if( descriptorsOut_pt.get() ) {
00851 ostream& os = *descriptorsOut_pt.get() ;
00852 insertDescriptor(os, descr_pt, true, fp, numKeypoints, keyValues) ;
00853 } else {
00854 insertDescriptor(out, descr_pt, false, fp, numKeypoints, keyValues, outGood) ;
00855 }
00856 }
00857
00858 if (outGood) out << endl ;
00859 }
00860 }
00861 }
00862
00863 if (outGood) out.close() ;
00864 if(descriptorsOut_pt.get()) descriptorsOut_pt->close();
00865 if(keypointsIn_pt.get()) keypointsIn_pt->close();
00866 verbose && cout
00867 << "siftpp: job completed"<<endl ;
00868 }
00869
00870 argc-- ;
00871 argv++ ;
00872 outputFilename = string("") ;
00873
00874 delete [] buffer.data;
00875 }
00876 catch(VL::Exception &e) {
00877 cerr<<endl<<"Error processing '"<<name<<"': "<<e.msg<<endl ;
00878 if (sift) delete sift;
00879 sift = NULL;
00880 return sift ;
00881 }
00882 }
00883
00884 return sift ;
00885 }
00886
00887 VL::Sift*
00888 siftdriver(int argc, char** argv, int* numKeypoints, vector<double>* keyvals)
00889 {
00890 vector< vector< vector<int> > > gaussianSpace;
00891 return siftdriver(argc, argv, numKeypoints, keyvals, gaussianSpace);
00892 }
00893
00894 VL::Sift*
00895 siftdriver(int argc, char** argv, int* numKeypoints)
00896 {
00897 vector<double> temp;
00898 return siftdriver(argc, argv, numKeypoints, &temp);
00899 }
00900