// Copyright (C) 2006 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_SPATIAL_FILTERINg_H_ #define DLIB_SPATIAL_FILTERINg_H_ #include "../pixel.h" #include "spatial_filtering_abstract.h" #include "../algs.h" #include "../assert.h" #include <limits> namespace dlib { // ---------------------------------------------------------------------------------------- template < typename in_image_type, typename out_image_type, typename filter_type, long M, long N > void spatially_filter_image ( const in_image_type& in_img, out_image_type& out_img, const filter_type (&filter)[M][N], unsigned long scale = 1, bool use_abs = false ) { COMPILE_TIME_ASSERT( pixel_traits<typename in_image_type::type>::has_alpha == false ); COMPILE_TIME_ASSERT( pixel_traits<typename out_image_type::type>::has_alpha == false ); COMPILE_TIME_ASSERT(M%2 == 1); COMPILE_TIME_ASSERT(N%2 == 1); DLIB_ASSERT(scale > 0, "\tvoid spatially_filter_image()" << "\n\tYou can't give a scale of zero" ); DLIB_ASSERT(is_same_object(in_img, out_img), "\tvoid spatially_filter_image()" << "\n\tYou must give two different image objects" ); // if there isn't any input image then don't do anything if (in_img.size() == 0) { out_img.clear(); return; } out_img.set_size(in_img.nr(),in_img.nc()); zero_border_pixels(out_img, M/2, N/2); // figure out the range that we should apply the filter to const long first_row = M/2; const long first_col = N/2; const long last_row = in_img.nr() - M/2; const long last_col = in_img.nc() - N/2; // apply the filter to the image for (long r = first_row; r < last_row; ++r) { for (long c = first_col; c < last_col; ++c) { typedef typename pixel_traits<typename in_image_type::type>::basic_pixel_type bp_type; typename promote<bp_type>::type p; typename promote<bp_type>::type temp = 0; for (long m = 0; m < M; ++m) { for (long n = 0; n < N; ++n) { // pull out the current pixel and put it into p p = get_pixel_intensity(in_img[r-M/2+m][c-N/2+n]); temp += p*filter[m][n]; } } temp /= scale; // Catch any underflow or apply abs as appropriate if (temp < 0) { if (use_abs) { temp = -temp; } else { temp = 0; } } // save this pixel to the output image assign_pixel(out_img[r][c], in_img[r][c]); assign_pixel_intensity(out_img[r][c], temp); } } } // ---------------------------------------------------------------------------------------- } #endif // DLIB_SPATIAL_FILTERINg_H_