sift.c
Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00015 #define VL_SIFT_DRIVER_VERSION 0.1
00016 
00017 #include "generic-driver.h"
00018 
00019 #include <vl/generic.h>
00020 #include <vl/stringop.h>
00021 #include <vl/pgm.h>
00022 #include <vl/sift.h>
00023 #include <vl/getopt_long.h>
00024 
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <assert.h>
00028 
00029 /* ----------------------------------------------------------------- */
00030 /* help message */
00031 char const help_message [] =
00032   "Usage: %s [options] files ...\n"
00033   "\n"
00034   "Options include:\n"
00035   " --verbose -v    Be verbose\n"
00036   " --help -h       Print this help message\n"
00037   " --output -o     Specify output file\n"
00038   " --frames        Specify frames file\n"
00039   " --descriptors   Specify descriptors file\n"
00040   " --meta          Specify meta file\n"
00041   " --gss           Specify Gaussian scale space files\n"
00042   " --octaves -O    Number of octaves\n"
00043   " --levels -S     Number of levels per octave\n"
00044   " --first-octave  Index of the first octave\n"
00045   " --edge-thresh   Specify the edge threshold\n"
00046   " --peak-thresh   Specift the peak threshold\n"
00047   " --magnif        Specify the magnification factor\n"
00048   " --read-frames   Specify a file from which to read frames\n"
00049   " --orientations  Force the computation of the orientations\n"
00050   "\n" ;
00051 
00052 /* ----------------------------------------------------------------- */
00053 /* long options codes */
00054 enum {
00055   opt_meta = 1000,
00056   opt_frames,
00057   opt_descriptors,
00058   opt_gss,
00059   opt_first_octave,
00060   opt_edge_thresh,
00061   opt_peak_thresh,
00062   opt_magnif,
00063   opt_read_frames,
00064   opt_orientations
00065 } ;
00066 
00067 /* short options */
00068 char const opts [] = "vhO:S:o:" ;
00069 
00070 /* long options */
00071 struct option const longopts [] = {
00072   { "verbose",         no_argument,            0,          'v'              },
00073   { "help",            no_argument,            0,          'h'              },
00074   { "octaves",         required_argument,      0,          'O'              },
00075   { "levels",          required_argument,      0,          'S'              },
00076   { "output",          required_argument,      0,          'o'              },
00077   { "meta",            optional_argument,      0,          opt_meta         },
00078   { "frames",          optional_argument,      0,          opt_frames       },
00079   { "descriptors",     optional_argument,      0,          opt_descriptors  },
00080   { "gss",             optional_argument,      0,          opt_gss          },
00081   { "first-octave",    required_argument,      0,          opt_first_octave },
00082   { "edge-thresh",     required_argument,      0,          opt_edge_thresh  },
00083   { "peak-thresh",     required_argument,      0,          opt_peak_thresh  },
00084   { "magnif",          required_argument,      0,          opt_magnif       },
00085   { "read-frames",     required_argument,      0,          opt_read_frames  },
00086   { "orientations",    no_argument,            0,          opt_orientations },
00087   { 0,                 0,                      0,          0                }
00088 } ;
00089 
00090 /* ----------------------------------------------------------------- */
00094 static int
00095 save_gss (VlSiftFilt * filt, VlFileMeta * fm, const char * basename,
00096           int verbose)
00097 {
00098   char tmp [1024] ;
00099   int S = filt -> S ;
00100   int i ;
00101   int s, err = 0 ;
00102   int w, h ;
00103   int o = filt -> o_cur ;
00104   VlPgmImage pim ;
00105   vl_uint8 *buffer = 0 ;
00106   vl_size q ;
00107 
00108   if (! fm -> active) {
00109     return VL_ERR_OK ;
00110   }
00111 
00112   w = vl_sift_get_octave_width  (filt) ;
00113   h = vl_sift_get_octave_height (filt) ;
00114 
00115   pim.width     = w ;
00116   pim.height    = h ;
00117   pim.max_value = 255 ;
00118   pim.is_raw    = 1 ;
00119 
00120   buffer = malloc (sizeof(vl_uint8) * w * h) ;
00121   if (! buffer) {
00122     err = VL_ERR_ALLOC ;
00123     goto save_gss_quit ;
00124   }
00125 
00126   q = vl_string_copy (tmp, sizeof(tmp), basename) ;
00127   if (q >= sizeof(tmp)) {
00128     err = VL_ERR_OVERFLOW ;
00129     goto save_gss_quit ;
00130   }
00131 
00132   for (s = 0 ; s < S ; ++s) {
00133     vl_sift_pix * pt = vl_sift_get_octave (filt, s) ;
00134 
00135     /* conversion */
00136     for (i = 0 ; i < w * h ; ++i) {
00137       buffer [i] = (vl_uint8) pt [i] ;
00138     }
00139 
00140     /* save */
00141     snprintf(tmp + q, sizeof(tmp) - q, "_%02d_%03d", o, s) ;
00142 
00143     err = vl_file_meta_open (fm, tmp, "wb") ;
00144     if (err) goto save_gss_quit ;
00145 
00146     err = vl_pgm_insert (fm -> file, &pim, buffer) ;
00147     if (err) goto save_gss_quit ;
00148 
00149     if (verbose) {
00150       printf("sift: saved gss level to '%s'\n", fm -> name) ;
00151     }
00152 
00153     vl_file_meta_close (fm) ;
00154   }
00155 
00156  save_gss_quit : ;
00157   if (buffer) free (buffer) ;
00158   vl_file_meta_close (fm) ;
00159   return err ;
00160 }
00161 
00162 /* ----------------------------------------------------------------- */
00166 int
00167 korder (void const* a, void const* b) {
00168   double x = ((double*) a) [2] - ((double*) b) [2] ;
00169   if (x < 0) return -1 ;
00170   if (x > 0) return +1 ;
00171   return 0 ;
00172 }
00173 
00174 /* ---------------------------------------------------------------- */
00177 int
00178 main(int argc, char **argv)
00179 {
00180   /* algorithm parameters */
00181   double   edge_thresh  = -1 ;
00182   double   peak_thresh  = -1 ;
00183   double   magnif       = -1 ;
00184   int      O = -1, S = 3, omin = -1 ;
00185 
00186   vl_bool  err    = VL_ERR_OK ;
00187   char     err_msg [1024] ;
00188   int      n ;
00189   int      exit_code          = 0 ;
00190   int      verbose            = 0 ;
00191   vl_bool  force_output       = 0 ;
00192   vl_bool  force_orientations = 0 ;
00193 
00194   VlFileMeta out  = {1, "%.sift",  VL_PROT_ASCII, "", 0} ;
00195   VlFileMeta frm  = {0, "%.frame", VL_PROT_ASCII, "", 0} ;
00196   VlFileMeta dsc  = {0, "%.descr", VL_PROT_ASCII, "", 0} ;
00197   VlFileMeta met  = {0, "%.meta",  VL_PROT_ASCII, "", 0} ;
00198   VlFileMeta gss  = {0, "%.pgm",   VL_PROT_ASCII, "", 0} ;
00199   VlFileMeta ifr  = {0, "%.frame", VL_PROT_ASCII, "", 0} ;
00200 
00201 #define ERRF(msg, arg) {                                        \
00202     err = VL_ERR_BAD_ARG ;                                      \
00203     snprintf(err_msg, sizeof(err_msg), msg, arg) ;              \
00204     break ;                                                     \
00205   }
00206 
00207 #define ERR(msg) {                                              \
00208     err = VL_ERR_BAD_ARG ;                                      \
00209     snprintf(err_msg, sizeof(err_msg), msg) ;                   \
00210     break ;                                                     \
00211 }
00212 
00213   /* -----------------------------------------------------------------
00214    *                                                     Parse options
00215    * -------------------------------------------------------------- */
00216 
00217   while (!err) {
00218     int ch = getopt_long(argc, argv, opts, longopts, 0) ;
00219 
00220     /* If there are no files passed as input, print the help and settings */
00221     if (ch == -1 && argc - optind == 0)
00222       ch = 'h';
00223 
00224     /* end of option list? */
00225     if (ch == -1) break;
00226 
00227     switch (ch) {
00228 
00229     case '?' :
00230       /* unkown option ............................................ */
00231       ERRF("Invalid option '%s'.", argv [optind - 1]) ;
00232       break ;
00233 
00234     case ':' :
00235       /* missing argument ......................................... */
00236       ERRF("Missing mandatory argument for option '%s'.",
00237           argv [optind - 1]) ;
00238       break ;
00239 
00240     case 'h' :
00241       /* --help ................................................... */
00242       printf (help_message, argv [0]) ;
00243       printf ("SIFT         filespec: `%s'\n", out.pattern) ;
00244       printf ("Frames       filespec: `%s'\n", frm.pattern) ;
00245       printf ("Descriptors  filespec: `%s'\n", dsc.pattern) ;
00246       printf ("Meta         filespec: `%s'\n", met.pattern) ;
00247       printf ("GSS          filespec: '%s'\n", gss.pattern) ;
00248       printf ("Read frames  filespec: '%s'\n", ifr.pattern) ;
00249       printf ("Version: driver %s; libvl %s\n",
00250               VL_XSTRINGIFY(VL_SIFT_DRIVER_VERSION),
00251               vl_get_version_string()) ;
00252       exit (0) ;
00253       break ;
00254 
00255     case 'v' :
00256       /* --verbose ................................................ */
00257       ++ verbose ;
00258       break ;
00259 
00260     case 'o' :
00261       /* --output  ................................................ */
00262       err = vl_file_meta_parse (&out, optarg) ;
00263       if (err)
00264         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00265       force_output = 1 ;
00266       break ;
00267 
00268     case opt_frames :
00269       /* --frames  ................................................ */
00270       err = vl_file_meta_parse (&frm, optarg) ;
00271       if (err)
00272         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00273       break ;
00274 
00275     case opt_descriptors :
00276       /* --descriptor ............................................. */
00277       err = vl_file_meta_parse (&dsc, optarg) ;
00278       if (err)
00279         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00280       break;
00281 
00282     case opt_meta :
00283       /* --meta ................................................... */
00284       err = vl_file_meta_parse (&met, optarg) ;
00285       if (err)
00286         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00287 
00288       if (met.protocol != VL_PROT_ASCII)
00289         ERR("meta file supports only ASCII protocol") ;
00290       break ;
00291 
00292     case opt_read_frames :
00293       /* --read_frames ............................................ */
00294       err = vl_file_meta_parse (&ifr, optarg) ;
00295       if (err)
00296         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00297       break ;
00298 
00299     case opt_gss :
00300       /* --gss .................................................... */
00301       err = vl_file_meta_parse (&gss, optarg) ;
00302       if (err)
00303         ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
00304       break ;
00305 
00306 
00307 
00308     case 'O' :
00309       /* --octaves ............................................... */
00310       n = sscanf (optarg, "%d", &O) ;
00311       if (n == 0 || O < 0)
00312         ERRF("The argument of '%s' must be a non-negative integer.",
00313             argv [optind - 1]) ;
00314       break ;
00315 
00316     case 'S' :
00317       /* --levels ............................................... */
00318       n = sscanf (optarg, "%d", &S) ;
00319       if (n == 0 || S < 0)
00320         ERRF("The argument of '%s' must be a non-negative integer.",
00321             argv [optind - 1]) ;
00322       break ;
00323 
00324     case opt_first_octave :
00325       /* --first-octave ......................................... */
00326       n = sscanf (optarg, "%d", &omin) ;
00327       if (n == 0)
00328         ERRF("The argument of '%s' must be an integer.",
00329             argv [optind - 1]) ;
00330       break ;
00331 
00332 
00333 
00334     case opt_edge_thresh :
00335       /* --edge-thresh ........................................... */
00336       n = sscanf (optarg, "%lf", &edge_thresh) ;
00337       if (n == 0 || edge_thresh < 1)
00338         ERRF("The argument of '%s' must be not smaller than 1.",
00339             argv [optind - 1]) ;
00340       break ;
00341 
00342     case opt_peak_thresh :
00343       /* --edge-thresh ........................................... */
00344       n = sscanf (optarg, "%lf", &peak_thresh) ;
00345       if (n == 0 || peak_thresh < 0)
00346         ERRF("The argument of '%s' must be a non-negative float.",
00347             argv [optind - 1]) ;
00348       break ;
00349 
00350     case opt_magnif :
00351       /* --magnif  .............................................. */
00352       n = sscanf (optarg, "%lf", &magnif) ;
00353       if (n == 0 || magnif < 1)
00354         ERRF("The argument of '%s' must be a non-negative float.",
00355             argv [optind - 1]) ;
00356       break ;
00357 
00358 
00359     case opt_orientations :
00360       /* --orientations ......................................... */
00361       force_orientations = 1 ;
00362       break ;
00363 
00364     case 0 :
00365     default :
00366       /* should not get here ...................................... */
00367       abort() ;
00368     }
00369   }
00370 
00371   /* check for parsing errors */
00372   if (err) {
00373     fprintf(stderr, "%s: error: %s (%d)\n",
00374             argv [0],
00375             err_msg, err) ;
00376     exit (1) ;
00377   }
00378 
00379   /* parse other arguments (filenames) */
00380   argc -= optind ;
00381   argv += optind ;
00382 
00383   /*
00384      if --output is not specified, specifying --frames or --descriptors
00385      prevent the aggregate outout file to be produced.
00386   */
00387   if (! force_output && (frm.active || dsc.active)) {
00388     out.active = 0 ;
00389   }
00390 
00391   if (verbose > 1) {
00392 #define PRNFO(name,fm)                                                  \
00393     printf("sift: " name) ;                                             \
00394     printf("%3s ",  (fm).active ? "yes" : "no") ;                       \
00395     printf("%-6s ", vl_string_protocol_name ((fm).protocol)) ;          \
00396     printf("%-10s\n", (fm).pattern) ;
00397 
00398     PRNFO("write aggregate . ", out) ;
00399     PRNFO("write frames .... ", frm) ;
00400     PRNFO("write descriptors ", dsc) ;
00401     PRNFO("write meta ...... ", met) ;
00402     PRNFO("write GSS ....... ", gss) ;
00403     PRNFO("read  frames .... ", ifr) ;
00404 
00405     if (force_orientations)
00406       printf("sift: will compute orientations\n") ;
00407   }
00408 
00409   /* ------------------------------------------------------------------
00410    *                                         Process one image per time
00411    * --------------------------------------------------------------- */
00412 
00413   while (argc--) {
00414 
00415     char             basename [1024] ;
00416     char const      *name = *argv++ ;
00417 
00418     FILE            *in    = 0 ;
00419     vl_uint8        *data  = 0 ;
00420     vl_sift_pix     *fdata = 0 ;
00421     VlPgmImage       pim ;
00422 
00423     VlSiftFilt      *filt = 0 ;
00424     vl_size          q ;
00425     int              i ;
00426     vl_bool          first ;
00427 
00428     double           *ikeys = 0 ;
00429     int              nikeys = 0, ikeys_size = 0 ;
00430 
00431     /* ...............................................................
00432      *                                                 Determine files
00433      * ............................................................ */
00434 
00435     /* get basenmae from filename */
00436     q = vl_string_basename (basename, sizeof(basename), name, 1) ;
00437 
00438     err = (q >= sizeof(basename)) ;
00439 
00440     if (err) {
00441       snprintf(err_msg, sizeof(err_msg),
00442                "Basename of '%s' is too long", name);
00443       err = VL_ERR_OVERFLOW ;
00444       goto done ;
00445     }
00446 
00447     if (verbose) {
00448       printf ("sift: <== '%s'\n", name) ;
00449     }
00450 
00451     if (verbose > 1) {
00452       printf ("sift: basename is '%s'\n", basename) ;
00453     }
00454 
00455     /* open input file */
00456     in = fopen (name, "rb") ;
00457     if (!in) {
00458       err = VL_ERR_IO ;
00459       snprintf(err_msg, sizeof(err_msg),
00460                "Could not open '%s' for reading.", name) ;
00461       goto done ;
00462     }
00463 
00464     /* ...............................................................
00465      *                                                       Read data
00466      * ............................................................ */
00467 
00468     /* read PGM header */
00469     err = vl_pgm_extract_head (in, &pim) ;
00470 
00471     if (err) {
00472       switch (vl_get_last_error()) {
00473       case  VL_ERR_PGM_IO :
00474         snprintf(err_msg, sizeof(err_msg),
00475                  "Cannot read from '%s'.", name) ;
00476         err = VL_ERR_IO ;
00477         break ;
00478 
00479       case VL_ERR_PGM_INV_HEAD :
00480         snprintf(err_msg, sizeof(err_msg),
00481                  "'%s' contains a malformed PGM header.", name) ;
00482         err = VL_ERR_IO ;
00483         goto done ;
00484       }
00485     }
00486 
00487     if (verbose)
00488       printf ("sift: image is %" VL_FMT_SIZE " by %" VL_FMT_SIZE " pixels\n",
00489               pim. width,
00490               pim. height) ;
00491 
00492     /* allocate buffer */
00493     data  = malloc(vl_pgm_get_npixels (&pim) *
00494                    vl_pgm_get_bpp       (&pim) * sizeof (vl_uint8)   ) ;
00495     fdata = malloc(vl_pgm_get_npixels (&pim) *
00496                    vl_pgm_get_bpp       (&pim) * sizeof (vl_sift_pix)) ;
00497 
00498     if (!data || !fdata) {
00499       err = VL_ERR_ALLOC ;
00500       snprintf(err_msg, sizeof(err_msg),
00501                "Could not allocate enough memory.") ;
00502       goto done ;
00503     }
00504 
00505     /* read PGM body */
00506     err  = vl_pgm_extract_data (in, &pim, data) ;
00507 
00508     if (err) {
00509       snprintf(err_msg, sizeof(err_msg), "PGM body malformed.") ;
00510       err = VL_ERR_IO ;
00511       goto done ;
00512     }
00513 
00514     /* convert data type */
00515     for (q = 0 ; q < (unsigned) (pim.width * pim.height) ; ++q) {
00516       fdata [q] = data [q] ;
00517     }
00518 
00519     /* ...............................................................
00520      *                                     Optionally source keypoints
00521      * ............................................................ */
00522 
00523 #define WERR(name,op)                                           \
00524     if (err == VL_ERR_OVERFLOW) {                               \
00525       snprintf(err_msg, sizeof(err_msg),                        \
00526                "Output file name too long.") ;                  \
00527       goto done ;                                               \
00528     } else if (err) {                                           \
00529       snprintf(err_msg, sizeof(err_msg),                        \
00530                "Could not open '%s' for " #op, name) ;          \
00531       goto done ;                                               \
00532     }
00533 
00534     if (ifr.active) {
00535 
00536       /* open file */
00537       err = vl_file_meta_open (&ifr, basename, "rb") ;
00538       WERR(ifr.name, reading) ;
00539 
00540 #define QERR                                                            \
00541       if (err ) {                                                       \
00542         snprintf (err_msg, sizeof(err_msg),                             \
00543                   "'%s' malformed", ifr.name) ;                         \
00544         err = VL_ERR_IO ;                                               \
00545         goto done ;                                                     \
00546       }
00547 
00548       while (1) {
00549         double x, y, s, th ;
00550 
00551         /* read next guy */
00552         err = vl_file_meta_get_double (&ifr, &x) ;
00553         if   (err == VL_ERR_EOF) break;
00554         else QERR ;
00555         err = vl_file_meta_get_double (&ifr, &y ) ; QERR ;
00556         err = vl_file_meta_get_double (&ifr, &s ) ; QERR ;
00557         err = vl_file_meta_get_double (&ifr, &th) ;
00558         if   (err == VL_ERR_EOF) break;
00559         else QERR ;
00560 
00561         /* make enough space */
00562         if (ikeys_size < nikeys + 1) {
00563           ikeys_size += 10000 ;
00564           ikeys       = realloc (ikeys, 4 * sizeof(double) * ikeys_size) ;
00565         }
00566 
00567         /* add the guy to the buffer */
00568         ikeys [4 * nikeys + 0]  = x ;
00569         ikeys [4 * nikeys + 1]  = y ;
00570         ikeys [4 * nikeys + 2]  = s ;
00571         ikeys [4 * nikeys + 3]  = th ;
00572 
00573         ++ nikeys ;
00574       }
00575 
00576       /* now order by scale */
00577       qsort (ikeys, nikeys, 4 * sizeof(double), korder) ;
00578 
00579       if (verbose) {
00580         printf ("sift: read %d keypoints from '%s'\n", nikeys, ifr.name) ;
00581       }
00582 
00583       /* close file */
00584       vl_file_meta_close (&ifr) ;
00585     }
00586 
00587     /* ...............................................................
00588      *                                               Open output files
00589      * ............................................................ */
00590 
00591     err = vl_file_meta_open (&out, basename, "wb") ; WERR(out.name, writing) ;
00592     err = vl_file_meta_open (&dsc, basename, "wb") ; WERR(dsc.name, writing) ;
00593     err = vl_file_meta_open (&frm, basename, "wb") ; WERR(frm.name, writing) ;
00594     err = vl_file_meta_open (&met, basename, "wb") ; WERR(met.name, writing) ;
00595 
00596     if (verbose > 1) {
00597       if (out.active) printf("sift: writing all ....... to . '%s'\n", out.name);
00598       if (frm.active) printf("sift: writing frames .... to . '%s'\n", frm.name);
00599       if (dsc.active) printf("sift: writing descriptors to . '%s'\n", dsc.name);
00600       if (met.active) printf("sift: writign meta ...... to . '%s'\n", met.name);
00601     }
00602 
00603     /* ...............................................................
00604      *                                                     Make filter
00605      * ............................................................ */
00606 
00607     filt = vl_sift_new (pim.width, pim.height, O, S, omin) ;
00608 
00609     if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ;
00610     if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ;
00611     if (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;
00612 
00613     if (!filt) {
00614       snprintf (err_msg, sizeof(err_msg),
00615                 "Could not create SIFT filter.") ;
00616       err = VL_ERR_ALLOC ;
00617       goto done ;
00618     }
00619 
00620     if (verbose > 1) {
00621       printf ("sift: filter settings:\n") ;
00622       printf ("sift:   octaves      (O)     = %d\n",
00623               vl_sift_get_noctaves     (filt)) ;
00624       printf ("sift:   levels       (S)     = %d\n",
00625               vl_sift_get_nlevels      (filt)) ;
00626       printf ("sift:   first octave (o_min) = %d\n",
00627               vl_sift_get_octave_first (filt)) ;
00628       printf ("sift:   edge thresh           = %g\n",
00629               vl_sift_get_edge_thresh  (filt)) ;
00630       printf ("sift:   peak thresh           = %g\n",
00631               vl_sift_get_peak_thresh  (filt)) ;
00632       printf ("sift:   magnif                = %g\n",
00633               vl_sift_get_magnif       (filt)) ;
00634       printf ("sift: will source frames? %s\n",
00635               ikeys ? "yes" : "no") ;
00636       printf ("sift: will force orientations? %s\n",
00637               force_orientations ? "yes" : "no") ;
00638     }
00639 
00640     /* ...............................................................
00641      *                                             Process each octave
00642      * ............................................................ */
00643     i     = 0 ;
00644     first = 1 ;
00645     while (1) {
00646       VlSiftKeypoint const *keys = 0 ;
00647       int                   nkeys ;
00648 
00649       /* calculate the GSS for the next octave .................... */
00650       if (first) {
00651         first = 0 ;
00652         err = vl_sift_process_first_octave (filt, fdata) ;
00653       } else {
00654         err = vl_sift_process_next_octave  (filt) ;
00655       }
00656 
00657       if (err) {
00658         err = VL_ERR_OK ;
00659         break ;
00660       }
00661 
00662       if (verbose > 1) {
00663         printf("sift: GSS octave %d computed\n",
00664                vl_sift_get_octave_index (filt));
00665       }
00666 
00667       /* optionally save GSS */
00668       if (gss.active) {
00669         err = save_gss (filt, &gss, basename, verbose) ;
00670         if (err) {
00671           snprintf (err_msg, sizeof(err_msg),
00672                     "Could not write GSS to PGM file.") ;
00673           goto done ;
00674         }
00675       }
00676 
00677       /* run detector ............................................. */
00678       if (ikeys == 0) {
00679         vl_sift_detect (filt) ;
00680 
00681         keys  = vl_sift_get_keypoints     (filt) ;
00682         nkeys = vl_sift_get_nkeypoints (filt) ;
00683         i     = 0 ;
00684 
00685         if (verbose > 1) {
00686           printf ("sift: detected %d (unoriented) keypoints\n", nkeys) ;
00687         }
00688       } else {
00689         nkeys = nikeys ;
00690       }
00691 
00692       /* for each keypoint ........................................ */
00693       for (; i < nkeys ; ++i) {
00694         double                angles [4] ;
00695         int                   nangles ;
00696         VlSiftKeypoint        ik ;
00697         VlSiftKeypoint const *k ;
00698 
00699         /* obtain keypoint orientations ........................... */
00700         if (ikeys) {
00701           vl_sift_keypoint_init (filt, &ik,
00702                                  ikeys [4 * i + 0],
00703                                  ikeys [4 * i + 1],
00704                                  ikeys [4 * i + 2]) ;
00705 
00706           if (ik.o != vl_sift_get_octave_index (filt)) {
00707             break ;
00708           }
00709 
00710           k          = &ik ;
00711 
00712           /* optionally compute orientations too */
00713           if (force_orientations) {
00714             nangles = vl_sift_calc_keypoint_orientations
00715               (filt, angles, k) ;
00716           } else {
00717             angles [0] = ikeys [4 * i + 3] ;
00718             nangles    = 1 ;
00719           }
00720         } else {
00721           k = keys + i ;
00722           nangles = vl_sift_calc_keypoint_orientations
00723             (filt, angles, k) ;
00724         }
00725 
00726         /* for each orientation ................................... */
00727         for (q = 0 ; q < (unsigned) nangles ; ++q) {
00728           vl_sift_pix descr [128] ;
00729 
00730           /* compute descriptor (if necessary) */
00731           if (out.active || dsc.active) {
00732             vl_sift_calc_keypoint_descriptor
00733               (filt, descr, k, angles [q]) ;
00734           }
00735 
00736           if (out.active) {
00737             int l ;
00738             vl_file_meta_put_double (&out, k -> x     ) ;
00739             vl_file_meta_put_double (&out, k -> y     ) ;
00740             vl_file_meta_put_double (&out, k -> sigma ) ;
00741             vl_file_meta_put_double (&out, angles [q] ) ;
00742             for (l = 0 ; l < 128 ; ++l) {
00743               vl_file_meta_put_uint8 (&out, (vl_uint8) (512.0 * descr [l])) ;
00744             }
00745             if (out.protocol == VL_PROT_ASCII) fprintf(out.file, "\n") ;
00746           }
00747 
00748           if (frm.active) {
00749             vl_file_meta_put_double (&frm, k -> x     ) ;
00750             vl_file_meta_put_double (&frm, k -> y     ) ;
00751             vl_file_meta_put_double (&frm, k -> sigma ) ;
00752             vl_file_meta_put_double (&frm, angles [q] ) ;
00753             if (frm.protocol == VL_PROT_ASCII) fprintf(frm.file, "\n") ;
00754           }
00755 
00756           if (dsc.active) {
00757             int l ;
00758             for (l = 0 ; l < 128 ; ++l) {
00759               double x = 512.0 * descr[l] ;
00760               x = (x < 255.0) ? x : 255.0 ;
00761               vl_file_meta_put_uint8 (&dsc, (vl_uint8) (x)) ;
00762             }
00763             if (dsc.protocol == VL_PROT_ASCII) fprintf(dsc.file, "\n") ;
00764           }
00765         }
00766       }
00767     }
00768 
00769     /* ...............................................................
00770      *                                                       Finish up
00771      * ............................................................ */
00772 
00773     if (met.active) {
00774       fprintf(met.file, "<sift\n") ;
00775       fprintf(met.file, "  input       = '%s'\n", name) ;
00776       if (dsc.active) {
00777         fprintf(met.file, "  descriptors = '%s'\n", dsc.name) ;
00778       }
00779       if (frm.active) {
00780         fprintf(met.file,"  frames      = '%s'\n", frm.name) ;
00781       }
00782       fprintf(met.file, ">\n") ;
00783     }
00784 
00785   done :
00786     /* release input keys buffer */
00787     if (ikeys) {
00788       free (ikeys) ;
00789       ikeys_size = nikeys = 0 ;
00790       ikeys = 0 ;
00791     }
00792 
00793     /* release filter */
00794     if (filt) {
00795       vl_sift_delete (filt) ;
00796       filt = 0 ;
00797     }
00798 
00799     /* release image data */
00800     if (fdata) {
00801       free (fdata) ;
00802       fdata = 0 ;
00803     }
00804 
00805     /* release image data */
00806     if (data) {
00807       free (data) ;
00808       data = 0 ;
00809     }
00810 
00811     /* close files */
00812     if (in) {
00813       fclose (in) ;
00814       in = 0 ;
00815     }
00816 
00817     vl_file_meta_close (&out) ;
00818     vl_file_meta_close (&frm) ;
00819     vl_file_meta_close (&dsc) ;
00820     vl_file_meta_close (&met) ;
00821     vl_file_meta_close (&gss) ;
00822     vl_file_meta_close (&ifr) ;
00823 
00824     /* if bad print error message */
00825     if (err) {
00826       fprintf
00827         (stderr,
00828          "sift: err: %s (%d)\n",
00829          err_msg,
00830          err) ;
00831       exit_code = 1 ;
00832     }
00833   }
00834 
00835   /* quit */
00836   return exit_code ;
00837 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51