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