// Copyright (C) 2011 Davis E. King ([email protected]) | |
// License: Boost Software License See LICENSE.txt for the full license. | |
namespace dlib | |
{ | |
template < | |
long Downsample | |
> | |
class poly_image : noncopyable | |
{ | |
/*! | |
REQUIREMENTS ON TEMPLATE PARAMETERS | |
- Downsample >= 1 | |
WHAT THIS OBJECT REPRESENTS | |
This object is a tool for extracting local feature descriptors from an image. | |
In particular, it fits polynomials to local pixel patches and allows you to | |
query the coefficients of these polynomials. Additionally, the coefficients | |
may be intensity normalized by dividing them by the constant term of the fitted | |
polynomial and then the constant term is discarded. | |
Finally, the user can specify a downsampling rate. If the template argument | |
Downsample is set to 1 then feature extraction is performed at every pixel of | |
an input image (except for a small area around the image border). However, | |
if Downsample is set to 2 then feature extraction is only performed at every | |
other pixel location. More generally, if Downsample is set to N then feature | |
extraction is performed only every N pixels. | |
THREAD SAFETY | |
Concurrent access to an instance of this object is not safe and should be protected | |
by a mutex lock except for the case where you are copying the configuration | |
(via copy_configuration()) of a poly_image object to many other threads. | |
In this case, it is safe to copy the configuration of a shared object so long | |
as no other operations are performed on it. | |
!*/ | |
public: | |
typedef matrix<double, 0, 1> descriptor_type; | |
const static long downsample = Downsample; | |
poly_image ( | |
); | |
/*! | |
ensures | |
- #get_order() == 3 | |
- #get_window_size() == 13 | |
- #size() == 0 | |
- #uses_normalization() == true | |
- #is_rotationally_invariant() == false | |
!*/ | |
poly_image( | |
long order, | |
long window_size, | |
bool normalization = true, | |
bool rotation_invariance = false | |
); | |
/*! | |
requires | |
- 1 <= order <= 6 | |
- window_size >= 3 && window_size is odd | |
ensures | |
- #get_order() == order | |
- #get_window_size() == window_size | |
- #size() == 0 | |
- #uses_normalization() == normalization | |
- #is_rotationally_invariant() == rotation_invariance | |
!*/ | |
void clear ( | |
); | |
/*! | |
ensures | |
- this object will have its initial value | |
!*/ | |
void setup ( | |
long order, | |
long window_size | |
); | |
/*! | |
requires | |
- 1 <= order <= 6 | |
- window_size >= 3 && window_size is odd | |
ensures | |
- #get_order() == order | |
- #get_window_size() == window_size | |
!*/ | |
long get_order ( | |
) const; | |
/*! | |
ensures | |
- returns the order of the polynomial that will be fitted to | |
each local pixel patch during feature extraction. | |
!*/ | |
long get_window_size ( | |
) const; | |
/*! | |
ensures | |
- returns the size of the window used for local feature extraction. | |
This is the width and height of the window in pixels. | |
!*/ | |
bool uses_normalization ( | |
) const; | |
/*! | |
ensures | |
- returns true if the polynomial coefficients are intensity normalized | |
and false otherwise. | |
!*/ | |
void set_uses_normalization ( | |
bool normalization | |
); | |
/*! | |
ensures | |
- #uses_normalization() == normalization | |
!*/ | |
bool is_rotationally_invariant ( | |
); | |
/*! | |
ensures | |
- returns true if the feature extractor will adjust the output so that it | |
is rotationally invariant. This is done by rotating each patch such that | |
the gradient vector always points in the same direction. | |
!*/ | |
void set_is_rotationally_invariant ( | |
bool rotation_invariance | |
); | |
/*! | |
ensures | |
- #is_rotationally_invariant() == rotation_invariance | |
!*/ | |
void copy_configuration ( | |
const poly_image& item | |
); | |
/*! | |
ensures | |
- copies all the state information of item into *this, except for state | |
information populated by load(). More precisely, given two poly_image | |
objects H1 and H2, the following sequence of instructions should always | |
result in both of them having the exact same state. | |
H2.copy_configuration(H1); | |
H1.load(img); | |
H2.load(img); | |
!*/ | |
template < | |
typename image_type | |
> | |
inline void load ( | |
const image_type& img | |
); | |
/*! | |
requires | |
- image_type == an image object that implements the interface defined in | |
dlib/image_processing/generic_image.h | |
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false | |
ensures | |
- Performs the feature extraction described in the WHAT THIS OBJECT REPRESENTS | |
section above. This means after load() finishes you can call (*this)(row,col) | |
to obtain the polynomial coefficients for an order get_order() polynomial which | |
was fitted to the image patch get_block_rect(row,col). | |
- #size() > 0 | |
!*/ | |
void unload( | |
); | |
/*! | |
ensures | |
- #nr() == 0 | |
- #nc() == 0 | |
- clears only the state information which is populated by load(). For | |
example, let H be a poly_image object. Then consider the two sequences | |
of instructions: | |
Sequence 1: | |
H.load(img); | |
H.unload(); | |
H.load(img); | |
Sequence 2: | |
H.load(img); | |
Both sequence 1 and sequence 2 should have the same effect on H. | |
!*/ | |
inline size_t size ( | |
) const; | |
/*! | |
ensures | |
- returns nr()*nc() | |
!*/ | |
inline long nr ( | |
) const; | |
/*! | |
ensures | |
- returns the number of rows in this polynomial feature image | |
!*/ | |
inline long nc ( | |
) const; | |
/*! | |
ensures | |
- returns the number of columns in this polynomial feature image | |
!*/ | |
long get_num_dimensions ( | |
) const; | |
/*! | |
ensures | |
- returns the number of dimensions in the feature vectors generated by | |
this object. | |
- In this case, this will be the number of coefficients in an order | |
get_order() polynomial, except for the constant term of the polynomial | |
if uses_normalization() == true. | |
!*/ | |
inline const descriptor_type& operator() ( | |
long row, | |
long col | |
) const; | |
/*! | |
requires | |
- 0 <= row < nr() | |
- 0 <= col < nc() | |
ensures | |
- returns the descriptor for the polynomial filtering block at the given row and column. | |
This vector will contain the polynomial coefficients for a polynomial fitted to the | |
image patch located at get_block_rect(row,col) in the original image given to load(). | |
- The returned descriptor vector will have get_num_dimensions() elements. | |
!*/ | |
const rectangle get_block_rect ( | |
long row, | |
long col | |
) const; | |
/*! | |
ensures | |
- returns a rectangle that tells you what part of the original image is associated | |
with a particular polynomial filter block. That is, what part of the input image | |
is associated with (*this)(row,col). | |
- The returned rectangle will be get_window_size() pixels wide and tall. | |
!*/ | |
const point image_to_feat_space ( | |
const point& p | |
) const; | |
/*! | |
ensures | |
- Each local feature is extracted from a certain point in the input image. | |
This function returns the identity of the local feature corresponding | |
to the image location p. Or in other words, let P == image_to_feat_space(p), | |
then (*this)(P.y(),P.x()) == the local feature closest to, or centered at, | |
the point p in the input image. Note that some image points might not have | |
corresponding feature locations. E.g. border points or points outside the | |
image. In these cases the returned point will be outside get_rect(*this). | |
!*/ | |
const rectangle image_to_feat_space ( | |
const rectangle& rect | |
) const; | |
/*! | |
ensures | |
- returns rectangle(image_to_feat_space(rect.tl_corner()), image_to_feat_space(rect.br_corner())); | |
(i.e. maps a rectangle from image space to feature space) | |
!*/ | |
const point feat_to_image_space ( | |
const point& p | |
) const; | |
/*! | |
ensures | |
- returns the location in the input image space corresponding to the center | |
of the local feature at point p. In other words, this function computes | |
the inverse of image_to_feat_space(). Note that it may only do so approximately, | |
since more than one image location might correspond to the same local feature. | |
That is, image_to_feat_space() might not be invertible so this function gives | |
the closest possible result. | |
!*/ | |
const rectangle feat_to_image_space ( | |
const rectangle& rect | |
) const; | |
/*! | |
ensures | |
- return rectangle(feat_to_image_space(rect.tl_corner()), feat_to_image_space(rect.br_corner())); | |
(i.e. maps a rectangle from feature space to image space) | |
!*/ | |
}; | |
// ---------------------------------------------------------------------------------------- | |
template < | |
long downsample | |
> | |
void serialize ( | |
const poly_image<downsample>& item, | |
std::ostream& out | |
); | |
/*! | |
provides serialization support | |
!*/ | |
template < | |
long downsample | |
> | |
void deserialize ( | |
poly_image<downsample>& item, | |
std::istream& in | |
); | |
/*! | |
provides deserialization support | |
!*/ | |
// ---------------------------------------------------------------------------------------- | |
} | |