diff options
Diffstat (limited to 'ml/dlib/dlib/image_transforms/integral_image.h')
-rw-r--r-- | ml/dlib/dlib/image_transforms/integral_image.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/ml/dlib/dlib/image_transforms/integral_image.h b/ml/dlib/dlib/image_transforms/integral_image.h new file mode 100644 index 000000000..2ae47d921 --- /dev/null +++ b/ml/dlib/dlib/image_transforms/integral_image.h @@ -0,0 +1,190 @@ +// 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 + |