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; }
/** @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; };
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 ; mxArray *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 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 = uNextOption(in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_octaves : if (!uIsRealScalar(optarg) || (O = (int) *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'Octaves' must be a positive integer.") ; } break ; case opt_levels : if (! uIsRealScalar(optarg) || (S = (int) *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'Levels' must be a positive integer.") ; } break ; case opt_first_octave : if (!uIsRealScalar(optarg)) { mexErrMsgTxt("'FirstOctave' must be an integer") ; } o_min = (int) *mxGetPr(optarg) ; break ; case opt_edge_thresh : if (!uIsRealScalar(optarg) || (edge_thresh = *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'EdgeThresh' must be not smaller than 1.") ; } break ; case opt_peak_thresh : if (!uIsRealScalar(optarg) || (peak_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'PeakThresh' must be a non-negative real.") ; } break ; case opt_norm_thresh : if (!uIsRealScalar(optarg) || (norm_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'NormThresh' must be a non-negative real.") ; } break ; case opt_frames : if (!uIsRealMatrix(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 ; default : assert(0) ; break ; } } /* ----------------------------------------------------------------- * 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) { mexPrintf("siftmx: filter settings:\n") ; mexPrintf("siftmx: octaves (O) = %d\n", vl_sift_get_octave_num (filt)) ; mexPrintf("siftmx: levels (S) = %d\n", vl_sift_get_level_num (filt)) ; mexPrintf("siftmx: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; mexPrintf("siftmx: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; mexPrintf("siftmx: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; mexPrintf("siftmx: norm thresh = %g\n", vl_sift_get_norm_thresh (filt)) ; mexPrintf((nikeys >= 0) ? "siftmx: will source frames? yes (%d)\n" : "siftmx: will source frames? no\n", nikeys) ; mexPrintf("siftmx: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (true) { int err ; VlSiftKeypoint const *keys = 0 ; int nkeys = 0 ; if (verbose) { mexPrintf ("siftmx: 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("siftmx: 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 ("siftmx: 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) { descr = mxRealloc (descr, 128 * sizeof(double) * 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) { mexPrintf ("siftmx: found %d keypoints\n", nframes) ; } /* ............................................................... * Save back * ............................................................ */ { int 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 ; mxSetDimensions (out[OUT_FRAMES], dims, 2) ; mxSetPr (out[OUT_FRAMES], frames) ; if (nout > 1) { /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, mxUINT8_CLASS, mxREAL) ; /* set array content to be the descriptors buffer */ dims [0] = 128 ; dims [1] = nframes ; mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ; mxSetData (out[OUT_DESCRIPTORS], descr) ; } } /* cleanup */ vl_sift_delete (filt) ; if (ikeys_array) mxDestroyArray(ikeys_array) ; } /* end: do job */ }