examples.html 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <title>Examples - Boost.GIL documentation</title>
  7. <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  8. <link rel="stylesheet" href="../_static/style.css" type="text/css" />
  9. <script type="text/javascript">
  10. var DOCUMENTATION_OPTIONS = {
  11. URL_ROOT: '../',
  12. VERSION: '',
  13. COLLAPSE_MODINDEX: false,
  14. FILE_SUFFIX: '.html'
  15. };
  16. </script>
  17. <script type="text/javascript" src="../_static/jquery.js"></script>
  18. <script type="text/javascript" src="../_static/underscore.js"></script>
  19. <script type="text/javascript" src="../_static/doctools.js"></script>
  20. <link rel="index" title="Index" href="../genindex.html" />
  21. <link rel="search" title="Search" href="../search.html" />
  22. <link rel="top" title="Boost.GIL documentation" href="../index.html" />
  23. <link rel="up" title="Design Guide" href="index.html" />
  24. <link rel="next" title="Technicalities" href="technicalities.html" />
  25. <link rel="prev" title="Metafunctions" href="metafunctions.html" />
  26. </head>
  27. <body>
  28. <div class="header">
  29. <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
  30. "header">
  31. <tr>
  32. <td valign="top" width="300">
  33. <h3><a href="../index.html"><img
  34. alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3>
  35. </td>
  36. <td >
  37. <h1 align="center"><a href="../index.html"></a></h1>
  38. </td>
  39. <td>
  40. <div id="searchbox" style="display: none">
  41. <form class="search" action="../search.html" method="get">
  42. <input type="text" name="q" size="18" />
  43. <input type="submit" value="Search" />
  44. <input type="hidden" name="check_keywords" value="yes" />
  45. <input type="hidden" name="area" value="default" />
  46. </form>
  47. </div>
  48. <script type="text/javascript">$('#searchbox').show(0);</script>
  49. </td>
  50. </tr>
  51. </table>
  52. </div>
  53. <hr/>
  54. <div class="content">
  55. <div class="navbar" style="text-align:right;">
  56. <a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a>
  57. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  58. <a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a>
  59. </div>
  60. <div class="section" id="examples">
  61. <h1>Examples</h1>
  62. <div class="contents local topic" id="contents">
  63. <ul class="simple">
  64. <li><a class="reference internal" href="#pixel-level-operations" id="id1">Pixel-level Operations</a></li>
  65. <li><a class="reference internal" href="#resizing-image-canvas" id="id2">Resizing image canvas</a></li>
  66. <li><a class="reference internal" href="#histogram" id="id3">Histogram</a></li>
  67. <li><a class="reference internal" href="#using-image-views" id="id4">Using image views</a></li>
  68. </ul>
  69. </div>
  70. <div class="section" id="pixel-level-operations">
  71. <h2><a class="toc-backref" href="#id1">Pixel-level Operations</a></h2>
  72. <p>Here are some operations you can do with pixel values, pixel pointers and
  73. pixel references:</p>
  74. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">rgb8_pixel_t</span> <span class="nf">p1</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// make a red RGB pixel</span>
  75. <span class="n">bgr8_pixel_t</span> <span class="n">p2</span> <span class="o">=</span> <span class="n">p1</span><span class="p">;</span> <span class="c1">// RGB and BGR are compatible and the channels will be properly mapped.</span>
  76. <span class="n">assert</span><span class="p">(</span><span class="n">p1</span><span class="o">==</span><span class="n">p2</span><span class="p">);</span> <span class="c1">// p2 will also be red.</span>
  77. <span class="n">assert</span><span class="p">(</span><span class="n">p2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">!=</span><span class="n">p1</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// operator[] gives physical channel order (as laid down in memory)</span>
  78. <span class="n">assert</span><span class="p">(</span><span class="n">semantic_at_c</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">p1</span><span class="p">)</span><span class="o">==</span><span class="n">semantic_at_c</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">p2</span><span class="p">));</span> <span class="c1">// this is how to compare the two red channels</span>
  79. <span class="n">get_color</span><span class="p">(</span><span class="n">p1</span><span class="p">,</span><span class="n">green_t</span><span class="p">())</span> <span class="o">=</span> <span class="n">get_color</span><span class="p">(</span><span class="n">p2</span><span class="p">,</span><span class="n">blue_t</span><span class="p">());</span> <span class="c1">// channels can also be accessed by name</span>
  80. <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">r</span><span class="p">;</span>
  81. <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">g</span><span class="p">;</span>
  82. <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">b</span><span class="p">;</span>
  83. <span class="n">rgb8c_planar_ptr_t</span> <span class="nf">ptr</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">g</span><span class="p">,</span><span class="n">b</span><span class="p">);</span> <span class="c1">// constructing const planar pointer from const pointers to each plane</span>
  84. <span class="n">rgb8c_planar_ref_t</span> <span class="n">ref</span><span class="o">=*</span><span class="n">ptr</span><span class="p">;</span> <span class="c1">// just like built-in reference, dereferencing a planar pointer returns a planar reference</span>
  85. <span class="n">p2</span><span class="o">=</span><span class="n">ref</span><span class="p">;</span> <span class="n">p2</span><span class="o">=</span><span class="n">p1</span><span class="p">;</span> <span class="n">p2</span><span class="o">=</span><span class="n">ptr</span><span class="p">[</span><span class="mi">7</span><span class="p">];</span> <span class="n">p2</span><span class="o">=</span><span class="n">rgb8_pixel_t</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">);</span> <span class="c1">// planar/interleaved references and values to RGB/BGR can be freely mixed</span>
  86. <span class="c1">//rgb8_planar_ref_t ref2; // compile error: References have no default constructors</span>
  87. <span class="c1">//ref2=*ptr; // compile error: Cannot construct non-const reference by dereferencing const pointer</span>
  88. <span class="c1">//ptr[3]=p1; // compile error: Cannot set the fourth pixel through a const pointer</span>
  89. <span class="c1">//p1 = pixel&lt;float, rgb_layout_t&gt;();// compile error: Incompatible channel depth</span>
  90. <span class="c1">//p1 = pixel&lt;bits8, rgb_layout_t&gt;();// compile error: Incompatible color space (even though it has the same number of channels)</span>
  91. <span class="c1">//p1 = pixel&lt;bits8,rgba_layout_t&gt;();// compile error: Incompatible color space (even though it contains red, green and blue channels)</span>
  92. </pre></div>
  93. </div>
  94. <p>Here is how to use pixels in generic code:</p>
  95. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">GrayPixel</span><span class="p">,</span> <span class="k">typename</span> <span class="n">RGBPixel</span><span class="o">&gt;</span>
  96. <span class="kt">void</span> <span class="n">gray_to_rgb</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayPixel</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="n">RGBPixel</span><span class="o">&amp;</span> <span class="n">dst</span><span class="p">)</span>
  97. <span class="p">{</span>
  98. <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">PixelConcept</span><span class="o">&lt;</span><span class="n">GrayPixel</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  99. <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">MutableHomogeneousPixelConcept</span><span class="o">&lt;</span><span class="n">RGBPixel</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  100. <span class="k">typedef</span> <span class="k">typename</span> <span class="n">color_space_type</span><span class="o">&lt;</span><span class="n">GrayPixel</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">gray_cs_t</span><span class="p">;</span>
  101. <span class="k">static_assert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">is_same</span><span class="o">&lt;</span><span class="n">gray_cs_t</span><span class="p">,</span><span class="n">gray_t</span><span class="o">&gt;::</span><span class="n">value</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">);</span>
  102. <span class="k">typedef</span> <span class="k">typename</span> <span class="n">color_space_type</span><span class="o">&lt;</span><span class="n">RGBPixel</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">rgb_cs_t</span><span class="p">;</span>
  103. <span class="k">static_assert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">is_same</span><span class="o">&lt;</span><span class="n">rgb_cs_t</span><span class="p">,</span><span class="n">rgb_t</span><span class="o">&gt;::</span><span class="n">value</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">);</span>
  104. <span class="k">typedef</span> <span class="k">typename</span> <span class="n">channel_type</span><span class="o">&lt;</span><span class="n">GrayPixel</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">gray_channel_t</span><span class="p">;</span>
  105. <span class="k">typedef</span> <span class="k">typename</span> <span class="n">channel_type</span><span class="o">&lt;</span><span class="n">RGBPixel</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">rgb_channel_t</span><span class="p">;</span>
  106. <span class="n">gray_channel_t</span> <span class="n">gray</span> <span class="o">=</span> <span class="n">get_color</span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="n">gray_color_t</span><span class="p">());</span>
  107. <span class="n">static_fill</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="n">channel_convert</span><span class="o">&lt;</span><span class="n">rgb_channel_t</span><span class="o">&gt;</span><span class="p">(</span><span class="n">gray</span><span class="p">));</span>
  108. <span class="p">}</span>
  109. <span class="c1">// example use patterns:</span>
  110. <span class="c1">// converting gray l-value to RGB and storing at (5,5) in a 16-bit BGR interleaved image:</span>
  111. <span class="n">bgr16_view_t</span> <span class="n">b16</span><span class="p">(...);</span>
  112. <span class="n">gray_to_rgb</span><span class="p">(</span><span class="n">gray8_pixel_t</span><span class="p">(</span><span class="mi">33</span><span class="p">),</span> <span class="n">b16</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">5</span><span class="p">));</span>
  113. <span class="c1">// storing the first pixel of an 8-bit grayscale image as the 5-th pixel of 32-bit planar RGB image:</span>
  114. <span class="n">rgb32f_planar_view_t</span> <span class="n">rpv32</span><span class="p">;</span>
  115. <span class="n">gray8_view_t</span> <span class="nf">gv8</span><span class="p">(...);</span>
  116. <span class="n">gray_to_rgb</span><span class="p">(</span><span class="o">*</span><span class="n">gv8</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">rpv32</span><span class="p">[</span><span class="mi">5</span><span class="p">]);</span>
  117. </pre></div>
  118. </div>
  119. <p>As the example shows, both the source and the destination can be references or
  120. values, planar or interleaved, as long as they model <code class="docutils literal"><span class="pre">PixelConcept</span></code> and
  121. <code class="docutils literal"><span class="pre">MutablePixelConcept</span></code> respectively.</p>
  122. </div>
  123. <div class="section" id="resizing-image-canvas">
  124. <h2><a class="toc-backref" href="#id2">Resizing image canvas</a></h2>
  125. <p>Resizing an image canvas means adding a buffer of pixels around existing
  126. pixels. Size of canvas of an image can never be smaller than the image itself.</p>
  127. <p>Suppose we want to convolve an image with multiple kernels, the largest of
  128. which is 2K+1 x 2K+1 pixels. It may be worth creating a margin of K pixels
  129. around the image borders. Here is how to do it:</p>
  130. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">SrcView</span><span class="p">,</span> <span class="c1">// Models ImageViewConcept (the source view)</span>
  131. <span class="k">typename</span> <span class="n">DstImage</span><span class="o">&gt;</span> <span class="c1">// Models ImageConcept (the returned image)</span>
  132. <span class="kt">void</span> <span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span> <span class="n">SrcView</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">,</span> <span class="n">DstImage</span><span class="o">&amp;</span> <span class="n">result</span><span class="p">)</span>
  133. <span class="p">{</span>
  134. <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">ImageViewConcept</span><span class="o">&lt;</span><span class="n">SrcView</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  135. <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">ImageConcept</span><span class="o">&lt;</span><span class="n">DstImage</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  136. <span class="n">gil_function_requires</span><span class="o">&lt;</span><span class="n">ViewsCompatibleConcept</span><span class="o">&lt;</span><span class="n">SrcView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">DstImage</span><span class="o">::</span><span class="n">view_t</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">();</span>
  137. <span class="n">result</span><span class="o">=</span><span class="n">DstImage</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">,</span> <span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">);</span>
  138. <span class="k">typename</span> <span class="n">DstImage</span><span class="o">::</span><span class="n">view_t</span> <span class="n">centerImg</span><span class="o">=</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">result</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">(),</span><span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">());</span>
  139. <span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">src</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">centerImg</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
  140. <span class="p">}</span>
  141. </pre></div>
  142. </div>
  143. <p>We allocated a larger image, then we used <code class="docutils literal"><span class="pre">subimage_view</span></code> to create a
  144. shallow image of its center area of top left corner at (k,k) and of identical
  145. size as <code class="docutils literal"><span class="pre">src</span></code>, and finally we copied <code class="docutils literal"><span class="pre">src</span></code> into that center image. If the
  146. margin needs initialization, we could have done it with <code class="docutils literal"><span class="pre">fill_pixels</span></code>. Here
  147. is how to simplify this code using the <code class="docutils literal"><span class="pre">copy_pixels</span></code> algorithm:</p>
  148. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">SrcView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">DstImage</span><span class="o">&gt;</span>
  149. <span class="kt">void</span> <span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span> <span class="n">SrcView</span><span class="o">&amp;</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">,</span> <span class="n">DstImage</span><span class="o">&amp;</span> <span class="n">result</span><span class="p">)</span>
  150. <span class="p">{</span>
  151. <span class="n">result</span><span class="p">.</span><span class="n">recreate</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">,</span> <span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">);</span>
  152. <span class="n">copy_pixels</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">subimage_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">result</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">(),</span><span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()));</span>
  153. <span class="p">}</span>
  154. </pre></div>
  155. </div>
  156. <p>(Note also that <code class="docutils literal"><span class="pre">image::recreate</span></code> is more efficient than <code class="docutils literal"><span class="pre">operator=</span></code>, as
  157. the latter will do an unnecessary copy construction). Not only does the above
  158. example work for planar and interleaved images of any color space and pixel
  159. depth; it is also optimized. GIL overrides <code class="docutils literal"><span class="pre">std::copy</span></code> - when called on two
  160. identical interleaved images with no padding at the end of rows, it simply
  161. does a <code class="docutils literal"><span class="pre">memmove</span></code>. For planar images it does <code class="docutils literal"><span class="pre">memmove</span></code> for each channel.
  162. If one of the images has padding, (as in our case) it will try to do
  163. <code class="docutils literal"><span class="pre">memmove</span></code> for each row. When an image has no padding, it will use its
  164. lightweight horizontal iterator (as opposed to the more complex 1D image
  165. iterator that has to check for the end of rows). It choses the fastest method,
  166. taking into account both static and run-time parameters.</p>
  167. </div>
  168. <div class="section" id="histogram">
  169. <h2><a class="toc-backref" href="#id3">Histogram</a></h2>
  170. <p>The histogram can be computed by counting the number of pixel values that fall
  171. in each bin. The following method takes a grayscale (one-dimensional) image
  172. view, since only grayscale pixels are convertible to integers:</p>
  173. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">GrayView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">&gt;</span>
  174. <span class="kt">void</span> <span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayView</span><span class="o">&amp;</span> <span class="n">img</span><span class="p">,</span> <span class="n">R</span><span class="o">&amp;</span> <span class="n">hist</span><span class="p">)</span>
  175. <span class="p">{</span>
  176. <span class="k">for</span> <span class="p">(</span><span class="k">typename</span> <span class="n">GrayView</span><span class="o">::</span><span class="n">iterator</span> <span class="n">it</span><span class="o">=</span><span class="n">img</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">it</span><span class="o">!=</span><span class="n">img</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span>
  177. <span class="o">++</span><span class="n">hist</span><span class="p">[</span><span class="o">*</span><span class="n">it</span><span class="p">];</span>
  178. <span class="p">}</span>
  179. </pre></div>
  180. </div>
  181. <p>Using <code class="docutils literal"><span class="pre">boost::lambda</span></code> and GIL&#8217;s <code class="docutils literal"><span class="pre">for_each_pixel</span></code> algorithm, we can write
  182. this more compactly:</p>
  183. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">GrayView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">&gt;</span>
  184. <span class="kt">void</span> <span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayView</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="n">R</span><span class="o">&amp;</span> <span class="n">hist</span><span class="p">)</span>
  185. <span class="p">{</span>
  186. <span class="n">for_each_pixel</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="o">++</span><span class="n">var</span><span class="p">(</span><span class="n">hist</span><span class="p">)[</span><span class="n">_1</span><span class="p">]);</span>
  187. <span class="p">}</span>
  188. </pre></div>
  189. </div>
  190. <p>Where <code class="docutils literal"><span class="pre">for_each_pixel</span></code> invokes <code class="docutils literal"><span class="pre">std::for_each</span></code> and <code class="docutils literal"><span class="pre">var</span></code> and <code class="docutils literal"><span class="pre">_1</span></code> are
  191. <code class="docutils literal"><span class="pre">boost::lambda</span></code> constructs. To compute the luminosity histogram, we call the
  192. above method using the grayscale view of an image:</p>
  193. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">&gt;</span>
  194. <span class="kt">void</span> <span class="n">luminosity_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="n">R</span><span class="o">&amp;</span> <span class="n">hist</span><span class="p">)</span>
  195. <span class="p">{</span>
  196. <span class="n">grayimage_histogram</span><span class="p">(</span><span class="n">color_converted_view</span><span class="o">&lt;</span><span class="n">gray8_pixel_t</span><span class="o">&gt;</span><span class="p">(</span><span class="n">v</span><span class="p">),</span><span class="n">hist</span><span class="p">);</span>
  197. <span class="p">}</span>
  198. </pre></div>
  199. </div>
  200. <p>This is how to invoke it:</p>
  201. <div class="highlight-cpp"><div class="highlight"><pre><span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">hist</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span>
  202. <span class="n">std</span><span class="o">::</span><span class="n">fill</span><span class="p">(</span><span class="n">hist</span><span class="p">,</span><span class="n">hist</span><span class="o">+</span><span class="mi">256</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
  203. <span class="n">luminosity_histogram</span><span class="p">(</span><span class="n">my_view</span><span class="p">,</span><span class="n">hist</span><span class="p">);</span>
  204. </pre></div>
  205. </div>
  206. <p>If we want to view the histogram of the second channel of the image in the top
  207. left 100x100 area, we call:</p>
  208. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">grayimage_histogram</span><span class="p">(</span><span class="n">nth_channel_view</span><span class="p">(</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">img</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">100</span><span class="p">,</span><span class="mi">100</span><span class="p">),</span><span class="mi">1</span><span class="p">),</span><span class="n">hist</span><span class="p">);</span>
  209. </pre></div>
  210. </div>
  211. <p>No pixels are copied and no extra memory is allocated - the code operates
  212. directly on the source pixels, which could be in any supported color space and
  213. channel depth. They could be either planar or interleaved.</p>
  214. </div>
  215. <div class="section" id="using-image-views">
  216. <h2><a class="toc-backref" href="#id4">Using image views</a></h2>
  217. <p>The following code illustrates the power of using image views:</p>
  218. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">jpeg_read_image</span><span class="p">(</span><span class="s">&quot;monkey.jpg&quot;</span><span class="p">,</span> <span class="n">img</span><span class="p">);</span>
  219. <span class="n">step1</span><span class="o">=</span><span class="n">view</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
  220. <span class="n">step2</span><span class="o">=</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">step1</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span><span class="mi">300</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span><span class="mi">150</span><span class="p">);</span>
  221. <span class="n">step3</span><span class="o">=</span><span class="n">color_converted_view</span><span class="o">&lt;</span><span class="n">rgb8_view_t</span><span class="p">,</span><span class="n">gray8_pixel_t</span><span class="o">&gt;</span><span class="p">(</span><span class="n">step2</span><span class="p">);</span>
  222. <span class="n">step4</span><span class="o">=</span><span class="n">rotated180_view</span><span class="p">(</span><span class="n">step3</span><span class="p">);</span>
  223. <span class="n">step5</span><span class="o">=</span><span class="n">subsampled_view</span><span class="p">(</span><span class="n">step4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
  224. <span class="n">jpeg_write_view</span><span class="p">(</span><span class="s">&quot;monkey_transform.jpg&quot;</span><span class="p">,</span> <span class="n">step5</span><span class="p">);</span>
  225. </pre></div>
  226. </div>
  227. <p>The intermediate images are shown here:</p>
  228. <img alt="../_images/monkey_steps.jpg" src="../_images/monkey_steps.jpg" />
  229. <p>Notice that no pixels are ever copied. All the work is done inside
  230. <code class="docutils literal"><span class="pre">jpeg_write_view</span></code>. If we call our <code class="docutils literal"><span class="pre">luminosity_histogram</span></code> with
  231. <code class="docutils literal"><span class="pre">step5</span></code> it will do the right thing.</p>
  232. </div>
  233. </div>
  234. <div class="navbar" style="text-align:right;">
  235. <a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a>
  236. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  237. <a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a>
  238. </div>
  239. </div>
  240. <div class="footer" role="contentinfo">
  241. Last updated on 2019-12-10 00:12:10.
  242. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
  243. </div>
  244. </body>
  245. </html>