void SIFT_ADAPTER::set_sift_model() { clear_model_related_data(); m_sift_model = vl_sift_new(m_org_img.cols, m_org_img.rows, getNOctaves(), getNLevels(), getOctFirst()); vl_sift_set_edge_thresh(m_sift_model, getEdgeThrd()); vl_sift_set_peak_thresh(m_sift_model, getPeakThrd()); vl_sift_set_norm_thresh(m_sift_model, getNormThrd()); vl_sift_set_magnif(m_sift_model, getMagnif()); vl_sift_set_window_size(m_sift_model, getWindowSize()); }
/** * Creates a new SIFT filter. Must be called before calling other MAR SIFT functions. * * @param width The width of the camera frame * @param height The height of the camera frame * @param number_of_octaves The number of octaves used by the SIFT filter. * Increasing the scale by an octave means doubling the size of the smoothing kernel, * whose effect is roughly equivalent to halving the image resolution. * @param number_of_levels The number of levels used by the SIFT filter. * Each octave is sampled at this given number of intermediate scales * Increasing this number might in principle return more refined keypoints, but in practice can make their selection unstable due to noise. * @param first_octave The SIFT filter will iterate from first_octave to number_of_octaves * * @return MAR_ERROR_NONE on success, an error code on failure. */ MAR_PUBLIC mar_error_code mar_sift_new(int width, int height, int number_of_octaves, int number_of_levels, int first_octave) { // Create the image buffer sift_image_width = width; sift_image_height = height; sift_image_buffer = malloc(width * height * sizeof(float)); if (sift_image_buffer == NULL) { return MAR_ERROR_MALLOC; } // Create SIFT filter sift_filter = vl_sift_new(width, height, number_of_octaves, number_of_levels, first_octave); // Create the SIFT keypoint buffer sift_keypoints = malloc(sizeof(mar_sift_keypoint) * MAR_SIFT_DEFAULT_NUMBER_OF_KEYPOINTS); if (sift_keypoints == NULL) { return MAR_ERROR_MALLOC; } return MAR_ERROR_NONE; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_GRAD=0,IN_FRAMES,IN_END} ; enum {OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; mxArray *grad_array ; vl_sift_pix *grad ; int M, N ; vl_bool floatDescriptors = 0 ; double magnif = -1 ; double *ikeys = 0 ; int nikeys = 0 ; int i,j ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 2) { mexErrMsgTxt("Two arguments required.") ; } else if (nout > 1) { mexErrMsgTxt("Too many output arguments."); } if (mxGetNumberOfDimensions (in[IN_GRAD]) != 3 || mxGetClassID (in[IN_GRAD]) != mxSINGLE_CLASS || mxGetDimensions (in[IN_GRAD])[0] != 2 ) { mexErrMsgTxt("GRAD must be a 2xMxN matrix of class SINGLE.") ; } if (!vlmxIsMatrix(in[IN_FRAMES], 4, -1)) { mexErrMsgTxt("FRAMES must be a 4xN matrix.") ; } nikeys = mxGetN (in[IN_FRAMES]) ; ikeys = mxGetPr(in[IN_FRAMES]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_magnif : if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("MAGNIF must be a non-negative scalar.") ; } break ; case opt_float_descriptors : floatDescriptors = 1 ; break ; default : abort() ; } } grad_array = mxDuplicateArray(in[IN_GRAD]) ; grad = (vl_sift_pix*) mxGetData (grad_array) ; M = mxGetDimensions(in[IN_GRAD])[1] ; N = mxGetDimensions(in[IN_GRAD])[2] ; /* transpose angles */ for (i = 1 ; i < 2*M*N ; i+=2) { grad [i] = VL_PI/2 - grad [i] ; } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt * filt = 0 ; void * descr = 0 ; /* create a filter to process the image */ filt = vl_sift_new (M, N, -1, -1, 0) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (verbose) { mexPrintf("vl_siftdescriptor: filter settings:\n") ; mexPrintf("vl_siftdescriptor: magnif = %g\n", vl_sift_get_magnif (filt)) ; mexPrintf("vl_siftdescriptor: num of frames = %d\n", nikeys) ; mexPrintf("vl_siftdescriptor: float descriptor = %d\n", floatDescriptors) ; } { mwSize dims [2] ; dims [0] = 128 ; dims [1] = nikeys ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS, mxREAL) ; descr = mxGetData(out[OUT_DESCRIPTORS]) ; } /* ............................................................... * Process each octave * ............................................................ */ for (i = 0 ; i < nikeys ; ++i) { vl_sift_pix buf [128], rbuf [128] ; double y = *ikeys++ - 1 ; double x = *ikeys++ - 1 ; double s = *ikeys++ ; double th = VL_PI / 2 - *ikeys++ ; vl_sift_calc_raw_descriptor (filt, grad, buf, M, N, x, y, s, th) ; transpose_descriptor (rbuf, buf) ; if (! floatDescriptors) { vl_uint8 * descr_ = descr ; for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; x = (x < 255.0F) ? x : 255.0F ; *descr_++ = (vl_uint8) (x) ; } descr = descr_ ; } else { float * descr_ = descr ; for (j = 0 ; j < 128 ; ++j) { *descr_++ = 512.0F * rbuf [j] ; } descr = descr_ ; } } /* cleanup */ mxDestroyArray (grad_array) ; vl_sift_delete (filt) ; } /* job done */ }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0,IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; vl_sift_pix const *data ; int M, N ; int O = - 1 ; int S = 3 ; int o_min = 0 ; double edge_thresh = -1 ; double peak_thresh = -1 ; double norm_thresh = -1 ; double magnif = -1 ; double window_size = -1 ; mxArray *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 0 ; vl_bool floatDescriptors = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { mexErrMsgTxt("One argument required.") ; } else if (nout > 2) { mexErrMsgTxt("Too many output arguments."); } if (mxGetNumberOfDimensions (in[IN_I]) != 2 || mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) { mexErrMsgTxt("I must be a matrix of class SINGLE") ; } data = (vl_sift_pix*) mxGetData (in[IN_I]) ; M = mxGetM (in[IN_I]) ; N = mxGetN (in[IN_I]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_octaves : if (!vlmxIsPlainScalar(optarg) || (O = (int) *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'Octaves' must be a positive integer.") ; } break ; case opt_levels : if (! vlmxIsPlainScalar(optarg) || (S = (int) *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'Levels' must be a positive integer.") ; } break ; case opt_first_octave : if (!vlmxIsPlainScalar(optarg)) { mexErrMsgTxt("'FirstOctave' must be an integer") ; } o_min = (int) *mxGetPr(optarg) ; break ; case opt_edge_thresh : if (!vlmxIsPlainScalar(optarg) || (edge_thresh = *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'EdgeThresh' must be not smaller than 1.") ; } break ; case opt_peak_thresh : if (!vlmxIsPlainScalar(optarg) || (peak_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'PeakThresh' must be a non-negative real.") ; } break ; case opt_norm_thresh : if (!vlmxIsPlainScalar(optarg) || (norm_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'NormThresh' must be a non-negative real.") ; } break ; case opt_magnif : if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'Magnif' must be a non-negative real.") ; } break ; case opt_window_size : if (!vlmxIsPlainScalar(optarg) || (window_size = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'WindowSize' must be a non-negative real.") ; } break ; case opt_frames : if (!vlmxIsMatrix(optarg, 4, -1)) { mexErrMsgTxt("'Frames' must be a 4 x N matrix.x") ; } ikeys_array = mxDuplicateArray (optarg) ; nikeys = mxGetN (optarg) ; ikeys = mxGetPr (ikeys_array) ; if (! check_sorted (ikeys, nikeys)) { qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; } break ; case opt_orientations : force_orientations = 1 ; break ; case opt_float_descriptors : floatDescriptors = 1 ; break ; default : abort() ; } } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt *filt ; vl_bool first ; double *frames = 0 ; void *descr = 0 ; int nframes = 0, reserved = 0, i,j,q ; /* create a filter to process the image */ filt = vl_sift_new (M, N, O, S, o_min) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (window_size >= 0) vl_sift_set_window_size (filt, window_size) ; if (verbose) { mexPrintf("vl_sift: filter settings:\n") ; mexPrintf("vl_sift: octaves (O) = %d\n", vl_sift_get_noctaves (filt)) ; mexPrintf("vl_sift: levels (S) = %d\n", vl_sift_get_nlevels (filt)) ; mexPrintf("vl_sift: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; mexPrintf("vl_sift: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; mexPrintf("vl_sift: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; mexPrintf("vl_sift: norm thresh = %g\n", vl_sift_get_norm_thresh (filt)) ; mexPrintf("vl_sift: window size = %g\n", vl_sift_get_window_size (filt)) ; mexPrintf("vl_sift: float descriptor = %d\n", floatDescriptors) ; mexPrintf((nikeys >= 0) ? "vl_sift: will source frames? yes (%d read)\n" : "vl_sift: will source frames? no\n", nikeys) ; mexPrintf("vl_sift: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { int err ; VlSiftKeypoint const* keys = 0 ; int nkeys = 0 ; if (verbose) { mexPrintf ("vl_sift: processing octave %d\n", vl_sift_get_octave_index (filt)) ; } /* Calculate the GSS for the next octave .................... */ if (first) { err = vl_sift_process_first_octave (filt, data) ; first = 0 ; } else { err = vl_sift_process_next_octave (filt) ; } if (err) break ; if (verbose > 1) { mexPrintf("vl_sift: GSS octave %d computed\n", vl_sift_get_octave_index (filt)); } /* Run detector ............................................. */ if (nikeys < 0) { vl_sift_detect (filt) ; keys = vl_sift_get_keypoints (filt) ; nkeys = vl_sift_get_nkeypoints (filt) ; i = 0 ; if (verbose > 1) { printf ("vl_sift: detected %d (unoriented) keypoints\n", nkeys) ; } } else { nkeys = nikeys ; } /* For each keypoint ........................................ */ for (; i < nkeys ; ++i) { double angles [4] ; int nangles ; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* Obtain keypoint orientations ........................... */ if (nikeys >= 0) { vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 1] - 1, ikeys [4 * i + 0] - 1, ikeys [4 * i + 2]) ; if (ik.o != vl_sift_get_octave_index (filt)) { break ; } k = &ik ; /* optionally compute orientations too */ if (force_orientations) { nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } else { angles [0] = VL_PI / 2 - ikeys [4 * i + 3] ; nangles = 1 ; } } else { k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } /* For each orientation ................................... */ for (q = 0 ; q < nangles ; ++q) { vl_sift_pix buf [128] ; vl_sift_pix rbuf [128] ; /* compute descriptor (if necessary) */ if (nout > 1) { vl_sift_calc_keypoint_descriptor (filt, buf, k, angles [q]) ; transpose_descriptor (rbuf, buf) ; } /* make enough room for all these keypoints and more */ if (reserved < nframes + 1) { reserved += 2 * nkeys ; frames = mxRealloc (frames, 4 * sizeof(double) * reserved) ; if (nout > 1) { if (! floatDescriptors) { descr = mxRealloc (descr, 128 * sizeof(vl_uint8) * reserved) ; } else { descr = mxRealloc (descr, 128 * sizeof(float) * reserved) ; } } } /* Save back with MATLAB conventions. Notice tha the input * image was the transpose of the actual image. */ frames [4 * nframes + 0] = k -> y + 1 ; frames [4 * nframes + 1] = k -> x + 1 ; frames [4 * nframes + 2] = k -> sigma ; frames [4 * nframes + 3] = VL_PI / 2 - angles [q] ; if (nout > 1) { if (! floatDescriptors) { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; x = (x < 255.0F) ? x : 255.0F ; ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ; } } else { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; ((float*)descr) [128 * nframes + j] = x ; } } } ++ nframes ; } /* next orientation */ } /* next keypoint */ } /* next octave */ if (verbose) { mexPrintf ("vl_sift: found %d keypoints\n", nframes) ; } /* ............................................................... * Save back * ............................................................ */ { mwSize dims [2] ; /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_FRAMES] = mxCreateNumericArray (2, dims, mxDOUBLE_CLASS, mxREAL) ; /* set array content to be the frames buffer */ dims [0] = 4 ; dims [1] = nframes ; mxSetPr (out[OUT_FRAMES], frames) ; mxSetDimensions (out[OUT_FRAMES], dims, 2) ; if (nout > 1) { /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS, mxREAL) ; /* set array content to be the descriptors buffer */ dims [0] = 128 ; dims [1] = nframes ; mxSetData (out[OUT_DESCRIPTORS], descr) ; mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ; } } /* cleanup */ vl_sift_delete (filt) ; if (ikeys_array) mxDestroyArray(ikeys_array) ; } /* end: do job */ }
static bool SIFTDetector(const Image<unsigned char>& I, std::vector<SIOPointFeature>& feats, std::vector<Descriptor<type,128> >& descs, bool bDezoom = false, bool bRootSift = false, float dPeakThreshold = 0.04f) { // First Octave Index. int firstOctave = (bDezoom == true) ? -1 : 0; // Number of octaves. int numOctaves = 6; // Number of scales per octave. int numScales = 3; // Max ratio of Hessian eigenvalues. float edgeThresh = 10.0f; // Min contrast. float peakThresh = dPeakThreshold; int w=I.Width(), h=I.Height(); //Convert to float Image<float> If( I.GetMat().cast<float>() ); vl_constructor(); VlSiftFilt *filt = vl_sift_new(w,h,numOctaves,numScales,firstOctave); if (edgeThresh >= 0) vl_sift_set_edge_thresh(filt, edgeThresh); if (peakThresh >= 0) vl_sift_set_peak_thresh(filt, 255*peakThresh/numScales); vl_sift_process_first_octave(filt, If.data()); vl_sift_pix descr[128]; Descriptor<type, 128> descriptor; while (true) { vl_sift_detect(filt); VlSiftKeypoint const *keys = vl_sift_get_keypoints(filt); int nkeys = vl_sift_get_nkeypoints(filt); for (int i=0;i<nkeys;++i) { double angles [4]; int nangles=vl_sift_calc_keypoint_orientations(filt,angles,keys+i); for (int q=0 ; q < nangles ; ++q) { vl_sift_calc_keypoint_descriptor(filt,descr, keys+i, angles [q]); SIOPointFeature fp; fp.x() = keys[i].x; fp.y() = keys[i].y; fp.scale() = keys[i].sigma; fp.orientation() = static_cast<float>(angles[q]); siftDescToFloat(descr, descriptor, bRootSift); descs.push_back(descriptor); feats.push_back(fp); } } if (vl_sift_process_next_octave(filt)) break; // Last octave } vl_sift_delete(filt); vl_destructor(); return true; }
/** @brief SIFT driver entry point **/ int Sift::Detect() { /* algorithm parameters */ double edge_thresh = -1 ; double peak_thresh = -1 ; double magnif = -1 ; int O = -1, S = 3, omin = -1 ; vl_bool err = VL_ERR_OK ; vl_bool force_orientations = 0 ; VlSiftFilt *filt = 0 ; vl_size q ; int i ; vl_bool first ; TimeMeasureBase& measure = *TimeMeasureBase::getInstance(); measure.startTimer("Sift::Detect()"); #define WERR(name,op) \ if (err == VL_ERR_OVERFLOW) { \ snprintf(err_msg, sizeof(err_msg), \ "Output file name too long.") ; \ goto done ; \ } else if (err) { \ snprintf(err_msg, sizeof(err_msg), \ "Could not open '%s' for " #op, name) ; \ goto done ; \ } /* ............................................................... * Make filter * ............................................................ */ filt = vl_sift_new (pim.width, pim.height, O, S, omin) ; Logger::debug(Logger::SIFT, "new filter(vl_sift_new) created:%x", filt) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (!filt) { Logger::error(Logger::SIFT, "Detect: could not create SIFT-fiter."); throw SiftException("could not create SIFT-fiter."); } Logger::debug(Logger::SIFT, "sift: filter settings:") ; Logger::debug(Logger::SIFT, "sift: octaves (O) = %d", vl_sift_get_noctaves (filt)) ; Logger::debug(Logger::SIFT, "sift: levels (S) = %d", vl_sift_get_nlevels (filt)) ; Logger::debug(Logger::SIFT, "sift: first octave (o_min) = %d", vl_sift_get_octave_first (filt)) ; Logger::debug(Logger::SIFT, "sift: edge thresh = %g", vl_sift_get_edge_thresh (filt)) ; Logger::debug(Logger::SIFT, "sift: peak thresh = %g", vl_sift_get_peak_thresh (filt)) ; Logger::debug(Logger::SIFT, "sift: magnif = %g", vl_sift_get_magnif (filt)) ; Logger::debug(Logger::SIFT, "sift: will force orientations? %s", force_orientations ? "yes" : "no") ; /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { VlSiftKeypoint const *keys = 0 ; int nkeys ; Logger::debug(Logger::SIFT, "sift: computing octave"); /* calculate the GSS for the next octave .................... */ measure.startTimer("process_octave"); if (first) { measure.startTimer("process_f_octave"); first = 0 ; err = vl_sift_process_first_octave(filt, fdata) ; measure.stopTimer("process_f_octave"); } else { measure.startTimer("process_n_octave"); err = vl_sift_process_next_octave(filt); measure.stopTimer("process_n_octave"); } measure.stopTimer("process_octave"); if (err) { err = VL_ERR_OK ; break ; } Logger::debug(Logger::SIFT, "sift: GSS octave %d computed", vl_sift_get_octave_index (filt)); /* run detector ............................................. */ measure.startTimer("sift_detect"); vl_sift_detect (filt) ; measure.stopTimer("sift_detect"); keys = vl_sift_get_keypoints(filt) ; nkeys = vl_sift_get_nkeypoints(filt) ; i = 0 ; Logger::debug(Logger::SIFT, "sift: detected %d (unoriented) keypoints", nkeys) ; /* for each keypoint ........................................ */ for (; i < nkeys ; ++i) { measure.startTimer("per_kpoint"); double angles [4] ; int nangles ; //VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* obtain keypoint orientations ........................... */ k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; /* for each orientation ................................... */ for (q = 0 ; q < (unsigned) nangles ; ++q) { KeyPointDescriptor newKeyPoint; /* compute descriptor (if necessary) */ //if (out.active || dsc.active) { vl_sift_calc_keypoint_descriptor(filt, newKeyPoint.descr, k, angles [q]) ; //} newKeyPoint.keypoint = *k; newKeyPoint.angle = angles[q]; detected_keypoints.push_back(newKeyPoint); } measure.stopTimer("per_kpoint"); } } /* ............................................................... * Finish up * ............................................................ */ /* release filter */ if (filt) { Logger::debug(Logger::SIFT, "freeing filt: %x", filt); vl_sift_delete (filt) ; filt = 0 ; } measure.stopTimer("Sift::Detect()"); measure.printStatistic(); /* quit */ return 0; }
bool VlSIFTFeature::vl_keypoint_extractor(const vil_image_view<vxl_byte> & image, const vl_feat_sift_parameter ¶m, vcl_vector<bapl_keypoint_sptr> & keypoints, bool verbose) { vil_image_view<vxl_byte> grey; if (image.nplanes() == 1) { grey.deep_copy(image); } else { vil_convert_planes_to_grey(image, grey); } int width = grey.ni(); int height = grey.nj(); int noctaves = param.noctaves; // maximum octatve possible int nlevels = 3; int o_min = 0; //first octave index // create a filter to process the image VlSiftFilt *filt = vl_sift_new (width, height, noctaves, nlevels, o_min) ; double edge_thresh = param.edge_thresh; double peak_thresh = param.peak_thresh; double magnif = param.magnif ; double norm_thresh = param.norm_thresh; double window_size = param.window_size; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (window_size >= 0) vl_sift_set_window_size (filt, window_size) ; // data from image vl_sift_pix *fdata = (vl_sift_pix *)malloc(width * height * sizeof (vl_sift_pix)); for (int y = 0; y<grey.nj(); y++) { for (int x = 0; x<grey.ni(); x++) { int idx = y * width + x; fdata[idx] = grey(x, y, 0); } } // Process each octave bool isFirst = true ; vl_bool err = VL_ERR_OK; int nangles = 0; double angles[4]; vnl_vector_fixed<float, 128> descriptor; while (1) { if (isFirst) { isFirst = false; err = vl_sift_process_first_octave (filt, fdata) ; } else { err = vl_sift_process_next_octave (filt) ; } if(err == VL_ERR_EOF) { break; } vl_sift_detect (filt); VlSiftKeypoint const * keys = vl_sift_get_keypoints(filt) ; int nkeys = vl_sift_get_nkeypoints (filt) ; for (int i = 0; i<nkeys; i++) { VlSiftKeypoint const * curKey = keys + i; // Depending on the symmetry of the keypoint appearance, determining the orientation can be ambiguous. SIFT detectors have up to four possible orientations nangles = vl_sift_calc_keypoint_orientations(filt, angles, curKey) ; for (int q = 0 ; q < nangles ; q++) { vl_sift_calc_keypoint_descriptor(filt, &descriptor[0], curKey, angles[q]); bapl_lowe_keypoint *pKeypoint = new bapl_lowe_keypoint(); double x = curKey->x; double y = curKey->y; double s = curKey->sigma; double o = angles[q]; vnl_vector_fixed<double, 128> des; for (int j = 0; j<128; j++) { des[j] = descriptor[j]; } pKeypoint->set_location_i(x); pKeypoint->set_location_j(y); pKeypoint->set_scale(s); pKeypoint->set_orientation(o); pKeypoint->set_descriptor(des); keypoints.push_back(bapl_keypoint_sptr(pKeypoint)); } } } vl_sift_delete(filt); delete fdata; if(verbose){ vcl_cout<<"Found "<<keypoints.size()<<" keypoints."<<vcl_endl; } return true; }
void Sift::extract(Image &image, std::vector<Feature> *list) { float *fdata = new float[image.cv->width * image.cv->height]; BOOST_VERIFY(fdata); { float *d = fdata; unsigned char *l = (unsigned char *)image.cv->imageData; for (int h = 0; h < image.cv->height; ++h) { for (int w = 0; w < image.cv->width; ++w) { *d = float(l[w]); d++; } l += image.cv->widthStep; } } VlSiftFilt *filt = vl_sift_new (image.cv->width, image.cv->height, O, S, omin) ; BOOST_VERIFY(filt); if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; magnif = vl_sift_get_magnif(filt); list->clear(); int err = vl_sift_process_first_octave (filt, fdata); while (err == 0) { vl_sift_detect (filt) ; VlSiftKeypoint const *keys = vl_sift_get_keypoints(filt) ; int nkeys = vl_sift_get_nkeypoints(filt) ; for (int i = 0; i < nkeys ; ++i) { VlSiftKeypoint const *key = keys + i; double angles [4] ; int nangles = 0; if (do_angle) { nangles = vl_sift_calc_keypoint_orientations(filt, angles, key) ; } else { nangles = 1; angles[0] = 0; } for (int q = 0 ; q < nangles ; ++q) { list->push_back(Feature()); Feature &f = list->back(); f.desc.resize(DIM); /* compute descriptor (if necessary) */ vl_sift_calc_keypoint_descriptor(filt, &f.desc[0], key, angles[q]) ; BOOST_FOREACH(float &v, f.desc) { /* v = round(v * SIFT_RANGE); if (v > SIFT_RANGE) v = SIFT_RANGE; */ v *= 2; if (v > 1.0) v = 1.0; } f.scale = image.getScale(); f.x = key->x; f.y = key->y; f.dir = angles[q] / M_PI / 2; f.size = key->sigma * magnif; if ((entropy(f.desc) < e_th) || !checkBlackList(f.desc)) { list->pop_back(); } } } err = vl_sift_process_next_octave (filt) ; } vl_sift_delete (filt) ; delete [] fdata; }
int main (int argc, const char * argv[]) { int w=1280,h=720; int i=0; int nkeypoints=0; int press=0; char img2_file[] = "/Users/quake0day/ana2/MVI_0124_QT 768Kbps_012.mov"; vl_bool render=1; vl_bool first=1; VlSiftFilt * myFilter=0; VlSiftKeypoint const* keys; //CvCapture * camera = cvCreateCameraCapture (CV_CAP_ANY); CvCapture * camera = cvCreateFileCapture(img2_file); vl_sift_pix *descriptorsA, *descriptorsB; int ndescA=0, ndescB=0; //DescriptorA file int dscfd; struct stat filestat; dscfd = open("/Users/quake0day/ana2/saveC.jpg.dsc", O_RDONLY, 0644); fstat(dscfd, &filestat); int filesize=filestat.st_size; descriptorsA=(vl_sift_pix*)mmap(0, filesize, PROT_READ, MAP_SHARED, dscfd, 0); ndescA=(filesize/sizeof(vl_sift_pix))/DESCSIZE; printf("number of descriptors: %d\n", ndescA); //Build kdtreeA VlKDForest *myforest=vl_kdforest_new(VL_TYPE_FLOAT, DESCSIZE, 1); vl_kdforest_build(myforest, ndescA, descriptorsA); //DescriptorsB file dscfd=open("/Users/quake0day/ana2/saveD.jpg.dsc", O_RDONLY, 0644); fstat(dscfd, &filestat); filesize=filestat.st_size; descriptorsB=(vl_sift_pix*)mmap(0, filesize, PROT_READ, MAP_SHARED, dscfd, 0); ndescB=(filesize/sizeof(vl_sift_pix))/DESCSIZE; printf("number of descriptors: %d\n", ndescB); //Build kdtreeB VlKDForest *myforestB=vl_kdforest_new(VL_TYPE_FLOAT, DESCSIZE, 1); vl_kdforest_build(myforestB, ndescB, descriptorsB); //Neighbors VlKDForestNeighbor *neighbors=(VlKDForestNeighbor*)malloc(sizeof(VlKDForestNeighbor)); VlKDForestNeighbor *neighborsB=(VlKDForestNeighbor*)malloc(sizeof(VlKDForestNeighbor)); //Image variables vl_sift_pix* fim; int err=0; int octave, nlevels, o_min; cvNamedWindow("Hello", 1); //For text CvFont font; double hScale=2; double vScale=2; int lineWidth=2; cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth, 1); IplImage *myCVImage=cvQueryFrame(camera);//cvLoadImage("2.jpg", -1); IplImage *afterCVImage=cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); IplImage *resizingImg=cvCreateImage(cvSize(w, h), myCVImage->depth, myCVImage->nChannels); octave=2; nlevels=5; o_min=1; myFilter=vl_sift_new(w, h, octave, nlevels, o_min); vl_sift_set_peak_thresh(myFilter, 0.5); fim=malloc(sizeof(vl_sift_pix)*w*h); float thre; while (myCVImage) { dprintf("%d*%d\n",myCVImage->width,myCVImage->height); cvResize(myCVImage, resizingImg, CV_INTER_AREA); dprintf("resized scale:%d*%d\n",myCVImage->width,myCVImage->height); if (press=='s') { cvSaveImage("save.jpg", resizingImg); } cvConvertImage(resizingImg, afterCVImage, 0); for (i=0; i<h; i++) { for (int j=0; j<w; j++) { fim[i*w+j]=CV_IMAGE_ELEM(afterCVImage,uchar,i,j); } } //vl_sift_set_peak_thresh(myFilter, 0.5); //vl_sift_set_edge_thresh(myFilter, 10.0); first=1; while (1) { printf("~~~~~~~~~~start of octave~~~~~~~~~~~~\n"); if (first) { first=0; thre=0.25; err=vl_sift_process_first_octave(myFilter, fim); } else { thre=0.05; err=vl_sift_process_next_octave(myFilter); } if (err) { err=VL_ERR_OK; break; } printf("Octave: %d\n", vl_sift_get_octave_index(myFilter)); vl_sift_detect(myFilter); nkeypoints=vl_sift_get_nkeypoints(myFilter); dprintf("insider numkey:%d\n",nkeypoints); keys=vl_sift_get_keypoints(myFilter); dprintf("final numkey:%d\n",nkeypoints); int countA=0, countB=0; int matchcountA=0, matchcountB=0; float avgA=0, avgB=0; if (render) { for (i=0; i<nkeypoints; i++) { //cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 255, 50, 0), 1, CV_AA, 0); dprintf("x:%f,y:%f,s:%f,sigma:%f,\n",keys->x,keys->y,keys->s,keys->sigma); double angles [4] ; int nangles ; /* obtain keypoint orientations ........................... */ nangles=vl_sift_calc_keypoint_orientations(myFilter, angles, keys); /* for each orientation ................................... */ for (int q = 0 ; q < (unsigned) 1 ; ++q) { vl_sift_pix descr [128] ; /* compute descriptor (if necessary) */ vl_sift_calc_keypoint_descriptor(myFilter, descr, keys, angles[q]); for (int j=0; j<128; j++) { descr[j]*=512.0; descr[j]=(descr[j]<255.0)?descr[j]:255.0; } vl_kdforest_query(myforest, neighbors, 1, descr); vl_kdforest_query(myforestB, neighborsB, 1, descr); if (neighbors->distance<50000.0) { matchcountA++; cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 0, 0, 255), 1, CV_AA, 0); } if (neighborsB->distance<50000.0) { matchcountB++; cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(0, 50, 255, 100), 1, CV_AA, 0); } countA++; avgA+=neighbors->distance; countB++; avgB+=neighborsB->distance; } keys++; } } avgA=avgA/countA; float percentage=((float)matchcountA*2)/ndescA; printf("Percentage:%f\n", percentage); printf("avg:%f\n",avgA); printf("thre==%f\n", thre); if (percentage>=thre) { printf("A shows!!!\n"); cvPutText (resizingImg, "A shows!!",cvPoint(50, 100), &font, cvScalar(0,255,255,0)); } avgB=avgB/countB; percentage=((float)matchcountB*2.5)/ndescB; printf("Percentage:%f\n", percentage); printf("avg:%f\n",avgB); printf("thre==%f\n", thre); if (percentage>=thre) { printf("B shows!!!\n"); cvPutText (resizingImg, "B shows!!",cvPoint(400, 100), &font, cvScalar(0,255,255,0)); } printf("~~~~~~~~~~~end of octave~~~~~~~~~~~~\n"); } cvShowImage("Hello", resizingImg); myCVImage = cvQueryFrame(camera); press=cvWaitKey(1); if( press=='q' ) break; else if( press=='r' ) render=1-render; } free(fim); free(neighbors); free(neighborsB); cvReleaseImage(&afterCVImage); cvReleaseImage(&resizingImg); cvReleaseImage(&myCVImage); return 0; }
void sift_keypoints_and_descriptors( float *pixels, int width, int height, int max_descriptors, int* nkeypoints, //output int** keypoints, //output int* ndescriptors, //output float** descriptors) //output { unsigned int seed = time(NULL); *keypoints = (int*) malloc(KEYPOINT_SPACE_SIZE * 2 * sizeof(int)); *descriptors = (float*) malloc(KEYPOINT_SPACE_SIZE * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float)); //printf("width=%d height=%d\n", width, height); //init the sift filter object VlSiftFilt *filter = vl_sift_new( width,//image width height,//image height -1,//number of octaves (-1 means all octaves) 3,//number of levels per octave 0);//startoctave (first is 0) vl_sift_set_edge_thresh(filter, 10.0); //default: 10.0 vl_sift_set_peak_thresh(filter, 0.0); //default: 0.0 //printf("a\n"); //we start with the first octave first octave (highest image resolution) vl_sift_process_first_octave(filter, pixels); int keypoint_count = 0; int descriptor_count = 0; do { //detect the keypoints of the image vl_sift_detect(filter); //and get them const VlSiftKeypoint* vlkeypoints = vl_sift_get_keypoints(filter); //iterate them int i; for(i=0; i<filter->nkeys; i++) { //save keypoint coordinates (*keypoints)[2*keypoint_count] = (int) vlkeypoints[i].x; (*keypoints)[2*keypoint_count+1] = (int) vlkeypoints[i].y; //calculate keypoint orientations double angles[4]; int norients = vl_sift_calc_keypoint_orientations( filter, angles, vlkeypoints+i); //iterate orientations int j; for(j=0; j<norients; j++) { //calculate the descriptor vl_sift_calc_keypoint_descriptor( filter, (*descriptors)+KEYPOINT_DESCRIPTOR_SIZE*descriptor_count, vlkeypoints+i, angles[j]); descriptor_count++; } keypoint_count++; } } //iterate over the rest of the octaves while(vl_sift_process_next_octave(filter) != VL_ERR_EOF); //printf("b\n"); //delete the filter object from memory vl_sift_delete(filter); //printf("c\n"); *keypoints = (int*) realloc(*keypoints, keypoint_count * 2 * sizeof(int)); *descriptors = (float*) realloc(*descriptors, descriptor_count * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float)); //shuffle the keypoints and descriptors int i; for(i=0; i<descriptor_count; i++) { int r = rand_r(&seed) % descriptor_count; int j; for(j=0; j<KEYPOINT_DESCRIPTOR_SIZE; j++) { float tmp; tmp = (*descriptors)[i*KEYPOINT_DESCRIPTOR_SIZE+j]; (*descriptors)[i*KEYPOINT_DESCRIPTOR_SIZE+j] = (*descriptors)[r*KEYPOINT_DESCRIPTOR_SIZE+j]; (*descriptors)[r*KEYPOINT_DESCRIPTOR_SIZE+j] = tmp; } } //printf("descriptor_count=%d\n", descriptor_count); *ndescriptors = (descriptor_count < max_descriptors) ? descriptor_count : max_descriptors; *descriptors = (float*) realloc(*descriptors, (*ndescriptors) * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float)); *nkeypoints = keypoint_count; }
/** @brief Detect regions on the image and compute their attributes (description) @param image Image. @param regions The detected regions and attributes (the caller must delete the allocated data) @param mask 8-bit gray image for keypoint filtering (optional). Non-zero values depict the region of interest. */ bool Describe(const image::Image<unsigned char>& image, std::unique_ptr<Regions> ®ions, const image::Image<unsigned char> * mask = NULL) { const int w = image.Width(), h = image.Height(); //Convert to float const image::Image<float> If(image.GetMat().cast<float>()); VlSiftFilt *filt = vl_sift_new(w, h, _params._num_octaves, _params._num_scales, _params._first_octave); if (_params._edge_threshold >= 0) vl_sift_set_edge_thresh(filt, _params._edge_threshold); if (_params._peak_threshold >= 0) vl_sift_set_peak_thresh(filt, 255*_params._peak_threshold/_params._num_scales); Descriptor<vl_sift_pix, 128> descr; Descriptor<unsigned char, 128> descriptor; // Process SIFT computation vl_sift_process_first_octave(filt, If.data()); Allocate(regions); // Build alias to cached data SIFT_Regions * regionsCasted = dynamic_cast<SIFT_Regions*>(regions.get()); // reserve some memory for faster keypoint saving regionsCasted->Features().reserve(2000); regionsCasted->Descriptors().reserve(2000); while (true) { vl_sift_detect(filt); VlSiftKeypoint const *keys = vl_sift_get_keypoints(filt); const int nkeys = vl_sift_get_nkeypoints(filt); // Update gradient before launching parallel extraction vl_sift_update_gradient(filt); #ifdef OPENMVG_USE_OPENMP #pragma omp parallel for private(descr, descriptor) #endif for (int i = 0; i < nkeys; ++i) { // Feature masking if (mask) { const image::Image<unsigned char> & maskIma = *mask; if (maskIma(keys[i].y, keys[i].x) == 0) continue; } double angles [4] = {0.0, 0.0, 0.0, 0.0}; int nangles = 1; // by default (1 upright feature) if (_bOrientation) { // compute from 1 to 4 orientations nangles = vl_sift_calc_keypoint_orientations(filt, angles, keys+i); } for (int q=0 ; q < nangles ; ++q) { vl_sift_calc_keypoint_descriptor(filt, &descr[0], keys+i, angles[q]); const SIOPointFeature fp(keys[i].x, keys[i].y, keys[i].sigma, static_cast<float>(angles[q])); siftDescToUChar(&descr[0], descriptor, _params._root_sift); #ifdef OPENMVG_USE_OPENMP #pragma omp critical #endif { regionsCasted->Descriptors().push_back(descriptor); regionsCasted->Features().push_back(fp); } } } if (vl_sift_process_next_octave(filt)) break; // Last octave } vl_sift_delete(filt); return true; };
PyObject * vl_siftdescriptor_python( PyArrayObject & in_grad, PyArrayObject & in_frames) { // TODO: check types and dim // "GRAD must be a 2xMxN matrix of class SINGLE." assert(in_grad.descr->type_num == PyArray_FLOAT); assert(in_frames.descr->type_num == PyArray_FLOAT64); assert(in_grad.flags & NPY_FORTRAN); assert(in_frames.flags & NPY_FORTRAN); int verbose = 0; int opt; // TODO: check if we need to do a copy of the grad array float * grad_array; vl_sift_pix *grad; int M, N; double magnif = -1; double *ikeys = 0; int nikeys = 0; int i, j; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ // get frames nb and data pointer nikeys = in_frames.dimensions[1]; ikeys = (double *) in_frames.data; // TODO: deal with optional params // while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) { // switch (opt) { // // case opt_verbose : // ++ verbose ; // break ; // // case opt_magnif : // if (!uIsRealScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) { // mexErrMsgTxt("MAGNIF must be a non-negative scalar.") ; // } // break ; // // default : // assert(0) ; // break ; // } // } // TODO: convert to Python //grad_array = mxDuplicateArray(in[IN_GRAD]); (copy?) grad = (float*) in_grad.data; //mxGetData(grad_array); M = in_grad.dimensions[1]; N = in_grad.dimensions[2]; /* transpose angles */ for (i = 1; i < 2 * M * N; i += 2) { grad[i] = VL_PI / 2 - grad[i]; } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ PyArrayObject * _descr; { VlSiftFilt *filt = 0; vl_uint8 *descr = 0; /* create a filter to process the image */ filt = vl_sift_new(M, N, -1, -1, 0); if (magnif >= 0) vl_sift_set_magnif(filt, magnif); if (verbose) { printf("siftdescriptor: filter settings:\n"); printf( "siftdescriptor: magnif = %g\n", vl_sift_get_magnif(filt)); printf("siftdescriptor: num of frames = %d\n", nikeys); } { npy_intp dims[2]; dims[0] = 128; dims[1] = nikeys; _descr = (PyArrayObject*) PyArray_NewFromDescr( &PyArray_Type, PyArray_DescrFromType(PyArray_UBYTE), 2, dims, NULL, NULL, NPY_F_CONTIGUOUS, NULL); descr = (vl_uint8*) _descr->data; } /* ............................................................... * Process each octave * ............................................................ */ for (i = 0; i < nikeys; ++i) { vl_sift_pix buf[128], rbuf[128]; double y = *ikeys++; double x = *ikeys++; double s = *ikeys++; double th = VL_PI / 2 - *ikeys++; vl_sift_calc_raw_descriptor(filt, grad, buf, M, N, x, y, s, th); transpose_descriptor(rbuf, buf); for (j = 0; j < 128; ++j) { double x = 512.0 * rbuf[j]; x = (x < 255.0) ? x : 255.0; *descr++ = (vl_uint8) (x); } } /* cleanup */ // mxDestroyArray(grad_array); vl_sift_delete(filt); } /* job done */ return PyArray_Return(_descr); }
int main (int argc, const char * argv[]) { char *imagefilename=(char*)malloc(sizeof(char)*16); char *dscfilename=(char*)malloc(sizeof(char)*16); if (argc<3) { printf("Usage: ./dump-descr image-file-name descriptor-file-name"); strcpy(imagefilename, "savekkkk.jpg"); strcpy(dscfilename, "saveD.jpg.dsc"); } else { strcpy(imagefilename,argv[1]); strcpy(dscfilename,argv[2]); } FILE* dscfile; int w=1280,h=720; int i=0; int nkeypoints=0; vl_bool render=1; vl_bool first=1; VlSiftFilt * myFilter=0; VlSiftKeypoint const* keys; char img2_file[] = "/Users/quake0day/ana2/MVI_0124.MOV"; //printf("sizeof(VlSiftKeypoint)=%d, filt=%d, pix=%d\n", sizeof(VlSiftKeypoint), sizeof(VlSiftFilt),sizeof(vl_sift_pix)); dscfile=fopen(dscfilename, "wb"); vl_sift_pix* fim; int err=0; int octave, nlevels, o_min; //vl_sift_pix descr[128]; //CvCapture * camera = cvCreateCameraCapture (CV_CAP_ANY); CvCapture * camera = cvCreateFileCapture(img2_file); cvNamedWindow("Hello", 1); IplImage *myCVImage=cvQueryFrame(camera);//cvLoadImage(imagefilename, 0); IplImage *afterCVImage=cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); IplImage *resizingImg=cvCreateImage(cvSize(w, h), myCVImage->depth, myCVImage->nChannels); octave=3; nlevels=10; o_min=1; myFilter=vl_sift_new(w, h, octave, nlevels, o_min); vl_sift_set_peak_thresh(myFilter, 0.5); fim=malloc(sizeof(vl_sift_pix)*w*h); int press=0; while (myCVImage) { dprintf("%d*%d\n",myCVImage->width,myCVImage->height); //w=myCVImage->width; //h=myCVImage->height; cvResize(myCVImage, resizingImg, CV_INTER_AREA); dprintf("resized scale:%d*%d\n",myCVImage->width,myCVImage->height); cvConvertImage(resizingImg, afterCVImage, 0); for (i=0; i<h; i++) { for (int j=0; j<w; j++) { fim[i*w+j]=CV_IMAGE_ELEM(afterCVImage,uchar,i,j); //printf("%f ", fim[i*w+j]); } } //vl_sift_set_peak_thresh(myFilter, 0.5); //vl_sift_set_edge_thresh(myFilter, 10.0); first=1; while (1) { if (first) { first=0; err=vl_sift_process_first_octave(myFilter, fim); } else { err=vl_sift_process_next_octave(myFilter); } if (err) { err=VL_ERR_OK; break; } vl_sift_detect(myFilter); nkeypoints=vl_sift_get_nkeypoints(myFilter); dprintf("insider numkey:%d\n",nkeypoints); keys=vl_sift_get_keypoints(myFilter); dprintf("final numkey:%d\n",nkeypoints); if (render) { for (i=0; i<nkeypoints; i++) { cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 255, 50, 0), 1, CV_AA, 0); //printf("x:%f,y:%f,s:%f,sigma:%f,\n",keys->x,keys->y,keys->s,keys->sigma); if (press=='d') { double angles [4] ; int nangles ; /* obtain keypoint orientations ........................... */ nangles=vl_sift_calc_keypoint_orientations(myFilter, angles, keys); /* for each orientation ................................... */ for (int q = 0 ; q < (unsigned) nangles ; ++q) { vl_sift_pix descr [128] ; //printf("\n"); /* compute descriptor (if necessary) */ vl_sift_calc_keypoint_descriptor(myFilter, descr, keys, angles[q]); for (int j=0; j<128; j++) { descr[j]*=512.0; descr[j]=(descr[j]<255.0)?descr[j]:255.0; printf("%f ", descr[j]); } fwrite(descr, sizeof(vl_sift_pix), 128, dscfile); } } keys++; } } } cvShowImage("Hello", resizingImg); myCVImage = cvQueryFrame(camera); press=cvWaitKey(1); if( press=='q' ) return 0; else if( press=='r' ) render=1-render; } free(fim); cvReleaseImage(&afterCVImage); cvReleaseImage(&resizingImg); cvReleaseImage(&myCVImage); return 0; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I = 0, IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS, OUT_INFO, OUT_END} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; VlEnumerator *pair ; float const *image ; vl_size numCols, numRows ; VlCovDetMethod method = VL_COVDET_METHOD_DOG; vl_bool estimateAffineShape = VL_FALSE ; vl_bool estimateOrientation = VL_FALSE ; vl_bool doubleImage = VL_TRUE ; vl_index octaveResolution = -1 ; double edgeThreshold = -1 ; double peakThreshold = -1 ; double lapPeakThreshold = -1 ; int descriptorType = -1 ; vl_index patchResolution = -1 ; double patchRelativeExtent = -1 ; double patchRelativeSmoothing = -1 ; float *patch = NULL ; float *patchXY = NULL ; vl_int liopNumSpatialBins = 6; vl_int liopNumNeighbours = 4; float liopRadius = 6.0; float liopIntensityThreshold = VL_NAN_F ; double boundaryMargin = 2.0 ; double * userFrames = NULL ; vl_size userFrameDimension = 0 ; vl_size numUserFrames = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < IN_END) { vlmxError(vlmxErrNotEnoughInputArguments, 0) ; } else if (nout > OUT_END) { vlmxError(vlmxErrTooManyOutputArguments, 0) ; } if (mxGetNumberOfDimensions(IN(I)) != 2 || mxGetClassID(IN(I)) != mxSINGLE_CLASS){ vlmxError(vlmxErrInvalidArgument, "I must be a matrix of class SINGLE.") ; } image = (float*) mxGetData(IN(I)) ; numRows = mxGetM(IN(I)) ; numCols = mxGetN(IN(I)) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_method: pair = vlmxDecodeEnumeration(optarg, vlCovdetMethods, VL_TRUE) ; if (pair == NULL) { vlmxError(vlmxErrInvalidArgument, "METHOD is not a supported detection method.") ; } method = (VlCovDetMethod)pair->value ; break; case opt_descriptor: pair = vlmxDecodeEnumeration(optarg, vlCovDetDescriptorTypes, VL_TRUE) ; if (pair == NULL) { vlmxError(vlmxErrInvalidArgument, "DESCRIPTOR is not a supported descriptor.") ; } descriptorType = (VlCovDetDescriptorType)pair->value ; break; case opt_estimate_affine_shape: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "ESTIMATEAFFINESHAPE must be a logical scalar value.") ; } else { estimateAffineShape = *mxGetLogicals(optarg) ; } break ; case opt_estimate_orientation: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "ESTIMATEORIENTATION must be a logical scalar value.") ; } else { estimateOrientation = *mxGetLogicals(optarg); } break ; case opt_double_image: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "DOUBLEIMAGE must be a logical scalar value.") ; } else { doubleImage = *mxGetLogicals(optarg); } break ; case opt_octave_resolution : if (!vlmxIsPlainScalar(optarg) || (octaveResolution = (vl_index)*mxGetPr(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "OCTAVERESOLUTION must be an integer not smaller than 1.") ; } break ; case opt_edge_threshold : if (!vlmxIsPlainScalar(optarg) || (edgeThreshold = *mxGetPr(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "EDGETHRESHOLD must be a real not smaller than 1.") ; } break ; case opt_peak_threshold : if (!vlmxIsPlainScalar(optarg) || (peakThreshold = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "PEAKTHRESHOLD must be a non-negative real.") ; } break ; case opt_laplacian_peak_threshold : if (!vlmxIsPlainScalar(optarg) || (lapPeakThreshold = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "LAPLACIANPEAKTHRESHOLD must be a non-negative real.") ; } break ; case opt_patch_relative_smoothing : if (!vlmxIsPlainScalar(optarg) || (patchRelativeSmoothing = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVESMOOTHING must be a non-negative real.") ; } break ; case opt_patch_relative_extent : if (!vlmxIsPlainScalar(optarg) || (patchRelativeExtent = *mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVEEXTENT must be a posiive real.") ; } break ; case opt_patch_resolution : if (!vlmxIsPlainScalar(optarg) || (patchResolution = (vl_index)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRESOLUTION must be a positive integer.") ; } break ; case opt_liop_bins : if (!vlmxIsPlainScalar(optarg) || (liopNumSpatialBins = (vl_int)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMSPATIALBINS is not a positive scalar.") ; } break ; case opt_liop_neighbours : if (!vlmxIsPlainScalar(optarg) || (liopNumNeighbours = (vl_int)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMNEIGHBOURS is not a positive scalar.") ; } break ; case opt_liop_radius : if (!vlmxIsPlainScalar(optarg) || (liopRadius = (float)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "LIOPRADIUS must is not a positive scalar.") ; } break ; case opt_liop_threshold : if (!vlmxIsPlainScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "LIOPINTENSITYTHRESHOLD is not a scalar.") ; } liopIntensityThreshold = *mxGetPr(optarg) ; break ; case opt_frames: if (!vlmxIsPlainMatrix(optarg,-1,-1)) { vlmxError(vlmxErrInvalidArgument, "FRAMES must be a palin matrix.") ; } numUserFrames = mxGetN (optarg) ; userFrameDimension = mxGetM (optarg) ; userFrames = mxGetPr (optarg) ; switch (userFrameDimension) { case 2: case 3: case 4: case 5: case 6: /* ok */ break ; default: vlmxError(vlmxErrInvalidArgument, "FRAMES of dimensions %d are not recognised", userFrameDimension); ; } break ; default : abort() ; } } if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT ; switch (descriptorType) { case VL_COVDET_DESC_NONE : break ; case VL_COVDET_DESC_PATCH : if (patchResolution < 0) patchResolution = 20 ; if (patchRelativeExtent < 0) patchRelativeExtent = 6 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ; break ; case VL_COVDET_DESC_SIFT : /* the patch parameters are selected to match the SIFT descriptor geometry */ if (patchResolution < 0) patchResolution = 15 ; if (patchRelativeExtent < 0) patchRelativeExtent = 7.5 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ; break ; case VL_COVDET_DESC_LIOP : if (patchResolution < 0) patchResolution = 20 ; if (patchRelativeExtent < 0) patchRelativeExtent = 4 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 0.5 ; break ; } if (patchResolution > 0) { vl_size w = 2*patchResolution + 1 ; patch = mxMalloc(sizeof(float) * w * w); patchXY = mxMalloc(2 * sizeof(float) * w * w); } if (descriptorType == VL_COVDET_DESC_LIOP && liopRadius > patchResolution) { vlmxError(vlmxErrInconsistentData, "LIOPRADIUS is larger than PATCHRESOLUTION.") ; } /* ----------------------------------------------------------------- * Detector * -------------------------------------------------------------- */ { VlCovDet * covdet = vl_covdet_new(method) ; /* set covdet parameters */ vl_covdet_set_transposed(covdet, VL_TRUE) ; vl_covdet_set_first_octave(covdet, doubleImage ? -1 : 0) ; if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution) ; if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold) ; if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold) ; if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold) ; if (verbose) { VL_PRINTF("vl_covdet: doubling image: %s\n", VL_YESNO(vl_covdet_get_first_octave(covdet) < 0)) ; } /* process the image */ vl_covdet_put_image(covdet, image, numRows, numCols) ; /* fill with frames: eitehr run the detector of poure them in */ if (numUserFrames > 0) { vl_index k ; if (verbose) { mexPrintf("vl_covdet: sourcing %d frames\n", numUserFrames) ; } for (k = 0 ; k < (signed)numUserFrames ; ++k) { double const * uframe = userFrames + userFrameDimension * k ; double a11, a21, a12, a22 ; VlCovDetFeature feature ; feature.peakScore = VL_INFINITY_F ; feature.edgeScore = 1.0 ; feature.frame.x = (float)uframe[1] - 1 ; feature.frame.y = (float)uframe[0] - 1 ; switch (userFrameDimension) { case 2: a11 = 1.0 ; a21 = 0.0 ; a12 = 0.0 ; a22 = 1.0 ; break ; case 3: a11 = uframe[2] ; a21 = 0.0 ; a12 = 0.0 ; a22 = uframe[2] ; break ; case 4: { double sigma = uframe[2] ; double c = cos(uframe[3]) ; double s = sin(uframe[3]) ; a11 = sigma * c ; a21 = sigma * s ; a12 = sigma * (-s) ; a22 = sigma * c ; break ; } case 5: { double d2 ; if (uframe[2] < 0) { vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ; } a11 = sqrt(uframe[2]) ; a21 = uframe[3] / VL_MAX(a11, 1e-10) ; a12 = 0.0 ; d2 = uframe[4] - a21*a21 ; if (d2 < 0) { vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ; } a22 = sqrt(d2) ; break ; } case 6: { a11 = uframe[2] ; a21 = uframe[3] ; a12 = uframe[4] ; a22 = uframe[5] ; break ; } default: a11 = 0 ; a21 = 0 ; a12 = 0 ; a22 = 0 ; assert(0) ; } feature.frame.a11 = (float)a22 ; feature.frame.a21 = (float)a12 ; feature.frame.a12 = (float)a21 ; feature.frame.a22 = (float)a11 ; vl_covdet_append_feature(covdet, &feature) ; } } else { if (verbose) { mexPrintf("vl_covdet: detector: %s\n", vl_enumeration_get_by_value(vlCovdetMethods, method)->name) ; mexPrintf("vl_covdet: peak threshold: %g, edge threshold: %g\n", vl_covdet_get_peak_threshold(covdet), vl_covdet_get_edge_threshold(covdet)) ; } vl_covdet_detect(covdet) ; if (verbose) { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n", vl_covdet_get_num_non_extrema_suppressed(covdet), vl_covdet_get_non_extrema_suppression_threshold(covdet)) ; switch (method) { case VL_COVDET_METHOD_HARRIS_LAPLACE: case VL_COVDET_METHOD_HESSIAN_LAPLACE: { vl_size numScales ; vl_size const * numFeaturesPerScale ; numFeaturesPerScale = vl_covdet_get_laplacian_scales_statistics (covdet, &numScales) ; mexPrintf("vl_covdet: Laplacian scales:") ; for (i = 0 ; i <= (signed)numScales ; ++i) { mexPrintf("%d with %d scales;", numFeaturesPerScale[i], i) ; } mexPrintf("\n") ; } break ; default: break ; } mexPrintf("vl_covdet: detected %d features\n", numFeatures) ; } if (boundaryMargin > 0) { vl_covdet_drop_features_outside (covdet, boundaryMargin) ; if (verbose) { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: kept %d inside the boundary margin (%g)\n", numFeatures, boundaryMargin) ; } } } /* affine adaptation if needed */ if (estimateAffineShape) { if (verbose) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: estimating affine shape for %d features\n", numFeaturesBefore) ; } vl_covdet_extract_affine_shape(covdet) ; if (verbose) { vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter) ; } } /* orientation estimation if needed */ if (estimateOrientation) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; vl_size numFeaturesAfter ; vl_covdet_extract_orientations(covdet) ; numFeaturesAfter = vl_covdet_get_num_features(covdet) ; if (verbose && numFeaturesAfter > numFeaturesBefore) { mexPrintf("vl_covdet: %d duplicate features were crated due to ambiguous " "orientation detection (%d total)\n", numFeaturesAfter - numFeaturesBefore, numFeaturesAfter) ; } } /* store results back */ { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); double * pt ; OUT(FRAMES) = mxCreateDoubleMatrix (6, numFeatures, mxREAL) ; pt = mxGetPr(OUT(FRAMES)) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { /* save the transposed frame, adjust origin to MATLAB's*/ *pt++ = feature[i].frame.y + 1 ; *pt++ = feature[i].frame.x + 1 ; *pt++ = feature[i].frame.a22 ; *pt++ = feature[i].frame.a12 ; *pt++ = feature[i].frame.a21 ; *pt++ = feature[i].frame.a11 ; } } if (nout >= 2) { switch (descriptorType) { case VL_COVDET_DESC_NONE: OUT(DESCRIPTORS) = mxCreateDoubleMatrix(0,0,mxREAL); break ; case VL_COVDET_DESC_PATCH: { vl_size numFeatures ; VlCovDetFeature const * feature ; vl_index i ; vl_size w = 2*patchResolution + 1 ; float * desc ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=patch, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } numFeatures = vl_covdet_get_num_features(covdet) ; feature = vl_covdet_get_features(covdet); OUT(DESCRIPTORS) = mxCreateNumericMatrix(w*w, numFeatures, mxSINGLE_CLASS, mxREAL) ; desc = mxGetData(OUT(DESCRIPTORS)) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { vl_covdet_extract_patch_for_frame(covdet, desc, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame) ; desc += w*w ; } break ; } case VL_COVDET_DESC_SIFT: { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0) ; vl_index i ; vl_size dimension = 128 ; vl_size patchSide = 2 * patchResolution + 1 ; double patchStep = (double)patchRelativeExtent / patchResolution ; float tempDesc [128] ; float * desc ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=sift, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL) ; desc = mxGetData(OUT(DESCRIPTORS)) ; vl_sift_set_magnif(sift, 3.0) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame) ; vl_imgradient_polar_f (patchXY, patchXY +1, 2, 2 * patchSide, patch, patchSide, patchSide, patchSide) ; /* Note: the patch is transposed, so that x and y are swapped. However, if NBO is not divisible by 4, then the configuration of the SIFT orientations is not symmetric by rotations of pi/2. Hence the only option is to rotate the descriptor further by an angle we need to compute the descriptor rotaed by an additional pi/2 angle. In this manner, x concides and y is flipped. */ vl_sift_calc_raw_descriptor (sift, patchXY, tempDesc, (int)patchSide, (int)patchSide, (double)(patchSide-1) / 2, (double)(patchSide-1) / 2, (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) / patchStep, VL_PI / 2) ; flip_descriptor (desc, tempDesc) ; desc += dimension ; } vl_sift_delete(sift) ; break ; } case VL_COVDET_DESC_LIOP : { /* TODO: get parameters form input */ vl_size numFeatures = vl_covdet_get_num_features(covdet) ; vl_size dimension ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); vl_index i ; vl_size patchSide = 2 * patchResolution + 1 ; float * desc ; VlLiopDesc * liop = vl_liopdesc_new(liopNumNeighbours, liopNumSpatialBins, liopRadius, (vl_size)patchSide) ; if (!vl_is_nan_f(liopIntensityThreshold)) { vl_liopdesc_set_intensity_threshold(liop, liopIntensityThreshold) ; } dimension = vl_liopdesc_get_dimension(liop) ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=liop, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL); desc = mxGetData(OUT(DESCRIPTORS)) ; vl_tic(); for(i = 0; i < (signed)numFeatures; i++){ vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame); vl_liopdesc_process(liop, desc, patch); desc += dimension; } mexPrintf("time: %f\n",vl_toc()); mexPrintf("threshold: %f\n",liop->intensityThreshold); break; } default: assert(0) ; /* descriptor type */ } } if (nout >= 3) { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); const char* names[] = { "gss", "css", "peakScores", "edgeScores", "orientationScore", "laplacianScaleScore" }; mxArray * gss_array = _createArrayFromScaleSpace(vl_covdet_get_gss(covdet)) ; mxArray * css_array = _createArrayFromScaleSpace(vl_covdet_get_css(covdet)) ; mxArray * peak_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * edge_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * orientation_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * laplacian_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; float * peak = mxGetData(peak_array) ; float * edge = mxGetData(edge_array) ; float * orientation = mxGetData(orientation_array) ; float * laplacian = mxGetData(laplacian_array) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { peak[i] = feature[i].peakScore ; edge[i] = feature[i].edgeScore ; orientation[i] = feature[i].orientationScore ; laplacian[i] = feature[i].laplacianScaleScore ; } OUT(INFO) = mxCreateStructMatrix(1, 1, 6, names) ; mxSetFieldByNumber(OUT(INFO), 0, 0, gss_array) ; mxSetFieldByNumber(OUT(INFO), 0, 1, css_array) ; mxSetFieldByNumber(OUT(INFO), 0, 2, peak_array) ; mxSetFieldByNumber(OUT(INFO), 0, 3, edge_array) ; mxSetFieldByNumber(OUT(INFO), 0, 4, orientation_array) ; mxSetFieldByNumber(OUT(INFO), 0, 5, laplacian_array) ; } /* cleanup */ vl_covdet_delete (covdet) ; } if (patchXY) mxFree(patchXY) ; if (patch) mxFree(patch) ; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0,IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; vl_sift_pix const *data ; int M, N ; int O = - 1 ; int S = 3 ; int o_min = 0 ; double edge_thresh = -1 ; double peak_thresh = -1 ; double norm_thresh = -1 ; double magnif = -1 ; double window_size = -1 ; mxArray *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 0 ; vl_bool floatDescriptors = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { mexErrMsgTxt("One argument required.") ; } else if (nout > 2) { mexErrMsgTxt("Too many output arguments."); } if (mxGetNumberOfDimensions (in[IN_I]) != 2 || mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) { mexErrMsgTxt("I must be a matrix of class SINGLE") ; } data = (vl_sift_pix*) mxGetData (in[IN_I]) ; M = mxGetM (in[IN_I]) ; N = mxGetN (in[IN_I]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_frames : if (!vlmxIsMatrix(optarg, 4, -1)) { mexErrMsgTxt("'Frames' must be a 4 x N matrix.") ; } ikeys_array = mxDuplicateArray (optarg) ; nikeys = mxGetN (optarg) ; ikeys = mxGetPr (ikeys_array) ; if (! check_sorted (ikeys, nikeys)) { qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; } break ; default : mexPrintf("F**k you!"); abort() ; } } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt *filt ; vl_bool first ; double *frames = 0 ; void *descr = 0 ; int nframes = 0, reserved = 0, i,j,q ; /* create a filter to process the image */ filt = vl_sift_new (M, N, O, S, o_min) ; //mexPrintf("%f %f %f \n%f %f %f %f %f\n",(float)O,(float)S,(float)o_min,(float)peak_thresh // ,(float)edge_thresh,(float)norm_thresh,(float)magnif,(float)window_size); /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (first == 1) { int err ; VlSiftKeypoint const *keys = 0 ; int nkeys = 0 ; err = vl_sift_process_first_octave (filt, data) ; first = 0 ; if (err) break ; /* Run detector ............................................. */ nkeys = nikeys ; //mexPrintf("Zhu: entering sweeping nkeys, nkeys = %d, i = %d \n", nkeys, i); /* For each keypoint ........................................ */ for (; i < nkeys ; ++i) { int h; vl_sift_pix buf[128]; vl_sift_pix rbuf[128]; double angle; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* Obtain keypoint orientations ........................... */ vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 1] - 1, ikeys [4 * i + 0] - 1, ikeys [4 * i + 2]) ; //mexPrintf("ikeys: [%f, %f, %f]\n", (float)(ikeys [4 * i + 1] - 1), (float)(ikeys [4 * i + 0] - 1), (float)(ikeys [4 * i + 2]) ); k = &ik ; /* optionally compute orientations too */ angle = VL_PI / 2 - ikeys [4 * i + 3] ; q = 0; /* compute descriptor (if necessary) */ //int h; //mexPrintf("M = %d, N = %d.\n",M,N); //for (h = 0; h < 300; h++) //{ // mexPrintf("%f ",data[h]); // if (h % 8 == 7) mexPrintf("\n"); //} if (nout > 1) { //mexPrintf("angles = %f, x = %f(%d), y = %f(%d), s = %f(%d), o = %d, sigma = %f.\n buf = [", //angle,k->x,k->ix,k->y,k->iy,k->s,k->is,k->o,k->sigma); vl_sift_calc_keypoint_descriptor (filt, buf, k, angle) ; //for (h = 0; h < 128; h++) //{ // mexPrintf("%f ",(float)buf[h]); // if (h % 8 == 7) mexPrintf("\n"); //} //mexPrintf("...].\nrbuf = ["); transpose_descriptor (rbuf, buf) ; //for (h = 0; h < 128; h++) //{ // mexPrintf("%f ",(float)rbuf[h]); // if (h % 8 == 7) mexPrintf("\n"); //} //mexPrintf("...].\n"); } /* make enough room for all these keypoints and more */ if (reserved < nframes + 1) { reserved += 2 * nkeys ; frames = mxRealloc (frames, 4 * sizeof(double) * reserved) ; if (nout > 1) { if (! floatDescriptors) { descr = mxRealloc (descr, 128 * sizeof(vl_uint8) * reserved) ; } else { descr = mxRealloc (descr, 128 * sizeof(float) * reserved) ; } } } /* Save back with MATLAB conventions. Notice tha the input * image was the transpose of the actual image. */ frames [4 * nframes + 0] = k -> y + 1 ; frames [4 * nframes + 1] = k -> x + 1 ; frames [4 * nframes + 2] = k -> sigma ; frames [4 * nframes + 3] = VL_PI / 2 - angle; //mexPrintf("Zhu: %d\n", nframes); if (nout > 1) { if (! floatDescriptors) { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; x = (x < 255.0F) ? x : 255.0F ; ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ; } } else { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; ((float*)descr) [128 * nframes + j] = x ; } } } ++ nframes ; /* next orientation */ } /* next keypoint */ //break; //mexPrintf("Zhu: skip subsequent octave\n"); } /* next octave */ //mexPrintf("nframes_tot = %d\n",nframes); /* ............................................................... * Save back * ............................................................ */ { mwSize dims [2] ; /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_FRAMES] = mxCreateNumericArray (2, dims, mxDOUBLE_CLASS, mxREAL) ; /* set array content to be the frames buffer */ dims [0] = 4 ; dims [1] = nframes ; mxSetPr (out[OUT_FRAMES], frames) ; mxSetDimensions (out[OUT_FRAMES], dims, 2) ; if (nout > 1) { /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS, mxREAL) ; /* set array content to be the descriptors buffer */ dims [0] = 128 ; dims [1] = nframes ; mxSetData (out[OUT_DESCRIPTORS], descr) ; mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ; } } /* cleanup */ vl_sift_delete (filt) ; if (ikeys_array) mxDestroyArray(ikeys_array) ; } /* end: do job */ }
void siftDesctor::covdet_keypoints_and_descriptors(cv::Mat &img, std::vector<std::vector<float>> &frames, std::vector<std::vector<float>> &desctor, bool rootSIFT, bool verbose){ bool display_image = 0; vl_size numCols, numRows; numCols = img.cols; //61 numRows = img.rows; //74 img = (cv::Mat_<float>)img/255.0; // This is for debugging, checking the image was correctly loaded. if (display_image) { std::string window_name = "Image"; namedWindow(window_name, cv::WINDOW_AUTOSIZE );// Create a window for display. imshow(window_name, img); // Show our image inside it. cv::waitKey(0); // Wait for a keystroke in the window } cv::Mat imageTest(img.rows, img.cols, CV_32FC1); cv::Mat imgT(img.cols, img.rows, CV_32FC1); img.copyTo(imageTest); imgT = img.t(); imgT = imgT.reshape(1,1); //std::cout << imgT << std::endl; float *image = new float[(int)imgT.cols]; for(int i = 0; i < imgT.cols; i++){ image[i] = (float)imgT.at<float>(i); //std::cout << image[i] << " "; } typedef enum _VlCovDetDescriptorType{ VL_COVDET_DESC_SIFT } VlCovDetDescriporType; VlCovDetMethod method = VL_COVDET_METHOD_DOG; //vl_bool estimateAffineShape = VL_FALSE; //vl_bool estimateOrientation = VL_FALSE; vl_bool doubleImage = VL_TRUE; vl_index octaveResolution = -1; double edgeThreshold = 10; double peakThreshold = 0.01; double lapPeakThreshold = -1; int descriptorType = -1; vl_index patchResolution = -1; double patchRelativeExtent = -1; double patchRelativeSmoothing = -1; double boundaryMargin = 2.0; if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT; switch (descriptorType){ case VL_COVDET_DESC_SIFT: if (patchResolution < 0) patchResolution = 15; if (patchRelativeExtent < 0) patchRelativeExtent = 10; if (patchRelativeSmoothing <0) patchRelativeSmoothing = 1; if (verbose){ printf("vl_covdet: VL_COVDET_DESC_SIFT: patchResolution=%lld, patchRelativeExtent=%g, patchRelativeSmoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } } if (1) { //clock_t t_start = clock(); // create a detector object: VL_COVDET_METHOD_HESSIAN VlCovDet * covdet = vl_covdet_new(method); // set various parameters (optional) vl_covdet_set_transposed(covdet, VL_TRUE); vl_covdet_set_first_octave(covdet, doubleImage? -1 : 0); if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution); if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold); if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold); if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold); //vl_covdet_set_target_num_features(covdet, target_num_features); //vl_covdet_set_use_adaptive_suppression(covdet, use_adaptive_suppression); if(verbose){ VL_PRINTF("vl_covdet: doubling image: %s, image size: numRows = %d, numCols = %d\n", VL_YESNO(vl_covdet_get_first_octave(covdet) < 0), numCols, numRows); } // process the image and run the detector, im.shape(1) is column, im.shape(0) is row //see http://www.vlfeat.org/api/covdet_8h.html#affcedda1fdc7ed72d223e0aab003024e for detail vl_covdet_put_image(covdet, image, numRows, numCols); if (verbose) { VL_PRINTF("vl_covdet: detector: %s\n", vl_enumeration_get_by_value(vlCovdetMethods, method)->name); VL_PRINTF("vl_covdet: peak threshold: %g, edge threshold: %g\n", vl_covdet_get_peak_threshold(covdet),vl_covdet_get_edge_threshold(covdet)); } vl_covdet_detect(covdet); if (verbose) { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n", vl_covdet_get_num_non_extrema_suppressed(covdet), vl_covdet_get_non_extrema_suppression_threshold(covdet)); VL_PRINTF("vl_covdet: detected %d features", numFeatures); } //drop feature on the margin(optimal) if(boundaryMargin > 0){ vl_covdet_drop_features_outside(covdet, boundaryMargin); if(verbose){ vl_size numFeatures = vl_covdet_get_num_features(covdet); VL_PRINTF("vl_covdet: kept %d inside the boundary margin (%g)\n", numFeatures, boundaryMargin); } } /* affine adaptation if needed */ bool estimateAffineShape = true; if (estimateAffineShape) { if (verbose) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: estimating affine shape for %d features", numFeaturesBefore); } vl_covdet_extract_affine_shape(covdet) ; if (verbose) { vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter); } } // compute the orientation of the features (optional) //vl_covdet_extract_orientations(covdet); // get feature descriptors vl_size numFeatures = vl_covdet_get_num_features(covdet); VlCovDetFeature const * feature = (VlCovDetFeature const *)vl_covdet_get_features(covdet); VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0); vl_size patchSide = 2 * patchResolution + 1; double patchStep = (double)patchRelativeExtent / patchResolution; float tempDesc[128]; //float * desc; if (verbose) { VL_PRINTF("vl_covdet: descriptors: type = sift, resolution = %d, extent = %g, smoothing = %g\n", patchResolution,patchRelativeExtent, patchRelativeSmoothing); } //std::vector<float> points(6 * numFeatures); //std::vector<float> desc(dimension * numFeatures); std::vector<float> desc(128); std::vector<float> frame(6); //std::vector<float> patch(patchSide * patchSide); //std::vector<float> patchXY(2 * patchSide * patchSide); float *patch = (float*)malloc(sizeof(float)*patchSide*patchSide); float *patchXY = (float*)malloc(2*sizeof(float)*patchSide*patchSide); vl_sift_set_magnif(sift, 3.0); for (vl_index i = 0; i < (signed)numFeatures; i++) { frame.clear(); frame.push_back(feature[i].frame.y); frame.push_back(feature[i].frame.x); frame.push_back(feature[i].frame.a22); frame.push_back(feature[i].frame.a12); frame.push_back(feature[i].frame.a21); frame.push_back(feature[i].frame.a11); frames.push_back(frame); //std::cout << std::setiosflags(std::ios::fixed); //std::cout << std::setprecision(6) << feature[i].frame.y << ", " << feature[i].frame.x << ", " << feature[i].frame.a22 << ", "<< feature[i].frame.a12 << ", "<< feature[i].frame.a21 << ", " << feature[i].frame.a11 << ", "<< std::endl; vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame); vl_imgradient_polar_f(patchXY, patchXY+1, 2, 2 * patchSide, patch, patchSide, patchSide, patchSide); vl_sift_calc_raw_descriptor(sift, patchXY, tempDesc, (int)patchSide, (int)patchSide, (double)(patchSide - 1) / 2, (double)(patchSide - 1) / 2, (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) / patchStep, VL_PI / 2); flip_descriptor(desc, tempDesc); // sift or rootsift if(rootSIFT == true){ std::vector<float> rootdesc = rootsift(desc); desctor.push_back(rootdesc); }else{ desctor.push_back(desc); } /*std::cout << std::setiosflags(std::ios::fixed); for(vl_index j = 0; j < 128; j++){ std::cout << std::setprecision(6) << desc[j] << " "; } std::cout << "\n" << std::endl;*/ } vl_sift_delete(sift); vl_covdet_delete(covdet); //delete covdet; delete patch; delete patchXY; } }
/** @brief SIFT driver entry point **/ int main(int argc, char **argv) { /* algorithm parameters */ double edge_thresh = -1 ; double peak_thresh = -1 ; double magnif = -1 ; int O = -1, S = 3, omin = -1 ; vl_bool err = VL_ERR_OK ; char err_msg [1024] ; int n ; int exit_code = 0 ; int verbose = 0 ; vl_bool force_output = 0 ; vl_bool force_orientations = 0 ; VlFileMeta out = {1, "%.sift", VL_PROT_ASCII, "", 0} ; VlFileMeta frm = {0, "%.frame", VL_PROT_ASCII, "", 0} ; VlFileMeta dsc = {0, "%.descr", VL_PROT_ASCII, "", 0} ; VlFileMeta met = {0, "%.meta", VL_PROT_ASCII, "", 0} ; VlFileMeta gss = {0, "%.pgm", VL_PROT_ASCII, "", 0} ; VlFileMeta ifr = {0, "%.frame", VL_PROT_ASCII, "", 0} ; #define ERRF(msg, arg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg, arg) ; \ break ; \ } #define ERR(msg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg) ; \ break ; \ } /* ----------------------------------------------------------------- * Parse options * -------------------------------------------------------------- */ while (!err) { int ch = getopt_long(argc, argv, opts, longopts, 0) ; /* If there are no files passed as input, print the help and settings */ if (ch == -1 && argc - optind == 0) ch = 'h'; /* end of option list? */ if (ch == -1) break; switch (ch) { case '?' : /* unkown option ............................................ */ ERRF("Invalid option '%s'.", argv [optind - 1]) ; break ; case ':' : /* missing argument ......................................... */ ERRF("Missing mandatory argument for option '%s'.", argv [optind - 1]) ; break ; case 'h' : /* --help ................................................... */ printf (help_message, argv [0]) ; printf ("SIFT filespec: `%s'\n", out.pattern) ; printf ("Frames filespec: `%s'\n", frm.pattern) ; printf ("Descriptors filespec: `%s'\n", dsc.pattern) ; printf ("Meta filespec: `%s'\n", met.pattern) ; printf ("GSS filespec: '%s'\n", gss.pattern) ; printf ("Read frames filespec: '%s'\n", ifr.pattern) ; printf ("Version: driver %s; libvl %s\n", VL_XSTRINGIFY(VL_SIFT_DRIVER_VERSION), vl_get_version_string()) ; exit (0) ; break ; case 'v' : /* --verbose ................................................ */ ++ verbose ; break ; case 'o' : /* --output ................................................ */ err = vl_file_meta_parse (&out, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; force_output = 1 ; break ; case opt_frames : /* --frames ................................................ */ err = vl_file_meta_parse (&frm, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_descriptors : /* --descriptor ............................................. */ err = vl_file_meta_parse (&dsc, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break; case opt_meta : /* --meta ................................................... */ err = vl_file_meta_parse (&met, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; if (met.protocol != VL_PROT_ASCII) ERR("meta file supports only ASCII protocol") ; break ; case opt_read_frames : /* --read_frames ............................................ */ err = vl_file_meta_parse (&ifr, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_gss : /* --gss .................................................... */ err = vl_file_meta_parse (&gss, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case 'O' : /* --octaves ............................................... */ n = sscanf (optarg, "%d", &O) ; if (n == 0 || O < 0) ERRF("The argument of '%s' must be a non-negative integer.", argv [optind - 1]) ; break ; case 'S' : /* --levels ............................................... */ n = sscanf (optarg, "%d", &S) ; if (n == 0 || S < 0) ERRF("The argument of '%s' must be a non-negative integer.", argv [optind - 1]) ; break ; case opt_first_octave : /* --first-octave ......................................... */ n = sscanf (optarg, "%d", &omin) ; if (n == 0) ERRF("The argument of '%s' must be an integer.", argv [optind - 1]) ; break ; case opt_edge_thresh : /* --edge-thresh ........................................... */ n = sscanf (optarg, "%lf", &edge_thresh) ; if (n == 0 || edge_thresh < 1) ERRF("The argument of '%s' must be not smaller than 1.", argv [optind - 1]) ; break ; case opt_peak_thresh : /* --edge-thresh ........................................... */ n = sscanf (optarg, "%lf", &peak_thresh) ; if (n == 0 || peak_thresh < 0) ERRF("The argument of '%s' must be a non-negative float.", argv [optind - 1]) ; break ; case opt_magnif : /* --magnif .............................................. */ n = sscanf (optarg, "%lf", &magnif) ; if (n == 0 || magnif < 1) ERRF("The argument of '%s' must be a non-negative float.", argv [optind - 1]) ; break ; case opt_orientations : /* --orientations ......................................... */ force_orientations = 1 ; break ; case 0 : default : /* should not get here ...................................... */ assert (0) ; break ; } } /* check for parsing errors */ if (err) { fprintf(stderr, "%s: error: %s (%d)\n", argv [0], err_msg, err) ; exit (1) ; } /* parse other arguments (filenames) */ argc -= optind ; argv += optind ; /* if --output is not specified, specifying --frames or --descriptors prevent the aggregate outout file to be produced. */ if (! force_output && (frm.active || dsc.active)) { out.active = 0 ; } if (verbose > 1) { #define PRNFO(name,fm) \ printf("sift: " name) ; \ printf("%3s ", (fm).active ? "yes" : "no") ; \ printf("%-6s ", vl_string_protocol_name ((fm).protocol)) ; \ printf("%-10s\n", (fm).pattern) ; PRNFO("write aggregate . ", out) ; PRNFO("write frames .... ", frm) ; PRNFO("write descriptors ", dsc) ; PRNFO("write meta ...... ", met) ; PRNFO("write GSS ....... ", gss) ; PRNFO("read frames .... ", ifr) ; if (force_orientations) printf("sift: will compute orientations\n") ; } /* ------------------------------------------------------------------ * Process one image per time * --------------------------------------------------------------- */ while (argc--) { char basename [1024] ; char const *name = *argv++ ; FILE *in = 0 ; vl_uint8 *data = 0 ; vl_sift_pix *fdata = 0 ; VlPgmImage pim ; VlSiftFilt *filt = 0 ; int q, i ; vl_bool first ; double *ikeys = 0 ; int nikeys = 0, ikeys_size = 0 ; /* ............................................................... * Determine files * ............................................................ */ /* get basenmae from filename */ q = vl_string_basename (basename, sizeof(basename), name, 1) ; err = (q >= sizeof(basename)) ; if (err) { snprintf(err_msg, sizeof(err_msg), "Basename of '%s' is too long", name); err = VL_ERR_OVERFLOW ; goto done ; } if (verbose) { printf ("sift: <== '%s'\n", name) ; } if (verbose > 1) { printf ("sift: basename is '%s'\n", basename) ; } /* open input file */ in = fopen (name, "rb") ; if (!in) { err = VL_ERR_IO ; snprintf(err_msg, sizeof(err_msg), "Could not open '%s' for reading.", name) ; goto done ; } /* ............................................................... * Read data * ............................................................ */ /* read PGM header */ err = vl_pgm_extract_head (in, &pim) ; if (err) { switch (vl_err_no) { case VL_ERR_PGM_IO : snprintf(err_msg, sizeof(err_msg), "Cannot read from '%s'.", name) ; err = VL_ERR_IO ; break ; case VL_ERR_PGM_INV_HEAD : snprintf(err_msg, sizeof(err_msg), "'%s' contains a malformed PGM header.", name) ; err = VL_ERR_IO ; goto done ; } } if (verbose) printf ("sift: image is %d by %d pixels\n", pim. width, pim. height) ; /* allocate buffer */ data = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim) * sizeof (vl_uint8) ) ; fdata = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim) * sizeof (vl_sift_pix)) ; if (!data || !fdata) { err = VL_ERR_ALLOC ; snprintf(err_msg, sizeof(err_msg), "Could not allocate enough memory.") ; goto done ; } /* read PGM body */ err = vl_pgm_extract_data (in, &pim, data) ; if (err) { snprintf(err_msg, sizeof(err_msg), "PGM body malformed.") ; err = VL_ERR_IO ; goto done ; } /* convert data type */ for (q = 0 ; q < pim.width * pim.height ; ++q) fdata [q] = data [q] ; /* ............................................................... * Optionally source keypoints * ............................................................ */ #define WERR(name,op) \ if (err == VL_ERR_OVERFLOW) { \ snprintf(err_msg, sizeof(err_msg), \ "Output file name too long.") ; \ goto done ; \ } else if (err) { \ snprintf(err_msg, sizeof(err_msg), \ "Could not open '%s' for " #op, name) ; \ goto done ; \ } if (ifr.active) { /* open file */ err = vl_file_meta_open (&ifr, basename, "rb") ; WERR(ifr.name, reading) ; #define QERR \ if (err ) { \ snprintf (err_msg, sizeof(err_msg), \ "'%s' malformed", ifr.name) ; \ err = VL_ERR_IO ; \ goto done ; \ } while (1) { double x, y, s, th ; /* read next guy */ err = vl_file_meta_get_double (&ifr, &x) ; if (err == VL_ERR_EOF) break; else QERR ; err = vl_file_meta_get_double (&ifr, &y ) ; QERR ; err = vl_file_meta_get_double (&ifr, &s ) ; QERR ; err = vl_file_meta_get_double (&ifr, &th) ; if (err == VL_ERR_EOF) break; else QERR ; /* make enough space */ if (ikeys_size < nikeys + 1) { ikeys_size += 10000 ; ikeys = realloc (ikeys, 4 * sizeof(double) * ikeys_size) ; } /* add the guy to the buffer */ ikeys [4 * nikeys + 0] = x ; ikeys [4 * nikeys + 1] = y ; ikeys [4 * nikeys + 2] = s ; ikeys [4 * nikeys + 3] = th ; ++ nikeys ; } /* now order by scale */ qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; if (verbose) { printf ("sift: read %d keypoints from '%s'\n", nikeys, ifr.name) ; } /* close file */ vl_file_meta_close (&ifr) ; } /* ............................................................... * Open output files * ............................................................ */ err = vl_file_meta_open (&out, basename, "wb") ; WERR(out.name, writing) ; err = vl_file_meta_open (&dsc, basename, "wb") ; WERR(dsc.name, writing) ; err = vl_file_meta_open (&frm, basename, "wb") ; WERR(frm.name, writing) ; err = vl_file_meta_open (&met, basename, "wb") ; WERR(met.name, writing) ; if (verbose > 1) { if (out.active) printf("sift: writing all ....... to . '%s'\n", out.name); if (frm.active) printf("sift: writing frames .... to . '%s'\n", frm.name); if (dsc.active) printf("sift: writing descriptors to . '%s'\n", dsc.name); if (met.active) printf("sift: writign meta ...... to . '%s'\n", met.name); } /* ............................................................... * Make filter * ............................................................ */ filt = vl_sift_new (pim.width, pim.height, O, S, omin) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (!filt) { snprintf (err_msg, sizeof(err_msg), "Could not create SIFT filter.") ; err = VL_ERR_ALLOC ; goto done ; } if (verbose > 1) { printf ("sift: filter settings:\n") ; printf ("sift: octaves (O) = %d\n", vl_sift_get_noctaves (filt)) ; printf ("sift: levels (S) = %d\n", vl_sift_get_nlevels (filt)) ; printf ("sift: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; printf ("sift: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; printf ("sift: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; printf ("sift: magnif = %g\n", vl_sift_get_magnif (filt)) ; printf ("sift: will source frames? %s\n", ikeys ? "yes" : "no") ; printf ("sift: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { VlSiftKeypoint const *keys ; int nkeys ; /* calculate the GSS for the next octave .................... */ if (first) { first = 0 ; err = vl_sift_process_first_octave (filt, fdata) ; } else { err = vl_sift_process_next_octave (filt) ; } if (err) { err = VL_ERR_OK ; break ; } if (verbose > 1) { printf("sift: GSS octave %d computed\n", vl_sift_get_octave_index (filt)); } /* optionally save GSS */ if (gss.active) { err = save_gss (filt, &gss, basename, verbose) ; if (err) { snprintf (err_msg, sizeof(err_msg), "Could not write GSS to PGM file.") ; goto done ; } } /* run detector ............................................. */ if (ikeys == 0) { vl_sift_detect (filt) ; keys = vl_sift_get_keypoints (filt) ; nkeys = vl_sift_get_nkeypoints (filt) ; i = 0 ; if (verbose > 1) { printf ("sift: detected %d (unoriented) keypoints\n", nkeys) ; } } else { nkeys = nikeys ; } /* for each keypoint ........................................ */ for (; i < nkeys ; ++i) { double angles [4] ; int nangles ; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* obtain keypoint orientations ........................... */ if (ikeys) { vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 0], ikeys [4 * i + 1], ikeys [4 * i + 2]) ; if (ik.o != vl_sift_get_octave_index (filt)) { break ; } k = &ik ; /* optionally compute orientations too */ if (force_orientations) { nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } else { angles [0] = ikeys [4 * i + 3] ; nangles = 1 ; } } else { k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } /* for each orientation ................................... */ for (q = 0 ; q < nangles ; ++q) { vl_sift_pix descr [128] ; /* compute descriptor (if necessary) */ if (out.active || dsc.active) { vl_sift_calc_keypoint_descriptor (filt, descr, k, angles [q]) ; } if (out.active) { int l ; vl_file_meta_put_double (&out, k -> x ) ; vl_file_meta_put_double (&out, k -> y ) ; vl_file_meta_put_double (&out, k -> sigma ) ; vl_file_meta_put_double (&out, angles [q] ) ; for (l = 0 ; l < 128 ; ++l) { vl_file_meta_put_uint8 (&out, (vl_uint8) (512.0 * descr [l])) ; } if (out.protocol == VL_PROT_ASCII) fprintf(out.file, "\n") ; } if (frm.active) { vl_file_meta_put_double (&frm, k -> x ) ; vl_file_meta_put_double (&frm, k -> y ) ; vl_file_meta_put_double (&frm, k -> sigma ) ; vl_file_meta_put_double (&frm, angles [q] ) ; if (frm.protocol == VL_PROT_ASCII) fprintf(frm.file, "\n") ; } if (dsc.active) { int l ; for (l = 0 ; l < 128 ; ++l) { double x = 512.0 * descr[l] ; x = (x < 255.0) ? x : 255.0 ; vl_file_meta_put_uint8 (&dsc, (vl_uint8) (x)) ; } if (dsc.protocol == VL_PROT_ASCII) fprintf(dsc.file, "\n") ; } } } } /* ............................................................... * Finish up * ............................................................ */ if (met.active) { fprintf(met.file, "<sift\n") ; fprintf(met.file, " input = '%s'\n", name) ; if (dsc.active) { fprintf(met.file, " descriptors = '%s'\n", dsc.name) ; } if (frm.active) { fprintf(met.file," frames = '%s'\n", frm.name) ; } fprintf(met.file, ">\n") ; } done : /* release input keys buffer */ if (ikeys) { free (ikeys) ; ikeys_size = nikeys = 0 ; ikeys = 0 ; } /* release filter */ if (filt) { vl_sift_delete (filt) ; filt = 0 ; } /* release image data */ if (fdata) { free (fdata) ; fdata = 0 ; } /* release image data */ if (data) { free (data) ; data = 0 ; } /* close files */ if (in) { fclose (in) ; in = 0 ; } vl_file_meta_close (&out) ; vl_file_meta_close (&frm) ; vl_file_meta_close (&dsc) ; vl_file_meta_close (&met) ; vl_file_meta_close (&gss) ; vl_file_meta_close (&ifr) ; /* if bad print error message */ if (err) { fprintf (stderr, "sift: err: %s (%d)\n", err_msg, err) ; exit_code = 1 ; } } /* quit */ return exit_code ; }
static PyObject *sift(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *input, *input_frames = NULL; PyArrayObject *matin, *out_descr, *out_frames; /* Input arguments */ static char *kwlist[] = {"input", "Octave", "Levels", "FirstOctave", "Frames", "PeakThresh", "EdgeThresh", "NormThresh", "Orientations", "Verbose", NULL}; enum {IN_I=0,IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; int nout = 2; vl_sift_pix const *data ; int M, N ; int O = - 1 ; int S = 3 ; int o_min = 0 ; double edge_thresh = -1 ; double peak_thresh = -1 ; double norm_thresh = -1 ; PyArrayObject *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 0 ; // VL_USE_MATLAB_ENV ; /* Parse Python tuples into their appropriate variables */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iiiOiiiii", kwlist, &matin, &O, &S, &o_min, &input_frames, &peak_thresh, &edge_thresh, &norm_thresh, &force_orientations, &verbose)) return NULL; // matin = (PyArrayObject *) PyArray_ContiguousFromObject(input, PyArray_FLOAT, 2, 2); //if (matin == NULL) // return NULL; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (matin->nd != 2 || matin->descr->type_num != PyArray_FLOAT) { printf("I must be a 2d matrix of dtype float32\n") ; return NULL; } // Pointer to the data array in matin //data = (vl_sift_pix *) pyvector_to_Carrayptrs(matin); // vl_sift_pix is float! data = (vl_sift_pix *) matin->data; M = matin->dimensions[0]; N = matin->dimensions[1]; if (input_frames != NULL) { ikeys_array = (PyArrayObject *) PyArray_ContiguousFromObject(input_frames, PyArray_FLOAT, 2, 2); if (ikeys_array->dimensions[0] != 4) { printf("'Frames' must be a 4 x N matrix.x\n"); return NULL; } nikeys = ikeys_array->dimensions[1]; ikeys = (double *) ikeys_array->data; qsort (ikeys, nikeys, 4 * sizeof(double), korder); } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt *filt ; vl_bool first ; double *frames = 0 ; vl_uint8 *descr = 0 ; int nframes = 0, reserved = 0, i,j,q ; /* create a filter to process the image */ filt = vl_sift_new (M, N, O, S, o_min) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ; if (verbose) { printf("siftmx: filter settings:\n") ; printf("siftpy: octaves (O) = %d\n", vl_sift_get_octave_num (filt)) ; printf("siftpy: levels (S) = %d\n", vl_sift_get_level_num (filt)) ; printf("siftpy: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; printf("siftpy: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; printf("siftpy: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; printf("siftpy: norm thresh = %g\n", vl_sift_get_norm_thresh (filt)) ; printf("siftpy: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } Py_BEGIN_ALLOW_THREADS /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { int err ; VlSiftKeypoint const *keys = 0 ; int nkeys = 0 ; if (verbose) { printf ("siftpy: processing octave %d\n", vl_sift_get_octave_index (filt)) ; } /* Calculate the GSS for the next octave .................... */ if (first) { err = vl_sift_process_first_octave (filt, data) ; first = 0 ; } else { err = vl_sift_process_next_octave (filt) ; } if (err) break ; if (verbose > 1) { printf("siftpy: GSS octave %d computed\n", vl_sift_get_octave_index (filt)); } /* Run detector ............................................. */ if (nikeys < 0) { vl_sift_detect (filt) ; keys = vl_sift_get_keypoints (filt) ; nkeys = vl_sift_get_keypoints_num (filt) ; i = 0 ; if (verbose > 1) { printf ("siftpy: detected %d (unoriented) keypoints\n", nkeys) ; } } else { nkeys = nikeys ; } /* For each keypoint ........................................ */ for (; i < nkeys ; ++i) { double angles [4] ; int nangles ; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* Obtain keypoint orientations ........................... */ if (nikeys >= 0) { vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 1] - 1, ikeys [4 * i + 0] - 1, ikeys [4 * i + 2]) ; if (ik.o != vl_sift_get_octave_index (filt)) { break ; } k = &ik ; /* optionally compute orientations too */ if (force_orientations) { nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } else { angles [0] = VL_PI / 2 - ikeys [4 * i + 3] ; nangles = 1 ; } } else { k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } /* For each orientation ................................... */ for (q = 0 ; q < nangles ; ++q) { vl_sift_pix buf [128] ; vl_sift_pix rbuf [128] ; /* compute descriptor (if necessary) */ if (nout > 1) { vl_sift_calc_keypoint_descriptor (filt, buf, k, angles [q]) ; transpose_descriptor (rbuf, buf) ; } /* make enough room for all these keypoints and more */ if (reserved < nframes + 1) { reserved += 2 * nkeys ; frames = malloc (4 * sizeof(double) * reserved) ; if (nout > 1) { descr = malloc (128 * sizeof(vl_uint8) * reserved) ; } } /* Save back with MATLAB conventions. Notice tha the input * image was the transpose of the actual image. */ frames [4 * nframes + 0] = k -> y + 1 ; frames [4 * nframes + 1] = k -> x + 1 ; frames [4 * nframes + 2] = k -> sigma ; frames [4 * nframes + 3] = VL_PI / 2 - angles [q] ; if (nout > 1) { for (j = 0 ; j < 128 ; ++j) { double x = 512.0 * rbuf [j] ; x = (x < 255.0) ? x : 255.0 ; descr [128 * nframes + j] = (vl_uint8) (x) ; } } ++ nframes ; } /* next orientation */ } /* next keypoint */ } /* next octave */ if (verbose) { printf ("siftpy: found %d keypoints\n", nframes) ; } /* ............................................................... * Save back * ............................................................ */ Py_END_ALLOW_THREADS { int dims [2] ; /* create an empty array */ dims [0] = nframes ; dims [1] = 4 ; // We are allocating new memory here because its the only way to make // sure that it will get free()ed when there are no more references out_frames = (PyArrayObject*) PyArray_FromDims(2, dims, PyArray_DOUBLE); memcpy((double*) out_frames->data, frames, 4 * nframes * sizeof(double)); dims [0] = nframes ; // Numpy Array uses row format, Matlab uses column format dims [1] = 128 ; out_descr = (PyArrayObject*) PyArray_FromDims(2, dims, PyArray_UBYTE); memcpy((vl_uint8 *) out_descr->data, descr, 128 * nframes * sizeof(vl_uint8) ); } /* cleanup */ vl_sift_delete (filt) ; free(frames); free(descr); } /* end: do job */ return Py_BuildValue("(OO)",PyArray_Return(out_frames), PyArray_Return(out_descr)); }
int GetSiftFeatures(unsigned char *data, int nw, int nh, float *features, int *features_num) { vl_sift_pix *img_data = (vl_sift_pix *)malloc(sizeof(vl_sift_pix) * nw * nh); if(img_data == NULL) { printf("Memory overflow error:can't apply image data memory!\n"); return -1; } unsigned char *pixel; int i = 0, j = 0; for(i = 0;i < nh;++i) { for(j = 0;j < nw;++j) { pixel = (unsigned char *)(data + i * nw + j); img_data[i * nw + j] = *pixel; } } int noctaves = 4, nlevels = 3, o_min = -1; VlSiftFilt *sift_filt = NULL; sift_filt = vl_sift_new(nw, nh, noctaves, nlevels, o_min); int num_descriptors = 0; // int save_flag = -1; if(vl_sift_process_first_octave(sift_filt,img_data) != VL_ERR_EOF) { while(1) { vl_sift_detect(sift_filt); VlSiftKeypoint *sift_keypoints = sift_filt->keys; for(i = 0; i < sift_filt->nkeys;++i) { VlSiftKeypoint temp_sift_keypoint = *sift_keypoints; double angles[4]; int angle_count = vl_sift_calc_keypoint_orientations(sift_filt,angles,&temp_sift_keypoint); for(j = 0; j < angle_count;++j) { double temp_angle = angles[j]; float *descriptor = (float *)malloc(sizeof(float) * SIFT_DESCRIPTOR_DIM); vl_sift_calc_keypoint_descriptor(sift_filt, descriptor, &temp_sift_keypoint, temp_angle); float *curr_features = features + num_descriptors * SIFT_DESCRIPTOR_DIM; // if(save_flag == -1) // { memcpy(curr_features,descriptor,sizeof(float) * SIFT_DESCRIPTOR_DIM); //save_flag == 1; // } ++num_descriptors; free(descriptor); } ++sift_keypoints; } if(vl_sift_process_next_octave(sift_filt) == VL_ERR_EOF) { break; } } } *features_num = num_descriptors; vl_sift_delete(sift_filt); free(img_data); return 0; }