// Copyright (C) 2009 Davis E. King ([email protected]) | |
// License: Boost Software License See LICENSE.txt for the full license. | |
namespace dlib | |
{ | |
/* | |
The functions in this file implement the components of the SURF algorithm | |
for extracting scale invariant feature descriptors from images. | |
For the full story on what this algorithm does and how it works | |
you should refer to the following papers. | |
This is the original paper which introduced the algorithm: | |
SURF: Speeded Up Robust Features | |
By Herbert Bay, Tinne Tuytelaars, and Luc Van Gool | |
This paper provides a nice detailed overview of how the algorithm works: | |
Notes on the OpenSURF Library by Christopher Evans | |
*/ | |
// ---------------------------------------------------------------------------------------- | |
double gaussian ( | |
double x, | |
double y, | |
double sig | |
); | |
/*! | |
requires | |
- sig > 0 | |
ensures | |
- computes and returns the value of a 2D Gaussian function with mean 0 | |
and standard deviation sig at the given (x,y) point. | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
template <typename integral_image_type, typename T> | |
double compute_dominant_angle ( | |
const integral_image_type& img, | |
const dlib::vector<T,2>& center, | |
const double& scale | |
); | |
/*! | |
requires | |
- integral_image_type == an object such as dlib::integral_image or another | |
type that implements the interface defined in image_transforms/integral_image_abstract.h | |
- scale > 0 | |
- get_rect(img).contains(centered_rect(center, 17*scale, 17*scale)) == true | |
(i.e. center can't be within 17*scale pixels of the edge of the image) | |
ensures | |
- computes and returns the dominant angle (i.e. the angle of the dominant gradient) | |
at the given center point and scale in img. | |
- The returned angle is in radians. Specifically, if the angle is described by | |
a vector vect then the angle is exactly the value of std::atan2(vect.y(), vect.x()) | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
template <typename integral_image_type, typename T, typename MM, typename L> | |
void compute_surf_descriptor ( | |
const integral_image_type& img, | |
const dlib::vector<T,2>& center, | |
const double scale, | |
const double angle, | |
matrix<double,64,1,MM,L>& des | |
) | |
/*! | |
requires | |
- integral_image_type == an object such as dlib::integral_image or another | |
type that implements the interface defined in image_transforms/integral_image_abstract.h | |
- scale > 0 | |
- get_rect(img).contains(centered_rect(center, 32*scale, 32*scale)) == true | |
(i.e. center can't be within 32*scale pixels of the edge of the image) | |
ensures | |
- computes the 64 dimensional SURF descriptor vector of a box centered | |
at the given center point, tilted at an angle determined by the given | |
angle, and sized according to the given scale. | |
- #des == the computed SURF descriptor vector extracted from the img object. | |
- The angle is measured in radians and measures the degree of counter-clockwise | |
rotation around the center point. This is the same kind of rotation as is | |
performed by the dlib::rotate_point() function. | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
struct surf_point | |
{ | |
/*! | |
WHAT THIS OBJECT REPRESENTS | |
This object represents a detected SURF point. The meanings of | |
its fields are defined below in the get_surf_points() function. | |
!*/ | |
interest_point p; | |
matrix<double,64,1> des; | |
double angle; | |
}; | |
// ---------------------------------------------------------------------------------------- | |
void serialize ( | |
const surf_point& item, | |
std::ostream& out | |
); | |
/*! | |
provides serialization support | |
!*/ | |
void deserialize ( | |
surf_point& item, | |
std::istream& in | |
); | |
/*! | |
provides serialization support | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
template <typename image_type> | |
const std::vector<surf_point> get_surf_points ( | |
const image_type& img, | |
long max_points = 10000, | |
double detection_threshold = 30.0 | |
); | |
/*! | |
requires | |
- max_points > 0 | |
- detection_threshold >= 0 | |
- image_type == an image object that implements the interface defined in | |
dlib/image_processing/generic_image.h | |
- Let P denote the type of pixel in img, then we require: | |
- pixel_traits<P>::has_alpha == false | |
ensures | |
- This function runs the complete SURF algorithm on the given input image and | |
returns the points it found. | |
- returns a vector V such that: | |
- V.size() <= max_points | |
- for all valid i: | |
- V[i] == a SURF point found in the given input image img | |
- V[i].p == the interest_point extracted from the hessian pyramid for this | |
SURF point. | |
- V[i].des == the SURF descriptor for this point (calculated using | |
compute_surf_descriptor()) | |
- V[i].angle == the angle of the SURF box at this point (calculated using | |
compute_dominant_angle()) | |
- V[i].p.score >= detection_threshold | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
} | |