// Copyright (C) 2009 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_SURf_ABSTRACT_H_ #ifdef DLIB_SURf_ABSTRACT_H_ #include "hessian_pyramid_abstract.h" #include "../geometry/vector_abstract.h" #include "../matrix/matrix_abstract.h" #include "../image_processing/generic_image.h" 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 !*/ // ---------------------------------------------------------------------------------------- } #endif // DLIB_SURf_ABSTRACT_H_