Mat PyramidsVl::extractFeatures(const Mat &im, vector<KeyPoint> &keypoints, int step) { Q_UNUSED(step); Mat features(0, 128, CV_32F); double magnif = 6; QList<int> sizes; sizes << 4; sizes << 6; sizes << 8; sizes << 10; /* convert to float array */ assert(im.type() == CV_8U); float *imdata = new float[im.rows * im.cols]; for (int i = 0; i < im.rows; i++) for (int j = 0; j < im.cols; j++) imdata[i * im.cols + j] = im.row(i).data[j]; float *smoothed = new float[im.rows * im.cols]; for (int i = 0; i < sizes.size(); i++) { int step = sizes[i]; /* smoothing step */ double sigma = step / magnif; vl_imsmooth_f(smoothed, im.cols, imdata, im.cols, im.rows, im.cols, sigma, sigma); memcpy(smoothed, imdata, im.rows * im.cols * 4); /* denset sift */ VlDsiftFilter *dsift = vl_dsift_new_basic(im.cols, im.rows, step, 8); vl_dsift_process(dsift, smoothed); int cnt = vl_dsift_get_keypoint_num(dsift); const float *descs = vl_dsift_get_descriptors(dsift); const VlDsiftKeypoint *kpts = vl_dsift_get_keypoints(dsift); for (int i = 0; i < cnt; i++) { Mat ft(1, 128, CV_32F); for (int j = 0; j < 128; j++) ft.at<float>(0, j) = qMin(descs[i * 128 + j] * 512, float(255)); features.push_back(ft); KeyPoint kpt; kpt.pt.x = kpts[i].x; kpt.pt.y = kpts[i].y; keypoints.push_back(kpt); } vl_dsift_delete(dsift); } delete [] imdata; delete [] smoothed; return features; }
static void _vl_scalespace_start_octave_from_previous_octave (VlScaleSpace *self, vl_index o) { double sigma, prevSigma ; float *level, *prevLevel ; vl_index prevLevelIndex ; VlScaleSpaceOctaveGeometry ogeom ; assert(self) ; assert(o > self->geom.firstOctave) ; /* must not be the first octave */ assert(o <= self->geom.lastOctave) ; /* * From the previous octave pick the level which is closer to * self->geom.octaveFirstSubdivision in this octave. * The is self->geom.octaveFirstSubdivision + self->numLevels since there are * self->geom.octaveResolution levels in an octave, provided that * this value does not exceed self->geom.octaveLastSubdivision. */ prevLevelIndex = VL_MIN(self->geom.octaveFirstSubdivision + (signed)self->geom.octaveResolution, self->geom.octaveLastSubdivision) ; prevLevel = vl_scalespace_get_level (self, o - 1, prevLevelIndex) ; level = vl_scalespace_get_level (self, o, self->geom.octaveFirstSubdivision) ; ogeom = vl_scalespace_get_octave_geometry(self, o - 1) ; copy_and_downsample (level, prevLevel, ogeom.width, ogeom.height, 1) ; /* * Add remaining smoothing, if any. */ sigma = vl_scalespace_get_level_sigma(self, o, self->geom.octaveFirstSubdivision) ; prevSigma = vl_scalespace_get_level_sigma(self, o - 1, prevLevelIndex) ; if (sigma > prevSigma) { VlScaleSpaceOctaveGeometry ogeom = vl_scalespace_get_octave_geometry(self, o) ; double deltaSigma = sqrt (sigma*sigma - prevSigma*prevSigma) ; level = vl_scalespace_get_level (self, o, self->geom.octaveFirstSubdivision) ; /* todo: this may fail due to an out-of-memory condition */ vl_imsmooth_f (level, ogeom.width, level, ogeom.width, ogeom.height, ogeom.width, deltaSigma / ogeom.step, deltaSigma / ogeom.step) ; } }
static void _vl_scalespace_start_octave_from_image (VlScaleSpace *self, float const *image, vl_index o) { float *level ; double sigma, imageSigma ; vl_index op ; assert(self) ; assert(image) ; assert(o >= self->geom.firstOctave) ; assert(o <= self->geom.lastOctave) ; /* * Copy the image to self->geom.octaveFirstSubdivision of octave o, upscaling or * downscaling as needed. */ level = vl_scalespace_get_level(self, VL_MAX(0, o), self->geom.octaveFirstSubdivision) ; copy_and_downsample(level, image, self->geom.width, self->geom.height, VL_MAX(0, o)) ; for (op = -1 ; op >= o ; --op) { VlScaleSpaceOctaveGeometry ogeom = vl_scalespace_get_octave_geometry(self, op + 1) ; float *succLevel = vl_scalespace_get_level(self, op + 1, self->geom.octaveFirstSubdivision) ; level = vl_scalespace_get_level(self, op, self->geom.octaveFirstSubdivision) ; copy_and_upsample(level, succLevel, ogeom.width, ogeom.height) ; } /* * Adjust the smoothing of the first level just initialised, accounting * for the fact that the input image is assumed to be a nominal scale * level. */ sigma = vl_scalespace_get_level_sigma(self, o, self->geom.octaveFirstSubdivision) ; imageSigma = self->geom.nominalScale ; if (sigma > imageSigma) { VlScaleSpaceOctaveGeometry ogeom = vl_scalespace_get_octave_geometry(self, o) ; double deltaSigma = sqrt (sigma*sigma - imageSigma*imageSigma) ; level = vl_scalespace_get_level (self, o, self->geom.octaveFirstSubdivision) ; vl_imsmooth_f (level, ogeom.width, level, ogeom.width, ogeom.height, ogeom.width, deltaSigma / ogeom.step, deltaSigma / ogeom.step) ; } }
void _vl_scalespace_fill_octave (VlScaleSpace *self, vl_index o) { vl_index s ; VlScaleSpaceOctaveGeometry ogeom = vl_scalespace_get_octave_geometry(self, o) ; for(s = self->geom.octaveFirstSubdivision + 1 ; s <= self->geom.octaveLastSubdivision ; ++s) { double sigma = vl_scalespace_get_level_sigma(self, o, s) ; double previousSigma = vl_scalespace_get_level_sigma(self, o, s - 1) ; double deltaSigma = sqrtf(sigma*sigma - previousSigma*previousSigma) ; float* level = vl_scalespace_get_level (self, o, s) ; float* previous = vl_scalespace_get_level (self, o, s-1) ; vl_imsmooth_f (level, ogeom.width, previous, ogeom.width, ogeom.height, ogeom.width, deltaSigma / ogeom.step, deltaSigma / ogeom.step) ; } }
void DSift::Extract(const float* gray_img, const uint32_t width, const uint32_t height, vector<VlDsiftKeypoint>* frames, vector<float>* descrs, uint32_t* dim) { if (frames != NULL) frames->clear(); if (descrs == NULL || dim == NULL) { cerr << "NULL pointer for descriptors and dim" << endl; exit(-1); } descrs->clear(); *dim = 0; const uint32_t max_sz = *(std::max_element(sizes_.begin(), sizes_.end())); const uint32_t len_img = width * height; if (!has_setup_) SetUp(width, height); else { if (width != width_ || height != height_) { cerr << "ERROR: Image size not matching!" << endl; exit(-1); } } for (size_t i = 0; i < sizes_.size(); ++i) { const uint32_t sz = sizes_[i]; const int off = std::floor(1.5 * (max_sz - sz)); vl_dsift_set_bounds(dsift_model_, bound_minx_ + std::max(0, off), bound_miny_ + std::max(0, off), std::min((int) width - 1, bound_maxx_), std::min((int) height - 1, bound_maxy_)); VlDsiftDescriptorGeometry geom; geom.numBinX = DEFAULT_NUM_BIN_X; geom.numBinY = DEFAULT_NUM_BIN_Y; geom.numBinT = DEFAULT_NUM_BIN_T; geom.binSizeX = sz; geom.binSizeY = sz; vl_dsift_set_geometry(dsift_model_, &geom); /* { int stepX; int stepY; int minX; int minY; int maxX; int maxY; vl_bool useFlatWindow; int numFrames = vl_dsift_get_keypoint_num(dsift_model_); int descrSize = vl_dsift_get_descriptor_size(dsift_model_); VlDsiftDescriptorGeometry g = *vl_dsift_get_geometry(dsift_model_); vl_dsift_get_steps(dsift_model_, &stepY, &stepX); vl_dsift_get_bounds(dsift_model_, &minY, &minX, &maxY, &maxX); useFlatWindow = vl_dsift_get_flat_window(dsift_model_); printf( "vl_dsift: bounds: [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n", minX + 1, minY + 1, maxX + 1, maxY + 1); printf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX, stepY); printf( "vl_dsift: num bins: [numBinT, numBinX, numBinY] = [%d, %d, %d]\n", g.numBinT, g.numBinX, g.numBinY); printf("vl_dsift: descriptor size: %d\n", descrSize); printf("vl_dsift: bin sizes: [binSizeX, binSizeY] = [%d, %d]\n", g.binSizeX, g.binSizeY); printf("vl_dsift: flat window: %s\n", VL_YESNO(useFlatWindow)); printf("vl_dsift: window size: %g\n", vl_dsift_get_window_size(dsift_model_)); printf("vl_dsift: num of features: %d\n", numFrames); } */ const float sigma = 1.0 * sz / magnif_; float* smooth_img = (float*) malloc(sizeof(float) * len_img); memset(smooth_img, 0, sizeof(float) * len_img); vl_imsmooth_f(smooth_img, width, gray_img, width, height, width, sigma, sigma); vl_dsift_process(dsift_model_, smooth_img); free(smooth_img); const int num_key_pts = vl_dsift_get_keypoint_num(dsift_model_); const VlDsiftKeypoint* key_points = vl_dsift_get_keypoints(dsift_model_); *dim = vl_dsift_get_descriptor_size(dsift_model_); const float* features = vl_dsift_get_descriptors(dsift_model_); float* f = (float*) malloc(sizeof(float) * num_key_pts * (*dim)); cblas_scopy(num_key_pts * (*dim), features, 1, f, 1); cblas_sscal(num_key_pts * (*dim), 512.0f, f, 1); for (uint32_t d = 0; d < num_key_pts; ++d) { const float norm = (key_points + d)->norm; if (norm < contr_thrd_) { // remove low contrast memset(f + d * (*dim), 0, sizeof(float) * (*dim)); } else { for (uint32_t j = d * (*dim); j < (d + 1) * (*dim); ++j) { float tmp = VL_MIN(f[j], 255.0); if (!float_desc_) tmp = (int) tmp; f[j] = tmp; } } } if (i == 0) { if (frames != NULL) frames->reserve(num_key_pts * sizes_.size()); descrs->reserve(num_key_pts * sizes_.size() * (*dim)); } if (frames != NULL) frames->insert(frames->end(), key_points, key_points + num_key_pts); descrs->insert(descrs->end(), f, f + num_key_pts * (*dim)); free(f); } }