sustaining_gazes/lib/3rdParty/dlib/include/dlib/image_transforms/spatial_filtering_abstract.h

486 lines
22 KiB
C++

// Copyright (C) 2006 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_SPATIAL_FILTERINg_ABSTRACT_
#ifdef DLIB_SPATIAL_FILTERINg_ABSTRACT_
#include "../pixel.h"
#include "../matrix.h"
#include "../image_processing/generic_image.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type,
typename EXP,
typename T
>
rectangle spatially_filter_image (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP>& filter,
T scale = 1,
bool use_abs = false,
bool add_to = false
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- out_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- in_img and out_img do not contain pixels with an alpha channel. That is,
pixel_traits::has_alpha is false for the pixels in these objects.
- is_same_object(in_img, out_img) == false
- T must be some scalar type
- filter.size() != 0
- scale != 0
- if (in_img doesn't contain grayscale pixels) then
- use_abs == false && add_to == false
(i.e. You can only use the use_abs and add_to options with grayscale images)
ensures
- Applies the given spatial filter to in_img and stores the result in out_img (i.e.
cross-correlates in_img with filter). Also divides each resulting pixel by scale.
- The intermediate filter computations will be carried out using variables of type EXP::type.
This is whatever scalar type is used inside the filter matrix.
- Pixel values are stored into out_img using the assign_pixel() function and therefore
any applicable color space conversion or value saturation is performed. Note that if
add_to is true then the filtered output value will be added to out_img rather than
overwriting the original value.
- if (in_img doesn't contain grayscale pixels) then
- The filter is applied to each color channel independently.
- if (use_abs == true) then
- pixel values after filtering that are < 0 are converted to their absolute values.
- The filter is applied such that it's centered over the pixel it writes its
output into. For centering purposes, we consider the center element of the
filter to be filter(filter.nr()/2,filter.nc()/2). This means that the filter
that writes its output to a pixel at location point(c,r) and is W by H (width
by height) pixels in size operates on exactly the pixels in the rectangle
centered_rect(point(c,r),W,H) within in_img.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are always set to zero.
- #out_img.nc() == in_img.nc()
- #out_img.nr() == in_img.nr()
- returns a rectangle which indicates what pixels in #out_img are considered
non-border pixels and therefore contain output from the filter.
- if (use_abs == false && all images and filers contain float types) then
- This function will use SIMD instructions and is particularly fast. So if
you can use this form of the function it can give a decent speed boost.
!*/
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2,
typename T
>
rectangle spatially_filter_image_separable (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter,
T scale = 1,
bool use_abs = false,
bool add_to = false
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- out_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- in_img and out_img do not contain pixels with an alpha channel. That is,
pixel_traits::has_alpha is false for the pixels in these objects.
- is_same_object(in_img, out_img) == false
- T must be some scalar type
- scale != 0
- row_filter.size() != 0
- col_filter.size() != 0
- is_vector(row_filter) == true
- is_vector(col_filter) == true
- if (in_img doesn't contain grayscale pixels) then
- use_abs == false && add_to == false
(i.e. You can only use the use_abs and add_to options with grayscale images)
ensures
- Applies the given separable spatial filter to in_img and stores the result in out_img.
Also divides each resulting pixel by scale. Calling this function has the same
effect as calling the regular spatially_filter_image() routine with a filter,
FILT, defined as follows:
- FILT(r,c) == col_filter(r)*row_filter(c)
- The intermediate filter computations will be carried out using variables of type EXP1::type.
This is whatever scalar type is used inside the row_filter matrix.
- Pixel values are stored into out_img using the assign_pixel() function and therefore
any applicable color space conversion or value saturation is performed. Note that if
add_to is true then the filtered output value will be added to out_img rather than
overwriting the original value.
- if (in_img doesn't contain grayscale pixels) then
- The filter is applied to each color channel independently.
- if (use_abs == true) then
- pixel values after filtering that are < 0 are converted to their absolute values
- The filter is applied such that it's centered over the pixel it writes its
output into. For centering purposes, we consider the center element of the
filter to be FILT(col_filter.size()/2,row_filter.size()/2). This means that
the filter that writes its output to a pixel at location point(c,r) and is W
by H (width by height) pixels in size operates on exactly the pixels in the
rectangle centered_rect(point(c,r),W,H) within in_img.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are always set to zero.
- #out_img.nc() == in_img.nc()
- #out_img.nr() == in_img.nr()
- returns a rectangle which indicates what pixels in #out_img are considered
non-border pixels and therefore contain output from the filter.
- if (use_abs == false && all images and filers contain float types) then
- This function will use SIMD instructions and is particularly fast. So if
you can use this form of the function it can give a decent speed boost.
!*/
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2
>
rectangle float_spatially_filter_image_separable (
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter,
out_image_type& scratch,
bool add_to = false
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- out_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- in_img, out_img, row_filter, and col_filter must all contain float type elements.
- is_same_object(in_img, out_img) == false
- row_filter.size() != 0
- col_filter.size() != 0
- is_vector(row_filter) == true
- is_vector(col_filter) == true
ensures
- This function is identical to the above spatially_filter_image_separable()
function except that it can only be invoked on float images with float
filters. In fact, spatially_filter_image_separable() invokes
float_spatially_filter_image_separable() in those cases. So why is
float_spatially_filter_image_separable() in the public API? The reason is
because the separable filtering routines internally allocate an image each
time they are called. If you want to avoid this memory allocation then you
can call float_spatially_filter_image_separable() and provide the scratch
image as input. This allows you to reuse the same scratch image for many
calls to float_spatially_filter_image_separable() and thereby avoid having it
allocated and freed for each call.
!*/
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type,
typename EXP1,
typename EXP2,
typename T
>
rectangle spatially_filter_image_separable_down (
const unsigned long downsample,
const in_image_type& in_img,
out_image_type& out_img,
const matrix_exp<EXP1>& row_filter,
const matrix_exp<EXP2>& col_filter,
T scale = 1,
bool use_abs = false,
bool add_to = false
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- out_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- in_img and out_img do not contain pixels with an alpha channel. That is,
pixel_traits::has_alpha is false for the pixels in these objects.
- out_img contains grayscale pixels.
- is_same_object(in_img, out_img) == false
- T must be some scalar type
- scale != 0
- is_vector(row_filter) == true
- is_vector(col_filter) == true
- row_filter.size() % 2 == 1 (i.e. must be odd)
- col_filter.size() % 2 == 1 (i.e. must be odd)
- downsample > 0
ensures
- This function is equivalent to calling
spatially_filter_image_separable(in_img,out_img,row_filter,col_filter,scale,use_abs,add_to)
and then downsampling the output image by a factor of downsample. Therefore,
we will have that:
- #out_img.nr() == ceil((double)in_img.nr()/downsample)
- #out_img.nc() == ceil((double)in_img.nc()/downsample)
- #out_img[r][c] == filtered pixel corresponding to in_img[r*downsample][c*downsample]
- returns a rectangle which indicates what pixels in #out_img are considered
non-border pixels and therefore contain output from the filter.
- Note that the first row and column of non-zero padded data are the following
- first_row == ceil(floor(col_filter.size()/2.0)/downsample)
- first_col == ceil(floor(row_filter.size()/2.0)/downsample)
!*/
// ----------------------------------------------------------------------------------------
template <
long NR,
long NC,
typename T,
typename U,
typename in_image_type
>
inline void separable_3x3_filter_block_grayscale (
T (&block)[NR][NC],
const in_image_type& img,
const long& r,
const long& c,
const U& fe1,
const U& fm,
const U& fe2
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- T and U should be scalar types
- shrink_rect(get_rect(img),1).contains(c,r)
- shrink_rect(get_rect(img),1).contains(c+NC-1,r+NR-1)
ensures
- Filters the image in the sub-window of img defined by a rectangle
with its upper left corner at (c,r) and lower right at (c+NC-1,r+NR-1).
- The output of the filter is stored in #block. Note that img will be
interpreted as a grayscale image.
- The filter used is defined by the separable filter [fe1 fm fe2]. So the
spatial filter is thus:
fe1*fe1 fe1*fm fe2*fe1
fe1*fm fm*fm fe2*fm
fe1*fe2 fe2*fm fe2*fe2
!*/
// ----------------------------------------------------------------------------------------
template <
long NR,
long NC,
typename T,
typename U,
typename in_image_type
>
inline void separable_3x3_filter_block_rgb (
T (&block)[NR][NC],
const in_image_type& img,
const long& r,
const long& c,
const U& fe1,
const U& fm,
const U& fe2
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- img must contain RGB pixels, that is pixel_traits::rgb == true for the pixels
in img.
- T should be a struct with .red .green and .blue members.
- U should be a scalar type
- shrink_rect(get_rect(img),1).contains(c,r)
- shrink_rect(get_rect(img),1).contains(c+NC-1,r+NR-1)
ensures
- Filters the image in the sub-window of img defined by a rectangle
with its upper left corner at (c,r) and lower right at (c+NC-1,r+NR-1).
- The output of the filter is stored in #block. Note that the filter is applied
to each color component independently.
- The filter used is defined by the separable filter [fe1 fm fe2]. So the
spatial filter is thus:
fe1*fe1 fe1*fm fe2*fe1
fe1*fm fm*fm fe2*fm
fe1*fe2 fe2*fm fe2*fe2
!*/
// ----------------------------------------------------------------------------------------
inline double gaussian (
double x,
double sigma
);
/*!
requires
- sigma > 0
ensures
- computes and returns the value of a 1D Gaussian function with mean 0
and standard deviation sigma at the given x value.
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
matrix<T,0,1> create_gaussian_filter (
double sigma,
int size
);
/*!
requires
- sigma > 0
- size > 0
- size is an odd number
ensures
- returns a separable Gaussian filter F such that:
- is_vector(F) == true
- F.size() == size
- F is suitable for use with the spatially_filter_image_separable() routine
and its use with this function corresponds to running a Gaussian filter
of sigma width over an image.
!*/
// ----------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type
>
void gaussian_blur (
const in_image_type& in_img,
out_image_type& out_img,
double sigma = 1,
int max_size = 1001
);
/*!
requires
- in_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- out_image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- in_img and out_img do not contain pixels with an alpha channel. That is,
pixel_traits::has_alpha is false for the pixels in these objects.
- is_same_object(in_img, out_img) == false
- sigma > 0
- max_size > 0
- max_size is an odd number
ensures
- Filters in_img with a Gaussian filter of sigma width. The actual spatial filter will
be applied to pixel blocks that are at most max_size wide and max_size tall (note that
this function will automatically select a smaller block size as appropriate). The
results are stored into #out_img.
- Pixel values are stored into out_img using the assign_pixel() function and therefore
any applicable color space conversion or value saturation is performed.
- if (in_img doesn't contain grayscale pixels) then
- The filter is applied to each color channel independently.
- Pixels close enough to the edge of in_img to not have the filter still fit
inside the image are set to zero.
- #out_img.nc() == in_img.nc()
- #out_img.nr() == in_img.nr()
!*/
// ----------------------------------------------------------------------------------------
template <
typename image_type1,
typename image_type2
>
void sum_filter (
const image_type1& img,
image_type2& out,
const rectangle& rect
);
/*!
requires
- out.nr() == img.nr()
- out.nc() == img.nc()
- image_type1 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- image_type2 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- is_same_object(img,out) == false
ensures
- for all valid r and c:
- let SUM(r,c) == sum of pixels from img which are inside the rectangle
translate_rect(rect, point(c,r)).
- #out[r][c] == out[r][c] + SUM(r,c)
!*/
// ----------------------------------------------------------------------------------------
template <
typename image_type1,
typename image_type2
>
void sum_filter_assign (
const image_type1& img,
image_type2& out,
const rectangle& rect
);
/*!
requires
- image_type1 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- image_type2 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- is_same_object(img,out) == false
ensures
- #out.nr() == img.nr()
- #out.nc() == img.nc()
- for all valid r and c:
- let SUM(r,c) == sum of pixels from img which are inside the rectangle
translate_rect(rect, point(c,r)).
- #out[r][c] == SUM(r,c)
!*/
// ----------------------------------------------------------------------------------------
template <
typename image_type1,
typename image_type2
>
void max_filter (
image_type1& img,
image_type2& out,
const long width,
const long height,
const typename image_traits<image_type1>::pixel_type& thresh
);
/*!
requires
- out.nr() == img.nr()
- out.nc() == img.nc()
- image_type1 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- image_type2 == an image object that implements the interface defined in
dlib/image_processing/generic_image.h and it must contain grayscale pixels.
- is_same_object(img,out) == false
- width > 0 && height > 0
ensures
- for all valid r and c:
- let MAX(r,c) == maximum of pixels from img which are inside the rectangle
centered_rect(point(c,r), width, height)
- if (MAX(r,c) >= thresh)
- #out[r][c] == out[r][c] + MAX(r,c)
- else
- #out[r][c] == out[r][c] + thresh
- Does not change the size of img.
- Uses img as scratch space. Therefore, the pixel values in img will have
been modified by this function. That is, max_filter() destroys the contents
of img.
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SPATIAL_FILTERINg_ABSTRACT_