8 #ifndef BOOST_GIL_IMAGE_PROCESSING_HISTOGRAM_EQUALIZATION_HPP
9 #define BOOST_GIL_IMAGE_PROCESSING_HISTOGRAM_EQUALIZATION_HPP
11 #include <boost/gil/histogram.hpp>
12 #include <boost/gil/image.hpp>
18 namespace boost {
namespace gil {
43 template <
typename SrcKeyType>
44 auto histogram_equalization(histogram<SrcKeyType>
const& src_hist)
45 -> std::map<SrcKeyType, SrcKeyType>
47 histogram<SrcKeyType> dst_hist;
48 return histogram_equalization(src_hist, dst_hist);
61 template <
typename SrcKeyType,
typename DstKeyType>
62 auto histogram_equalization(histogram<SrcKeyType>
const& src_hist, histogram<DstKeyType>& dst_hist)
63 -> std::map<SrcKeyType, DstKeyType>
66 std::is_integral<SrcKeyType>::value &&
67 std::is_integral<DstKeyType>::value,
68 "Source and destination histogram types are not appropriate");
70 using value_t =
typename histogram<SrcKeyType>::value_type;
72 double sum = src_hist.sum();
73 SrcKeyType min_key = (std::numeric_limits<DstKeyType>::min)();
74 SrcKeyType max_key = (std::numeric_limits<DstKeyType>::max)();
75 auto cumltv_srchist = cumulative_histogram(src_hist);
76 std::map<SrcKeyType, DstKeyType> color_map;
77 std::for_each(cumltv_srchist.begin(), cumltv_srchist.end(), [&](value_t
const& v) {
78 DstKeyType trnsfrmd_key =
79 static_cast<DstKeyType>((v.second * (max_key - min_key)) / sum + min_key);
80 color_map[std::get<0>(v.first)] = trnsfrmd_key;
82 std::for_each(src_hist.begin(), src_hist.end(), [&](value_t
const& v) {
83 dst_hist[color_map[std::get<0>(v.first)]] += v.second;
98 template <
typename SrcView,
typename DstView>
99 void histogram_equalization(
100 SrcView
const& src_view,
101 DstView
const& dst_view,
102 std::size_t bin_width = 1,
104 std::vector<std::vector<bool>> src_mask = {})
106 gil_function_requires<ImageViewConcept<SrcView>>();
107 gil_function_requires<MutableImageViewConcept<DstView>>();
110 color_spaces_are_compatible<
111 typename color_space_type<SrcView>::type,
112 typename color_space_type<DstView>::type>::value,
113 "Source and destination views must have same color space");
116 using source_channel_t =
typename channel_type<SrcView>::type;
117 using dst_channel_t =
typename channel_type<DstView>::type;
118 using coord_t =
typename SrcView::x_coord_t;
120 std::size_t
const channels = num_channels<SrcView>::value;
121 coord_t
const width = src_view.width();
122 coord_t
const height = src_view.height();
123 std::size_t pixel_max = (std::numeric_limits<dst_channel_t>::max)();
124 std::size_t pixel_min = (std::numeric_limits<dst_channel_t>::min)();
126 for (std::size_t i = 0; i < channels; i++)
128 histogram<source_channel_t> h;
129 fill_histogram(nth_channel_view(src_view, i), h, bin_width,
false,
false, mask, src_mask);
131 auto h2 = cumulative_histogram(h);
132 for (std::ptrdiff_t src_y = 0; src_y < height; ++src_y)
134 auto src_it = nth_channel_view(src_view, i).row_begin(src_y);
135 auto dst_it = nth_channel_view(dst_view, i).row_begin(src_y);
136 for (std::ptrdiff_t src_x = 0; src_x < width; ++src_x)
138 if (mask && !src_mask[src_y][src_x])
139 dst_it[src_x][0] = channel_convert<dst_channel_t>(src_it[src_x][0]);
141 dst_it[src_x][0] =
static_cast<dst_channel_t
>(
142 h2[src_it[src_x][0]] * (pixel_max - pixel_min) + pixel_min);
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36