1 // Copyright (C) 2006  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 #ifndef DLIB_EQUALIZE_HISTOGRAm_
4 #define DLIB_EQUALIZE_HISTOGRAm_
5 
6 #include "../pixel.h"
7 #include "equalize_histogram_abstract.h"
8 #include <vector>
9 #include "../enable_if.h"
10 #include "../matrix.h"
11 
12 namespace dlib
13 {
14 
15 // ---------------------------------------------------------------------------------------
16 
17     template <
18         typename in_image_type,
19         long R,
20         long C,
21         typename MM
22         >
get_histogram(const in_image_type & in_img_,matrix<unsigned long,R,C,MM> & hist,size_t hist_size)23     void get_histogram (
24         const in_image_type& in_img_,
25         matrix<unsigned long,R,C,MM>& hist,
26         size_t hist_size
27     )
28     {
29         typedef typename image_traits<in_image_type>::pixel_type pixel_type;
30         COMPILE_TIME_ASSERT( pixel_traits<pixel_type>::is_unsigned == true );
31 
32         // make sure hist is the right size
33         if (R == 1)
34             hist.set_size(1,hist_size);
35         else
36             hist.set_size(hist_size,1);
37 
38 
39         set_all_elements(hist,0);
40 
41         const_image_view<in_image_type> in_img(in_img_);
42         // compute the histogram
43         for (long r = 0; r < in_img.nr(); ++r)
44         {
45             for (long c = 0; c < in_img.nc(); ++c)
46             {
47                 auto p = get_pixel_intensity(in_img[r][c]);
48                 if (p < hist_size)
49                     ++hist(p);
50             }
51         }
52     }
53 
54 // ----------------------------------------------------------------------------------------
55 
56     template <
57         typename in_image_type,
58         long R,
59         long C,
60         typename MM
61         >
get_histogram(const in_image_type & in_img_,matrix<unsigned long,R,C,MM> & hist)62     void get_histogram (
63         const in_image_type& in_img_,
64         matrix<unsigned long,R,C,MM>& hist
65     )
66     {
67         typedef typename image_traits<in_image_type>::pixel_type pixel_type;
68         COMPILE_TIME_ASSERT( pixel_traits<pixel_type>::is_unsigned == true );
69 
70         typedef typename pixel_traits<pixel_type>::basic_pixel_type in_image_basic_pixel_type;
71         COMPILE_TIME_ASSERT( sizeof(in_image_basic_pixel_type) <= 2);
72 
73         // make sure hist is the right size
74         if (R == 1)
75             hist.set_size(1,pixel_traits<pixel_type>::max()+1);
76         else
77             hist.set_size(pixel_traits<pixel_type>::max()+1,1);
78 
79 
80         set_all_elements(hist,0);
81 
82         const_image_view<in_image_type> in_img(in_img_);
83         // compute the histogram
84         for (long r = 0; r < in_img.nr(); ++r)
85         {
86             for (long c = 0; c < in_img.nc(); ++c)
87             {
88                 unsigned long p = get_pixel_intensity(in_img[r][c]);
89                 ++hist(p);
90             }
91         }
92     }
93 
94 // ---------------------------------------------------------------------------------------
95 
96     template <
97         typename in_image_type,
98         typename out_image_type
99         >
equalize_histogram(const in_image_type & in_img_,out_image_type & out_img_)100     void equalize_histogram (
101         const in_image_type& in_img_,
102         out_image_type& out_img_
103     )
104     {
105         const_image_view<in_image_type> in_img(in_img_);
106         image_view<out_image_type> out_img(out_img_);
107 
108         typedef typename image_traits<in_image_type>::pixel_type in_pixel_type;
109         typedef typename image_traits<out_image_type>::pixel_type out_pixel_type;
110 
111         COMPILE_TIME_ASSERT( pixel_traits<in_pixel_type>::has_alpha == false );
112         COMPILE_TIME_ASSERT( pixel_traits<out_pixel_type>::has_alpha == false );
113 
114         COMPILE_TIME_ASSERT( pixel_traits<in_pixel_type>::is_unsigned == true );
115         COMPILE_TIME_ASSERT( pixel_traits<out_pixel_type>::is_unsigned == true );
116 
117         typedef typename pixel_traits<in_pixel_type>::basic_pixel_type in_image_basic_pixel_type;
118         COMPILE_TIME_ASSERT( sizeof(in_image_basic_pixel_type) <= 2);
119 
120 
121         // if there isn't any input image then don't do anything
122         if (in_img.size() == 0)
123         {
124             out_img.clear();
125             return;
126         }
127 
128         out_img.set_size(in_img.nr(),in_img.nc());
129 
130         unsigned long p;
131 
132         matrix<unsigned long,1,0> histogram;
133         get_histogram(in_img_, histogram);
134         in_img = in_img_;
135 
136         double scale = pixel_traits<out_pixel_type>::max();
137         if (in_img.size() > histogram(0))
138             scale /= in_img.size()-histogram(0);
139         else
140             scale = 0;
141 
142         // make the black pixels remain black in the output image
143         histogram(0) = 0;
144 
145         // compute the transform function
146         for (long i = 1; i < histogram.size(); ++i)
147             histogram(i) += histogram(i-1);
148         // scale so that it is in the range [0,pixel_traits<out_pixel_type>::max()]
149         for (long i = 0; i < histogram.size(); ++i)
150             histogram(i) = static_cast<unsigned long>(histogram(i)*scale);
151 
152         // now do the transform
153         for (long row = 0; row < in_img.nr(); ++row)
154         {
155             for (long col = 0; col < in_img.nc(); ++col)
156             {
157                 p = histogram(get_pixel_intensity(in_img[row][col]));
158                 assign_pixel(out_img[row][col], in_img[row][col]);
159                 assign_pixel_intensity(out_img[row][col],p);
160             }
161         }
162 
163     }
164 
165     template <
166         typename image_type
167         >
equalize_histogram(image_type & img)168     void equalize_histogram (
169         image_type& img
170     )
171     {
172         equalize_histogram(img,img);
173     }
174 
175 // ---------------------------------------------------------------------------------------
176 
177 }
178 
179 #endif // DLIB_EQUALIZE_HISTOGRAm_
180 
181 
182 
183