Example #1
0
/* Alternate approach to return an orientation for a keypoint, as
   described in the PhD thesis of Krystian Mikolajczyk.  This is done
   by creating a Gaussian weighted average of the gradient directions
   in the region.  The result is in the range of -PII to PII.  This was
   found not to work as well, but is included so that comparisons can
   continue to be done.
*/
KKeypoint AssignOriAvg(Image grad, Image ori, float octSize, float octScale,
		      float octRow, float octCol, KKeypoint keys)
{
   int r, c, irow, icol, rows, cols, radius;
   float gval, sigma, distsq, weight, angle, xvec = 0.0, yvec = 0.0;
   
   rows = grad->rows;
   cols = grad->cols;
   irow = (int) (octRow+0.5);
   icol = (int) (octCol+0.5);
   
   /* Look at pixels within 3 sigma around the point and put their
      Gaussian weighted vector values in (xvec, yvec).
   */
   sigma = OriSigma * octScale;
   radius = (int) (3.0 * sigma);
   for (r = irow - radius; r <= irow + radius; r++)
      for (c = icol - radius; c <= icol + radius; c++)
         if (r >= 0 && c >= 0 && r < rows && c < cols) {
            gval = grad->pixels[r][c];
            distsq = (r - octRow) * (r - octRow) + (c - octCol) * (c - octCol);
            if (distsq <= radius * radius) {
               weight = exp(- distsq / (2.0 * sigma * sigma));
               /* Angle is in range of -PII to PII. */
               angle = ori->pixels[r][c];
	       xvec += gval * cos(angle);
	       yvec += gval * sin(angle);
            }
         }
   /* atan2 returns angle in range [-PII,PII]. */
   angle = atan2(yvec, xvec);  
   return MakeKeypoint(grad, ori, octSize, octScale, octRow, octCol,
		       angle, keys);
}
Example #2
0
/* Assign an orientation to this keypoint.  This is done by creating a
   Gaussian weighted histogram of the gradient directions in the
   region.  The histogram is smoothed and the largest peak selected.
   The results are in the range of -PI to PI.
*/
void AssignOriHist(
	const flimage& grad, float octSize,
	float octScale, float octRow, float octCol,keypointslist& keys,siftPar &par)
{
	int	bin, prev, next;
	float* hist = new float[par.OriBins];
	float	distsq, dif, weight, angle, interp;
	float radius2, sigma2;		

	int	row = (int) (octRow+0.5),
		col = (int) (octCol+0.5),
		rows = grad.h,
		cols = grad.w;

	for (int i = 0; i < par.OriBins; i++) hist[i] = 0.0;

	/* Look at pixels within 3 sigma around the point and sum their
	  Gaussian weighted gradient magnitudes into the histogram. */
	float	sigma = par.OriSigma * octScale;
	int	radius = (int) (sigma * 3.0);
	int rmin = std::max(0,row-radius);
	int cmin = std::max(0,col-radius);
	int rmax = std::min(row+radius,rows-2);
	int cmax = std::min(col+radius,cols-2);
	radius2 = (float)(radius * radius);
	sigma2 = 2.0f*sigma*sigma;

	for (int r = rmin; r <= rmax; r++) {
		for (int c = cmin; c <= cmax; c++) {
            dif = (r - octRow);	distsq = dif*dif;
            dif = (c - octCol);	distsq += dif*dif;
			const float* g=grad.pixel(c,r);

            if (g[0] > 0.0  &&  distsq < radius2 + 0.5) {
                weight = exp(- distsq / sigma2);
					
                /* Ori is in range of -PI to PI. */
                bin = (int) (par.OriBins * (g[1] + M_PI + 0.001) / (2.0 * M_PI));
                assert(bin >= 0 && bin <= par.OriBins);
                bin = std::min(bin, par.OriBins - 1);
                hist[bin] += weight * g[0];
            }
		}
	}


	/* Apply smoothing 6 times for accurate Gaussian approximation. */
	for (int i = 0; i < 6; i++)
		SmoothHistogram(hist, par.OriBins);

	/* Find maximum value in histogram. */
	float maxval = 0.0;
	for (int i = 0; i < par.OriBins; i++) 
		if (hist[i] > maxval) maxval = hist[i];

	/* Look for each local peak in histogram.  If value is within
	  par.OriHistThresh of maximum value, then generate a keypoint. */
	for (int i = 0; i < par.OriBins; i++) {
		prev = (i == 0 ? par.OriBins - 1 : i - 1);
		next = (i == par.OriBins - 1 ? 0 : i + 1);

		if (	hist[i] > hist[prev]  &&  hist[i] > hist[next]  &&
			hist[i] >= par.OriHistThresh * maxval ) {
	
			/* Use parabolic fit to interpolate peak location from 3 samples.
			  Set angle in range -PI to PI. */
			interp = InterpPeak(hist[prev], hist[i], hist[next]);
			angle = 2.0f * M_PI * (i + 0.5f + interp) / (float)par.OriBins - M_PI;
			assert(angle >= -M_PI  &&  angle <= M_PI);
		
			if (DEBUG) printf("angle selected: %f \t location: (%f,%f)\n", angle, octRow, octCol);

			/* Create a keypoint with this orientation. */
			MakeKeypoint(
				grad, octSize, octScale,
				octRow, octCol, angle, keys,par);
		}

	}
	delete [] hist;
}
Example #3
0
/* Assign an orientation to this keypoint.  This is done by creating a
     Gaussian weighted histogram of the gradient directions in the
     region.  The histogram is smoothed and the largest peak selected.
     The results are in the range of -PII to PII.
*/
KKeypoint AssignOriHist(Image grad, Image ori, float octSize, float octScale,
		       float octRow, float octCol, KKeypoint keys)
{
   int i, r, c, row, col, rows, cols, radius, bin, prev, next;
   float hist[OriBins], distsq, gval, weight, angle, sigma, interp,
         maxval = 0.0;
   
   row = (int) (octRow+0.5);
   col = (int) (octCol+0.5);
   rows = grad->rows;
   cols = grad->cols;
   
   for (i = 0; i < OriBins; i++)
      hist[i] = 0.0;
   
   /* Look at pixels within 3 sigma around the point and sum their
      Gaussian weighted gradient magnitudes into the histogram.
   */
   sigma = OriSigma * octScale;
   radius = (int) (sigma * 3.0);
   for (r = row - radius; r <= row + radius; r++)
      for (c = col - radius; c <= col + radius; c++)

         /* Do not use last row or column, which are not valid. */
         if (r >= 0 && c >= 0 && r < rows - 2 && c < cols - 2) {
            gval = grad->pixels[r][c];
            distsq = (r - octRow) * (r - octRow) + (c - octCol) * (c - octCol);

            if (gval > 0.0  &&  distsq < radius * radius + 0.5) {
               weight = exp(- distsq / (2.0 * sigma * sigma));
               /* Ori is in range of -PII to PII. */
               angle = ori->pixels[r][c];
               bin = (int) (OriBins * (angle + PII + 0.001) / (2.0 * PII));
               assert(bin >= 0 && bin <= OriBins);
               bin = MIN_(bin, OriBins - 1);
               hist[bin] += weight * gval;
            }
         }
   /* Apply circular smoothing 6 times for accurate Gaussian approximation. */
   for (i = 0; i < 6; i++)
     SmoothHistogram(hist, OriBins);

   /* Find maximum value in histogram. */
   for (i = 0; i < OriBins; i++)
      if (hist[i] > maxval)
         maxval = hist[i];

   /* Look for each local peak in histogram.  If value is within
      OriHistThresh of maximum value, then generate a keypoint.
   */
   for (i = 0; i < OriBins; i++) {
     prev = (i == 0 ? OriBins - 1 : i - 1);
     next = (i == OriBins - 1 ? 0 : i + 1);
     if (hist[i] > hist[prev]  &&  hist[i] > hist[next]  &&
	 hist[i] >= OriHistThresh * maxval) {
       
       /* Use parabolic fit to interpolate peak location from 3 samples.
	  Set angle in range -PII to PII.
       */
       interp = InterpPeak(hist[prev], hist[i], hist[next]);
       angle = 2.0 * PII * (i + 0.5 + interp) / OriBins - PII;
       assert(angle >= -PII  &&  angle <= PII);
       
       /* Create a keypoint with this orientation. */
       keys = MakeKeypoint(grad, ori, octSize, octScale, octRow, octCol,
			   angle, keys);
     }
   }
   return keys;
}