191 lines
5.9 KiB
C++
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
|
|
|