1Tutorial: Histogram 2=================== 3 4.. contents:: 5 :local: 6 :depth: 1 7 8This is a short tutorial presenting an example of a very simple sample of code 9from an existing code base that calculates histogram of an image. 10Next, the program is rewritten using GIL featres. 11 12Original implementation 13----------------------- 14 15Actual code from a commercial software product that computes the luminosity 16histogram (variable names have been changed and unrelated parts removed): 17 18.. code-block:: cpp 19 20 void luminosity_hist( 21 std::uint8_t const* r, std::uint8_t const* g, std::uint8_t const* b, 22 int rows, int cols, int sRowBytes, Histogram* hist) 23 { 24 for (int r = 0; r < rows; r++) 25 { 26 for (int c = 0; c < cols; c++) 27 { 28 int v = RGBToGray(r[c], g[c], b[c]); // call internal function or macro 29 (*hist)[v]++; 30 } 31 r += sRowBytes; 32 g += sRowBytes; 33 b += sRowBytes; 34 } 35 } 36 37Let's consider the following issues of the implementation above: 38 39- Works only for RGB (duplicate versions exist for other color spaces) 40- Works only for 8-bit images (duplicate versions exist) 41- Works only for planar images 42 43GIL implementation 44------------------ 45 46.. code-block:: cpp 47 48 template <typename GrayView, typename R> 49 void grayimage_histogram(GrayView& img, R& hist) 50 { 51 for (typename GrayView::iterator it=img.begin(); it!=img.end(); ++it) 52 ++hist[*it]; 53 } 54 55 template <typename View, typename R> 56 void luminosity8bit_hist(View& img, R& hist) 57 { 58 grayimage_histogram(color_converted_view<gray8_pixel_t>(img),hist); 59 } 60 61Using the Boost.Lambda library (or C++11 lambda) features it can written 62even simpler: 63 64.. code-block:: cpp 65 66 using boost::lambda; 67 68 template <typename GrayView, typename R> 69 void grayimage_histogram(GrayView& img, R& hist) 70 { 71 for_each_pixel(img, ++var(hist)[_1]); 72 } 73 74Let's consider the following advantages of the GIL version: 75 76- Works with any supported channel depth, color space, channel ordering 77 (RGB vs BGR), and row alignment policy. 78- Works for both planar and interleaved images. 79- Works with new color spaces, channel depths and image types that can be 80 provided in future extensions of GIL 81- The second version is as efficient as the hand-coded version 82 83Shortly, it is also very flexible. 84 85For example, to compute the histogram of the second channel of the top left 86quadrant of the image, taking every other row and column, call: 87 88.. code-block:: cpp 89 90 grayimage_histogram( 91 nth_channel_view( 92 subsampled_view( 93 subimage_view(img, 94 0,0, img.width() / 2, img.height() / 2), // upper left quadrant 95 2, 2 // skip every other row and column 96 ), 97 1 // index of the second channel (for example, green for RGB) 98 ), 99 hist 100 ); 101 102Since GIL operates on the source pixels of ``img`` object directly, no extra 103memory is allocated and no images are copied. 104