/* Create a keypoint at a peak near scale space location (s,r,c), where s is scale (index of DOGs image), and (r,c) is (row, col) location. Add to the list of keys with any new keys added. */ void InterpKeyPoint( const flimage* dogs, int s, int r, int c, const flimage& grad, LWImage<bool>& map, float octSize, keypointslist& keys, int movesRemain,siftPar &par) { /* Fit quadratic to determine offset and peak value. */ std::vector<float> offset(3); float peakval = FitQuadratic(offset, dogs, r, c); if (DEBUG) printf("peakval: %f, of[0]: %f of[1]: %f of[2]: %f\n", peakval, offset[0], offset[1], offset[2]); /* Move to an adjacent (row,col) location if quadratic interpolation is larger than 0.6 units in some direction (we use 0.6 instead of 0.5 to avoid jumping back and forth near boundary). We do not perform move to adjacent scales, as it is seldom useful and we do not have easy access to adjacent scale structures. The movesRemain counter allows only a fixed number of moves to prevent possibility of infinite loops. */ int newr = r, newc = c; if (offset[1] > 0.6 && r < dogs[0].h - 3) newr++; else if (offset[1] < -0.6 && r > 3) newr--; if (offset[2] > 0.6 && c < dogs[0].w - 3) newc++; else if (offset[2] < -0.6 && c > 3) newc--; if (movesRemain > 0 && (newr != r || newc != c)) { InterpKeyPoint(dogs, s, newr, newc, grad, map, octSize, keys,movesRemain - 1,par); return; } /* Do not create a keypoint if interpolation still remains far outside expected limits, or if magnitude of peak value is below threshold (i.e., contrast is too low). */ if (fabs(offset[0]) > 1.5 || fabs(offset[1]) > 1.5 || fabs(offset[2]) > 1.5 || fabs(peakval) < par.PeakThresh) { if (DEBUG) printf("Point not well localized by FitQuadratic\n"); par.noncorrectlylocalized++; return; } /* Check that no keypoint has been created at this location (to avoid duplicates). Otherwise, mark this map location. */ if (*map.pixel(c,r)) return; *map.pixel(c,r) = true; /* The scale relative to this octave is given by octScale. The scale units are in terms of sigma for the smallest of the Gaussians in the DOG used to identify that scale. */ float octScale = par.InitSigma * pow(2.0f, (s + offset[0]) / (float) par.Scales); /// always use histogram of orientations //if (UseHistogramOri) AssignOriHist(grad, octSize, octScale, r + offset[1], c + offset[2], keys, par); //else // AssignOriAvg( // grad, ori, octSize, octScale, // r + offset[1], c + offset[2], keys); }
/* Create a keypoint at a peak near scale space location (s,r,c), where s is scale (index of DOGs image), and (r,c) is (row, col) location. Return the list of keys with any new keys added. */ KKeypoint InterpKeyPoint(Image *dogs, int s, int r, int c, Image grad, Image ori, Image map, float octSize, KKeypoint keys, int movesRemain) { int newr = r, newc = c; float offset[3], octScale, peakval; /* The SkipInterp flag means that no interpolation will be performed and the peak will simply be assigned to the given integer sampling locations. */ if (SkipInterp) { assert(UseHistogramOri); /* Only needs testing for this case. */ if (fabs(dogs[s]->pixels[r][c]) < PeakThresh) return keys; else return AssignOriHist(grad, ori, octSize, InitSigma * pow(2.0, s / (float) Scales), (float) r, (float) c, keys); } /* Fit quadratic to determine offset and peak value. */ peakval = FitQuadratic(offset, dogs, s, r, c); /* Move to an adjacent (row,col) location if quadratic interpolation is larger than 0.6 units in some direction (we use 0.6 instead of 0.5 to avoid jumping back and forth near boundary). We do not perform move to adjacent scales, as it is seldom useful and we do not have easy access to adjacent scale structures. The movesRemain counter allows only a fixed number of moves to prevent possibility of infinite loops. */ if (offset[1] > 0.6 && r < dogs[0]->rows - 3) newr++; if (offset[1] < -0.6 && r > 3) newr--; if (offset[2] > 0.6 && c < dogs[0]->cols - 3) newc++; if (offset[2] < -0.6 && c > 3) newc--; if (movesRemain > 0 && (newr != r || newc != c)) return InterpKeyPoint(dogs, s, newr, newc, grad, ori, map, octSize, keys, movesRemain - 1); /* Do not create a keypoint if interpolation still remains far outside expected limits, or if magnitude of peak value is below threshold (i.e., contrast is too low). */ if (fabs(offset[0]) > 1.5 || fabs(offset[1]) > 1.5 || fabs(offset[2]) > 1.5 || fabs(peakval) < PeakThresh) return keys; /* Check that no keypoint has been created at this location (to avoid duplicates). Otherwise, mark this map location. */ if (map->pixels[r][c] > 0.0) return keys; map->pixels[r][c] = 1.0; /* The scale relative to this octave is given by octScale. The scale units are in terms of sigma for the smallest of the Gaussians in the DOG used to identify that scale. */ octScale = InitSigma * pow(2.0, (s + offset[0]) / (float) Scales); if (UseHistogramOri) return AssignOriHist(grad, ori, octSize, octScale, r + offset[1], c + offset[2], keys); else return AssignOriAvg(grad, ori, octSize, octScale, r + offset[1], c + offset[2], keys); }