// Copyright (C) 2006 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_EQUALIZE_HISTOGRAm_
#define DLIB_EQUALIZE_HISTOGRAm_
#include "../pixel.h"
#include "equalize_histogram_abstract.h"
#include <vector>
#include "../enable_if.h"
#include "../matrix.h"
namespace dlib
{
// ---------------------------------------------------------------------------------------
template <
typename in_image_type,
long R,
long C,
typename MM
>
void get_histogram (
const in_image_type& in_img,
matrix<unsigned long,R,C,MM>& hist
)
{
COMPILE_TIME_ASSERT( pixel_traits<typename in_image_type::type>::is_unsigned == true );
// make sure hist is the right size
if (R == 1)
hist.set_size(1,pixel_traits<typename in_image_type::type>::max()+1);
else
hist.set_size(pixel_traits<typename in_image_type::type>::max()+1,1);
set_all_elements(hist,0);
// compute the histogram
for (long r = 0; r < in_img.nr(); ++r)
{
for (long c = 0; c < in_img.nc(); ++c)
{
unsigned long p = get_pixel_intensity(in_img[r][c]);
++hist(p);
}
}
}
// ---------------------------------------------------------------------------------------
template <
typename in_image_type,
typename out_image_type
>
void equalize_histogram (
const in_image_type& in_img,
out_image_type& out_img
)
{
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( pixel_traits<typename in_image_type::type>::is_unsigned == true );
COMPILE_TIME_ASSERT( pixel_traits<typename out_image_type::type>::is_unsigned == true );
typedef typename in_image_type::type in_pixel_type;
typedef typename out_image_type::type out_pixel_type;
// 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());
unsigned long p;
matrix<unsigned long,1,0,typename in_image_type::mem_manager_type> histogram;
get_histogram(in_img, histogram);
double scale = pixel_traits<out_pixel_type>::max();
if (in_img.size() > histogram(0))
scale /= in_img.size()-histogram(0);
else
scale = 0;
// make the black pixels remain black in the output image
histogram(0) = 0;
// compute the transform function
for (long i = 1; i < histogram.size(); ++i)
histogram(i) += histogram(i-1);
// scale so that it is in the range [0,pixel_traits<out_pixel_type>::max()]
for (long i = 0; i < histogram.size(); ++i)
histogram(i) = static_cast<unsigned long>(histogram(i)*scale);
// now do the transform
for (long row = 0; row < in_img.nr(); ++row)
{
for (long col = 0; col < in_img.nc(); ++col)
{
p = histogram(get_pixel_intensity(in_img[row][col]));
assign_pixel(out_img[row][col], in_img[row][col]);
assign_pixel_intensity(out_img[row][col],p);
}
}
}
// ---------------------------------------------------------------------------------------
}
#endif // DLIB_EQUALIZE_HISTOGRAm_