/* 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; }
/// 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); }
/// 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(); } } } } }