// Copyright (C) 2007 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_ASSIGN_IMAGe_ #define DLIB_ASSIGN_IMAGe_ #include "../pixel.h" #include "assign_image_abstract.h" #include "../statistics.h" namespace dlib { // ---------------------------------------------------------------------------------------- template < typename dest_image_type, typename src_image_type > void impl_assign_image ( image_view<dest_image_type>& dest, const src_image_type& src ) { dest.set_size(src.nr(),src.nc()); for (long r = 0; r < src.nr(); ++r) { for (long c = 0; c < src.nc(); ++c) { assign_pixel(dest[r][c], src(r,c)); } } } template < typename dest_image_type, typename src_image_type > void impl_assign_image ( dest_image_type& dest_, const src_image_type& src ) { image_view<dest_image_type> dest(dest_); impl_assign_image(dest, src); } template < typename dest_image_type, typename src_image_type > void assign_image ( dest_image_type& dest, const src_image_type& src ) { // check for the case where dest is the same object as src if (is_same_object(dest,src)) return; impl_assign_image(dest, mat(src)); } // ---------------------------------------------------------------------------------------- template < typename dest_image_type, typename src_image_type > void impl_assign_image_scaled ( image_view<dest_image_type>& dest, const src_image_type& src, const double thresh ) { DLIB_ASSERT( thresh > 0, "\tvoid assign_image_scaled()" << "\n\t You have given an threshold value" << "\n\t thresh: " << thresh ); typedef typename image_traits<dest_image_type>::pixel_type dest_pixel; // If the destination has a dynamic range big enough to contain the source image data then just do a // regular assign_image() if (pixel_traits<dest_pixel>::max() >= pixel_traits<typename src_image_type::type>::max() && pixel_traits<dest_pixel>::min() <= pixel_traits<typename src_image_type::type>::min() ) { impl_assign_image(dest, src); return; } dest.set_size(src.nr(),src.nc()); if (src.size() == 0) return; if (src.size() == 1) { impl_assign_image(dest, src); return; } // gather image statistics running_stats<double> rs; for (long r = 0; r < src.nr(); ++r) { for (long c = 0; c < src.nc(); ++c) { rs.add(get_pixel_intensity(src(r,c))); } } typedef typename pixel_traits<typename src_image_type::type>::basic_pixel_type spix_type; if (std::numeric_limits<spix_type>::is_integer) { // If the destination has a dynamic range big enough to contain the source image data then just do a // regular assign_image() if (pixel_traits<dest_pixel>::max() >= rs.max() && pixel_traits<dest_pixel>::min() <= rs.min() ) { impl_assign_image(dest, src); return; } } // Figure out the range of pixel values based on image statistics. There might be some huge // outliers so don't just pick the min and max values. const double upper = std::min(rs.mean() + thresh*rs.stddev(), rs.max()); const double lower = std::max(rs.mean() - thresh*rs.stddev(), rs.min()); const double dest_min = pixel_traits<dest_pixel>::min(); const double dest_max = pixel_traits<dest_pixel>::max(); const double scale = (upper!=lower)? ((dest_max - dest_min) / (upper - lower)) : 0; for (long r = 0; r < src.nr(); ++r) { for (long c = 0; c < src.nc(); ++c) { const double val = get_pixel_intensity(src(r,c)) - lower; assign_pixel(dest[r][c], scale*val + dest_min); } } } template < typename dest_image_type, typename src_image_type > void impl_assign_image_scaled ( dest_image_type& dest_, const src_image_type& src, const double thresh ) { image_view<dest_image_type> dest(dest_); impl_assign_image_scaled(dest, src, thresh); } template < typename dest_image_type, typename src_image_type > void assign_image_scaled ( dest_image_type& dest, const src_image_type& src, const double thresh = 4 ) { // check for the case where dest is the same object as src if (is_same_object(dest,src)) return; impl_assign_image_scaled(dest, mat(src),thresh); } // ---------------------------------------------------------------------------------------- template < typename dest_image_type, typename src_pixel_type > void assign_all_pixels ( image_view<dest_image_type>& dest_img, const src_pixel_type& src_pixel ) { for (long r = 0; r < dest_img.nr(); ++r) { for (long c = 0; c < dest_img.nc(); ++c) { assign_pixel(dest_img[r][c], src_pixel); } } } // ---------------------------------------------------------------------------------------- template < typename dest_image_type, typename src_pixel_type > void assign_all_pixels ( dest_image_type& dest_img_, const src_pixel_type& src_pixel ) { image_view<dest_image_type> dest_img(dest_img_); assign_all_pixels(dest_img, src_pixel); } // ---------------------------------------------------------------------------------------- template < typename image_type > void assign_border_pixels ( image_view<image_type>& img, long x_border_size, long y_border_size, const typename image_traits<image_type>::pixel_type& p ) { DLIB_ASSERT( x_border_size >= 0 && y_border_size >= 0, "\tvoid assign_border_pixels(img, p, border_size)" << "\n\tYou have given an invalid border_size" << "\n\tx_border_size: " << x_border_size << "\n\ty_border_size: " << y_border_size ); y_border_size = std::min(y_border_size, img.nr()/2+1); x_border_size = std::min(x_border_size, img.nc()/2+1); // assign the top border for (long r = 0; r < y_border_size; ++r) { for (long c = 0; c < img.nc(); ++c) { img[r][c] = p; } } // assign the bottom border for (long r = img.nr()-y_border_size; r < img.nr(); ++r) { for (long c = 0; c < img.nc(); ++c) { img[r][c] = p; } } // now assign the two sides for (long r = y_border_size; r < img.nr()-y_border_size; ++r) { // left border for (long c = 0; c < x_border_size; ++c) img[r][c] = p; // right border for (long c = img.nc()-x_border_size; c < img.nc(); ++c) img[r][c] = p; } } template < typename image_type > void assign_border_pixels ( image_type& img_, long x_border_size, long y_border_size, const typename image_traits<image_type>::pixel_type& p ) { image_view<image_type> img(img_); assign_border_pixels(img, x_border_size, y_border_size, p); } // ---------------------------------------------------------------------------------------- template < typename image_type > void zero_border_pixels ( image_type& img, long x_border_size, long y_border_size ) { DLIB_ASSERT( x_border_size >= 0 && y_border_size >= 0, "\tvoid zero_border_pixels(img, p, border_size)" << "\n\tYou have given an invalid border_size" << "\n\tx_border_size: " << x_border_size << "\n\ty_border_size: " << y_border_size ); typename image_traits<image_type>::pixel_type zero_pixel; assign_pixel_intensity(zero_pixel, 0); assign_border_pixels(img, x_border_size, y_border_size, zero_pixel); } // ---------------------------------------------------------------------------------------- template < typename image_type > void zero_border_pixels ( image_view<image_type>& img, long x_border_size, long y_border_size ) { DLIB_ASSERT( x_border_size >= 0 && y_border_size >= 0, "\tvoid zero_border_pixels(img, p, border_size)" << "\n\tYou have given an invalid border_size" << "\n\tx_border_size: " << x_border_size << "\n\ty_border_size: " << y_border_size ); typename image_traits<image_type>::pixel_type zero_pixel; assign_pixel_intensity(zero_pixel, 0); assign_border_pixels(img, x_border_size, y_border_size, zero_pixel); } // ---------------------------------------------------------------------------------------- template < typename image_type > void zero_border_pixels ( image_view<image_type>& img, rectangle inside ) { inside = inside.intersect(get_rect(img)); if (inside.is_empty()) { assign_all_pixels(img, 0); return; } for (long r = 0; r < inside.top(); ++r) { for (long c = 0; c < img.nc(); ++c) assign_pixel(img[r][c], 0); } for (long r = inside.top(); r <= inside.bottom(); ++r) { for (long c = 0; c < inside.left(); ++c) assign_pixel(img[r][c], 0); for (long c = inside.right()+1; c < img.nc(); ++c) assign_pixel(img[r][c], 0); } for (long r = inside.bottom()+1; r < img.nr(); ++r) { for (long c = 0; c < img.nc(); ++c) assign_pixel(img[r][c], 0); } } // ---------------------------------------------------------------------------------------- template < typename image_type > void zero_border_pixels ( image_type& img_, const rectangle& inside ) { image_view<image_type> img(img_); zero_border_pixels(img, inside); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_ASSIGN_IMAGe_