Пример #1
0
/* Find the local maxima and minima of the DOG images in scale space.
   Return the keypoints for these locations, added to existing "keys".
*/
KKeypoint FindMaxMin(Image *dogs, Image *blur, float octSize, KKeypoint keys)
{
   int s, r, c, rows, cols;
   float val, **pix;
   Image map, grad, ori;
   
   rows = dogs[0]->rows;
   cols = dogs[0]->cols;

   /* Create an image map in which locations that have a keypoint are
      marked with value 1.0, to prevent two keypoints being located at
      same position.  This may seem an inefficient data structure, but
      does not add significant overhead.
   */
   map = CreateImage(rows, cols, IMAGE_POOL);
   for (r = 0; r < rows; r++)
     for (c = 0; c < cols; c++)
       map->pixels[r][c] = 0.0;

   /* Search through each scale, leaving 1 scale below and 1 above.
      There are Scales+2 dog images.
   */
   for (s = 1; s < Scales+1; s++) {
      
     /* For each intermediate image, compute gradient and orientation
	images to be used for keypoint description.
     */
     grad = CreateImage(rows, cols, IMAGE_POOL);
     ori = CreateImage(rows, cols, IMAGE_POOL);
     GradOriImages(blur[s], grad, ori);

     pix = dogs[s]->pixels;   /* Pointer to pixels for this scale. */

     /* Only find peaks at least BorderDist samples from image border, as
	peaks centered close to the border will lack stability.
     */
     assert(BorderDist >= 2);
     for (r = BorderDist; r < rows - BorderDist; r++)
       for (c = BorderDist; c < cols - BorderDist; c++) {
	 val = pix[r][c];       /* Pixel value at (r,c) position. */

	 /* DOG magnitude must be above 0.8 * PeakThresh threshold
	    (precise threshold check will be done once peak
	    interpolation is performed).  Then check whether this
	    point is a peak in 3x3 region at each level, and is not
	    on an elongated edge.
	 */
	 if (fabs(val) > 0.8 * PeakThresh  &&
	     LocalMaxMin(val, dogs[s], r, c) &&
	     LocalMaxMin(val, dogs[s-1], r, c) &&
	     LocalMaxMin(val, dogs[s+1], r, c) &&
	     NotOnEdge(dogs[s], r, c))
	   keys = InterpKeyPoint(dogs, s, r, c, grad, ori, map, octSize,
				 keys, 5);
       }
   }
   return keys;
}
Пример #2
0
/// blur[par.Scales+1] is not used in order to look for extrema
/// while these could be computed using avalaible blur and dogs
void FindMaxMin(const flimage* dogs,  const flimage& blur, int s,
                float octSize, keypointslist& keys,siftPar &par)
{

	int width = dogs[0].w, height = dogs[0].h;

	/* Create an image map in which locations that have a keypoint are
	marked with value 1.0, to prevent two keypoints being located at
	same position.  This may seem an inefficient data structure, but
	does not add significant overhead.
	*/
	LWImage<bool> map  = alloc_image<bool>(width,height);
	flimage grad = alloc_image<float>(width,height,2);
    grad.planar = false; // Contiguous norm and dir
    for(int i=map.sizeBuffer()-1; i>=0; i--)
        map.data[i]=false;
    for(int i=grad.sizeBuffer()-1; i>=0; i--)
        grad.data[i]=0.0f;
	
    /* For each intermediate image, compute gradient and orientation
    images to be used for keypoint description.  */
    compute_gradient_orientation(blur.data, grad.data, blur.w, blur.h);
	
    /* Only find peaks at least par.BorderDist samples from image border, as
    peaks centered close to the border will lack stability. */
    assert(par.BorderDist >= 2);
    float val;
    int partialcounter = 0;
    for (int r = par.BorderDist; r < height - par.BorderDist; r++) 
        for (int c = par.BorderDist; c < width - par.BorderDist; c++) {
            /* Pixel value at (c,r) position. */
            val = *dogs[1].pixel(c,r);	

            /* DOG magnitude must be above 0.8 * par.PeakThresh threshold
            (precise threshold check will be done once peak
            interpolation is performed).  Then check whether this
            point is a peak in 3x3 region at each level, and is not
            on an elongated edge.
            */
            if (fabs(val) > 0.8 * par.PeakThresh) {
                if(LocalMaxMin(val, dogs[0], r, c) &&
                   LocalMaxMin(val, dogs[1], r, c) &&
                   LocalMaxMin(val, dogs[2], r, c) &&
                   NotOnEdge(dogs[1], r, c, octSize,par)) {
                    partialcounter++;
                    if (DEBUG) printf("%d:  (%d,%d,%d)  val: %f\n",partialcounter, s,r,c,val);
                    InterpKeyPoint(dogs, s, r, c, grad,
                                   map, octSize, keys, 5,par);	
                }
            }
		}
    free(map.data);
    free(grad.data);
}
Пример #3
0
/* 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);
}
Пример #4
0
/// blur[par.Scales+1] is not used in order to look for extrema
/// while these could be computed using avalaible blur and dogs
void FindMaxMin(
	flimage* dogs,  flimage* blur,
	float octSize, keypointslist& keys,siftPar &par)
{

	int width = dogs[0].nwidth(), height = dogs[0].nheight();

	/* Create an image map in which locations that have a keypoint are
	marked with value 1.0, to prevent two keypoints being located at
	same position.  This may seem an inefficient data structure, but
	does not add significant overhead.
	*/
	flimage map(width,height,0.0f);
	flimage grad(width,height,0.0f);
	flimage ori(width,height,0.0f);
	
	/* Search through each scale, leaving 1 scale below and 1 above.
		There are par.Scales+2 dog images.
	*/
	for (int s = 1; s < par.Scales+1; s++) {

		if (DEBUG) printf("************************scale: %d\n", s);

		//getchar();

		/* For each intermediate image, compute gradient and orientation
		images to be used for keypoint description.  */
		compute_gradient_orientation(blur[s].getPlane(), grad.getPlane(), ori.getPlane(), blur[s].nwidth(), blur[s].nheight());

	
		/* Only find peaks at least par.BorderDist samples from image border, as
		peaks centered close to the border will lack stability. */
		assert(par.BorderDist >= 2);
		float val;
		int partialcounter = 0;
		for (int r = par.BorderDist; r < height - par.BorderDist; r++) 
			for (int c = par.BorderDist; c < width - par.BorderDist; c++) {
			
				/* Pixel value at (c,r) position. */
				val = dogs[s](c,r);	
	
				/* DOG magnitude must be above 0.8 * par.PeakThresh threshold
				(precise threshold check will be done once peak
				interpolation is performed).  Then check whether this
				point is a peak in 3x3 region at each level, and is not
				on an elongated edge.
				*/

				if (fabs(val) > 0.8 * par.PeakThresh)
				{

/*

					// If local maxima
					if (LocalMax(val, dogs[s-1], r, c,par) && LocalMax(val, dogs[s], r, c, par) && LocalMax(val, dogs[s+1], r, c,par) && NotOnEdge(dogs[s], r, c, octSize,par))
					{
						if (DEBUG) printf("Maximum Keypoint found (%d,%d,%d)  val: %f\n",s,r,c,val);
						InterpKeyPoint(
							dogs, s, r, c, grad, ori,
							map, octSize, keys, 5,par);	

					} else  if (LocalMin(val, dogs[s-1], r, c,par) && LocalMin(val, dogs[s], r, c,par) && LocalMin(val, dogs[s+1], r, c,par) && NotOnEdge(dogs[s], r, c, octSize,par))
					{
						if (DEBUG) printf("Minimum Keypoint found (%d,%d,%d)  val: %f\n",s,r,c,val);
						InterpKeyPoint(
							dogs, s, r, c, grad, ori,
							map, octSize, keys, 5,par);	
					}
*/
					if (LocalMaxMin(val, dogs[s-1], r, c) && LocalMaxMin(val, dogs[s], r, c) && LocalMaxMin(val, dogs[s+1], r, c) && NotOnEdge(dogs[s], r, c, octSize,par))
					{
						partialcounter++;
						if (DEBUG) printf("%d:  (%d,%d,%d)  val: %f\n",partialcounter, s,r,c,val);
						
						InterpKeyPoint(
							dogs, s, r, c, grad, ori,
							map, octSize, keys, 5,par);	

						//getchar();
					} 


				}

		}
	}

}
Пример #5
0
/* 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);
}