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

191 lines
5.9 KiB
C++

// Copyright (C) 2009 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_INTEGRAL_IMAGE
#define DLIB_INTEGRAL_IMAGE
#include "integral_image_abstract.h"
#include "../algs.h"
#include "../assert.h"
#include "../geometry.h"
#include "../array2d.h"
#include "../matrix.h"
#include "../pixel.h"
#include "../noncopyable.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename T
>
class integral_image_generic : noncopyable
{
public:
typedef T value_type;
long nr() const { return int_img.nr(); }
long nc() const { return int_img.nc(); }
template <typename image_type>
void load (
const image_type& img_
)
{
const_image_view<image_type> img(img_);
T pixel;
int_img.set_size(img.nr(), img.nc());
// compute the first row of the integral image
T temp = 0;
for (long c = 0; c < img.nc(); ++c)
{
assign_pixel(pixel, img[0][c]);
temp += pixel;
int_img[0][c] = temp;
}
// now compute the rest of the integral image
for (long r = 1; r < img.nr(); ++r)
{
temp = 0;
for (long c = 0; c < img.nc(); ++c)
{
assign_pixel(pixel, img[r][c]);
temp += pixel;
int_img[r][c] = temp + int_img[r-1][c];
}
}
}
value_type get_sum_of_area (
const rectangle& rect
) const
{
DLIB_ASSERT(get_rect(*this).contains(rect) == true && rect.is_empty() == false,
"\tvalue_type get_sum_of_area(rect)"
<< "\n\tYou have given a rectangle that goes outside the image"
<< "\n\tthis: " << this
<< "\n\trect.is_empty(): " << rect.is_empty()
<< "\n\trect: " << rect
<< "\n\tget_rect(*this): " << get_rect(*this)
);
T top_left = 0, top_right = 0, bottom_left = 0, bottom_right = 0;
bottom_right = int_img[rect.bottom()][rect.right()];
if (rect.left()-1 >= 0 && rect.top()-1 >= 0)
{
top_left = int_img[rect.top()-1][rect.left()-1];
bottom_left = int_img[rect.bottom()][rect.left()-1];
top_right = int_img[rect.top()-1][rect.right()];
}
else if (rect.left()-1 >= 0)
{
bottom_left = int_img[rect.bottom()][rect.left()-1];
}
else if (rect.top()-1 >= 0)
{
top_right = int_img[rect.top()-1][rect.right()];
}
return bottom_right - bottom_left - top_right + top_left;
}
void swap(integral_image_generic& item)
{
int_img.swap(item.int_img);
}
private:
array2d<T> int_img;
};
template <
typename T
>
void swap (
integral_image_generic<T>& a,
integral_image_generic<T>& b
) { a.swap(b); }
// ----------------------------------------------------------------------------------------
typedef integral_image_generic<long> integral_image;
// ----------------------------------------------------------------------------------------
template <typename integral_image_type>
typename integral_image_type::value_type haar_x (
const integral_image_type& img,
const point& p,
long width
)
{
DLIB_ASSERT(get_rect(img).contains(centered_rect(p,width,width)) == true,
"\tlong haar_x(img,p,width)"
<< "\n\tYou have given a point and with that goes outside the image"
<< "\n\tget_rect(img): " << get_rect(img)
<< "\n\tp: " << p
<< "\n\twidth: " << width
);
rectangle left_rect;
left_rect.set_left ( p.x() - width / 2 );
left_rect.set_top ( p.y() - width / 2 );
left_rect.set_right ( p.x()-1 );
left_rect.set_bottom ( left_rect.top() + width - 1 );
rectangle right_rect;
right_rect.set_left ( p.x() );
right_rect.set_top ( left_rect.top() );
right_rect.set_right ( left_rect.left() + width -1 );
right_rect.set_bottom ( left_rect.bottom() );
return img.get_sum_of_area(right_rect) - img.get_sum_of_area(left_rect);
}
// ----------------------------------------------------------------------------
template <typename integral_image_type>
typename integral_image_type::value_type haar_y (
const integral_image_type& img,
const point& p,
long width
)
{
DLIB_ASSERT(get_rect(img).contains(centered_rect(p,width,width)) == true,
"\tlong haar_y(img,p,width)"
<< "\n\tYou have given a point and with that goes outside the image"
<< "\n\tget_rect(img): " << get_rect(img)
<< "\n\tp: " << p
<< "\n\twidth: " << width
);
rectangle top_rect;
top_rect.set_left ( p.x() - width / 2 );
top_rect.set_top ( p.y() - width / 2 );
top_rect.set_right ( top_rect.left() + width - 1 );
top_rect.set_bottom ( p.y()-1 );
rectangle bottom_rect;
bottom_rect.set_left ( top_rect.left() );
bottom_rect.set_top ( p.y() );
bottom_rect.set_right ( top_rect.right() );
bottom_rect.set_bottom ( top_rect.top() + width - 1 );
return img.get_sum_of_area(bottom_rect) - img.get_sum_of_area(top_rect);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_INTEGRAL_IMAGE