2
0
mirror of https://github.com/boostorg/gil.git synced 2026-01-26 18:42:12 +00:00
Files
gil/develop/doc/html/design/examples.html
github-actions[bot] 62e86ae346 deploy: 4115f5b5d3
2026-01-23 01:40:49 +00:00

273 lines
35 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Examples - Boost.GIL documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/style.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/sphinx_highlight.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/searchtools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Boost.GIL documentation" href="../index.html" />
<link rel="up" title="Design Guide" href="index.html" />
<link rel="next" title="Technicalities" href="technicalities.html" />
<link rel="prev" title="Metafunctions" href="metafunctions.html" />
</head>
<body>
<div class="header">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../index.html"><img
alt="C++ Boost" src="../../_static/gil.png" border="0"></a></h3>
</td>
<td >
<h1 align="center"><a href="../index.html"></a></h1>
</td>
<td>
<div id="searchbox" style="display: none">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Search" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</td>
</tr>
</table>
</div>
<hr/>
<div class="content">
<div class="navbar" style="text-align:right;">
<a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a>
<a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
<a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a>
</div>
<section id="examples">
<h1>Examples<a class="headerlink" href="#examples" title="Link to this heading"></a></h1>
<nav class="contents local" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#pixel-level-operations" id="id1">Pixel-level Operations</a></p></li>
<li><p><a class="reference internal" href="#resizing-image-canvas" id="id2">Resizing image canvas</a></p></li>
<li><p><a class="reference internal" href="#histogram" id="id3">Histogram</a></p></li>
<li><p><a class="reference internal" href="#using-image-views" id="id4">Using image views</a></p></li>
</ul>
</nav>
<section id="pixel-level-operations">
<h2><a class="toc-backref" href="#id1" role="doc-backlink">Pixel-level Operations</a><a class="headerlink" href="#pixel-level-operations" title="Link to this heading"></a></h2>
<p>Here are some operations you can do with pixel values, pixel pointers and
pixel references:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="n">rgb8_pixel_t</span><span class="w"> </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="w"> </span><span class="c1">// make a red RGB pixel</span>
<span class="n">bgr8_pixel_t</span><span class="w"> </span><span class="n">p2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">p1</span><span class="p">;</span><span class="w"> </span><span class="c1">// RGB and BGR are compatible and the channels will be properly mapped.</span>
<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="w"> </span><span class="c1">// p2 will also be red.</span>
<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="w"> </span><span class="c1">// operator[] gives physical channel order (as laid down in memory)</span>
<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="w"> </span><span class="c1">// this is how to compare the two red channels</span>
<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="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="c1">// channels can also be accessed by name</span>
<span class="k">const</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">r</span><span class="p">;</span>
<span class="k">const</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">g</span><span class="p">;</span>
<span class="k">const</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<span class="n">rgb8c_planar_ptr_t</span><span class="w"> </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="w"> </span><span class="c1">// constructing const planar pointer from const pointers to each plane</span>
<span class="n">rgb8c_planar_ref_t</span><span class="w"> </span><span class="n">ref</span><span class="o">=*</span><span class="n">ptr</span><span class="p">;</span><span class="w"> </span><span class="c1">// just like built-in reference, dereferencing a planar pointer returns a planar reference</span>
<span class="n">p2</span><span class="o">=</span><span class="n">ref</span><span class="p">;</span><span class="w"> </span><span class="n">p2</span><span class="o">=</span><span class="n">p1</span><span class="p">;</span><span class="w"> </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="w"> </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="w"> </span><span class="c1">// planar/interleaved references and values to RGB/BGR can be freely mixed</span>
<span class="c1">//rgb8_planar_ref_t ref2; // compile error: References have no default constructors</span>
<span class="c1">//ref2=*ptr; // compile error: Cannot construct non-const reference by dereferencing const pointer</span>
<span class="c1">//ptr[3]=p1; // compile error: Cannot set the fourth pixel through a const pointer</span>
<span class="c1">//p1 = pixel&lt;float, rgb_layout_t&gt;();// compile error: Incompatible channel depth</span>
<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>
<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>
</pre></div>
</div>
<p>Here is how to use pixels in generic code:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">GrayPixel</span><span class="p">,</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">RGBPixel</span><span class="o">&gt;</span>
<span class="kt">void</span><span class="w"> </span><span class="n">gray_to_rgb</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">GrayPixel</span><span class="o">&amp;</span><span class="w"> </span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="n">RGBPixel</span><span class="o">&amp;</span><span class="w"> </span><span class="n">dst</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><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="w"> </span><span class="o">&gt;</span><span class="p">();</span>
<span class="w"> </span><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="w"> </span><span class="o">&gt;</span><span class="p">();</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">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="w"> </span><span class="n">gray_cs_t</span><span class="p">;</span>
<span class="w"> </span><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="w"> </span><span class="s">&quot;&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">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="w"> </span><span class="n">rgb_cs_t</span><span class="p">;</span>
<span class="w"> </span><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="w"> </span><span class="s">&quot;&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">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="w"> </span><span class="n">gray_channel_t</span><span class="p">;</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">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="w"> </span><span class="n">rgb_channel_t</span><span class="p">;</span>
<span class="w"> </span><span class="n">gray_channel_t</span><span class="w"> </span><span class="n">gray</span><span class="w"> </span><span class="o">=</span><span class="w"> </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>
<span class="w"> </span><span class="n">static_fill</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span><span class="w"> </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>
<span class="p">}</span>
<span class="c1">// example use patterns:</span>
<span class="c1">// converting gray l-value to RGB and storing at (5,5) in a 16-bit BGR interleaved image:</span>
<span class="n">bgr16_view_t</span><span class="w"> </span><span class="n">b16</span><span class="p">(...);</span>
<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="w"> </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>
<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>
<span class="n">rgb32f_planar_view_t</span><span class="w"> </span><span class="n">rpv32</span><span class="p">;</span>
<span class="n">gray8_view_t</span><span class="w"> </span><span class="nf">gv8</span><span class="p">(...);</span>
<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="w"> </span><span class="n">rpv32</span><span class="p">[</span><span class="mi">5</span><span class="p">]);</span>
</pre></div>
</div>
<p>As the example shows, both the source and the destination can be references or
values, planar or interleaved, as long as they model <code class="docutils literal notranslate"><span class="pre">PixelConcept</span></code> and
<code class="docutils literal notranslate"><span class="pre">MutablePixelConcept</span></code> respectively.</p>
</section>
<section id="resizing-image-canvas">
<h2><a class="toc-backref" href="#id2" role="doc-backlink">Resizing image canvas</a><a class="headerlink" href="#resizing-image-canvas" title="Link to this heading"></a></h2>
<p>Resizing an image canvas means adding a buffer of pixels around existing
pixels. Size of canvas of an image can never be smaller than the image itself.</p>
<p>Suppose we want to convolve an image with multiple kernels, the largest of
which is 2K+1 x 2K+1 pixels. It may be worth creating a margin of K pixels
around the image borders. Here is how to do it:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">SrcView</span><span class="p">,</span><span class="w"> </span><span class="c1">// Models ImageViewConcept (the source view)</span>
<span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">DstImage</span><span class="o">&gt;</span><span class="w"> </span><span class="c1">// Models ImageConcept (the returned image)</span>
<span class="kt">void</span><span class="w"> </span><span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">SrcView</span><span class="o">&amp;</span><span class="w"> </span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">DstImage</span><span class="o">&amp;</span><span class="w"> </span><span class="n">result</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><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="w"> </span><span class="o">&gt;</span><span class="p">();</span>
<span class="w"> </span><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="w"> </span><span class="o">&gt;</span><span class="p">();</span>
<span class="w"> </span><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="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">DstImage</span><span class="o">::</span><span class="n">view_t</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&gt;</span><span class="p">();</span>
<span class="w"> </span><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="w"> </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>
<span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">DstImage</span><span class="o">::</span><span class="n">view_t</span><span class="w"> </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="w"> </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>
<span class="w"> </span><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="w"> </span><span class="n">src</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span><span class="w"> </span><span class="n">centerImg</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
<span class="p">}</span>
</pre></div>
</div>
<p>We allocated a larger image, then we used <code class="docutils literal notranslate"><span class="pre">subimage_view</span></code> to create a
shallow image of its center area of top left corner at (k,k) and of identical
size as <code class="docutils literal notranslate"><span class="pre">src</span></code>, and finally we copied <code class="docutils literal notranslate"><span class="pre">src</span></code> into that center image. If the
margin needs initialization, we could have done it with <code class="docutils literal notranslate"><span class="pre">fill_pixels</span></code>. Here
is how to simplify this code using the <code class="docutils literal notranslate"><span class="pre">copy_pixels</span></code> algorithm:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">SrcView</span><span class="p">,</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">DstImage</span><span class="o">&gt;</span>
<span class="kt">void</span><span class="w"> </span><span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">SrcView</span><span class="o">&amp;</span><span class="w"> </span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">DstImage</span><span class="o">&amp;</span><span class="w"> </span><span class="n">result</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><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="w"> </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>
<span class="w"> </span><span class="n">copy_pixels</span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="w"> </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="w"> </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>
<span class="p">}</span>
</pre></div>
</div>
<p>(Note also that <code class="docutils literal notranslate"><span class="pre">image::recreate</span></code> is more efficient than <code class="docutils literal notranslate"><span class="pre">operator=</span></code>, as
the latter will do an unnecessary copy construction.) Not only does the above
example work for planar and interleaved images of any color space and pixel
depth; it is also optimized. GIL overrides <code class="docutils literal notranslate"><span class="pre">std::copy</span></code> - when called on two
identical interleaved images with no padding at the end of rows, it simply
does a <code class="docutils literal notranslate"><span class="pre">memmove</span></code>. For planar images it does <code class="docutils literal notranslate"><span class="pre">memmove</span></code> for each channel.
If one of the images has padding, (as in our case) it will try to do
<code class="docutils literal notranslate"><span class="pre">memmove</span></code> for each row. When an image has no padding, it will use its
lightweight horizontal iterator (as opposed to the more complex 1D image
iterator that has to check for the end of rows). It chooses the fastest method,
taking into account both static and run-time parameters.</p>
</section>
<section id="histogram">
<h2><a class="toc-backref" href="#id3" role="doc-backlink">Histogram</a><a class="headerlink" href="#histogram" title="Link to this heading"></a></h2>
<p>The histogram can be computed by counting the number of pixel values that fall
in each bin. The following method takes a grayscale (one-dimensional) image
view, since only grayscale pixels are convertible to integers:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">GrayView</span><span class="p">,</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">R</span><span class="o">&gt;</span>
<span class="kt">void</span><span class="w"> </span><span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">GrayView</span><span class="o">&amp;</span><span class="w"> </span><span class="n">img</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="o">&amp;</span><span class="w"> </span><span class="n">hist</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="k">typename</span><span class="w"> </span><span class="nc">GrayView</span><span class="o">::</span><span class="n">iterator</span><span class="w"> </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="w"> </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="w"> </span><span class="o">++</span><span class="n">it</span><span class="p">)</span>
<span class="w"> </span><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>
<span class="p">}</span>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">boost::lambda</span></code> and GILs <code class="docutils literal notranslate"><span class="pre">for_each_pixel</span></code> algorithm, we can write
this more compactly:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">GrayView</span><span class="p">,</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">R</span><span class="o">&gt;</span>
<span class="kt">void</span><span class="w"> </span><span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">GrayView</span><span class="o">&amp;</span><span class="w"> </span><span class="n">v</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="o">&amp;</span><span class="w"> </span><span class="n">hist</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">for_each_pixel</span><span class="p">(</span><span class="n">v</span><span class="p">,</span><span class="w"> </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>
<span class="p">}</span>
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">for_each_pixel</span></code> invokes <code class="docutils literal notranslate"><span class="pre">std::for_each</span></code> and <code class="docutils literal notranslate"><span class="pre">var</span></code> and <code class="docutils literal notranslate"><span class="pre">_1</span></code> are
<code class="docutils literal notranslate"><span class="pre">boost::lambda</span></code> constructs. To compute the luminosity histogram, we call the
above method using the grayscale view of an image:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">View</span><span class="p">,</span><span class="w"> </span><span class="k">typename</span><span class="w"> </span><span class="nc">R</span><span class="o">&gt;</span>
<span class="kt">void</span><span class="w"> </span><span class="n">luminosity_histogram</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">View</span><span class="o">&amp;</span><span class="w"> </span><span class="n">v</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="o">&amp;</span><span class="w"> </span><span class="n">hist</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><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>
<span class="p">}</span>
</pre></div>
</div>
<p>This is how to invoke it:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">hist</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span>
<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>
<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>
</pre></div>
</div>
<p>If we want to view the histogram of the second channel of the image in the top
left 100x100 area, we call:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><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>
</pre></div>
</div>
<p>No pixels are copied and no extra memory is allocated - the code operates
directly on the source pixels, which could be in any supported color space and
channel depth. They could be either planar or interleaved.</p>
</section>
<section id="using-image-views">
<h2><a class="toc-backref" href="#id4" role="doc-backlink">Using image views</a><a class="headerlink" href="#using-image-views" title="Link to this heading"></a></h2>
<p>The following code illustrates the power of using image views:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><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="w"> </span><span class="n">img</span><span class="p">);</span>
<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>
<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="w"> </span><span class="mi">200</span><span class="p">,</span><span class="mi">300</span><span class="p">,</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span><span class="mi">150</span><span class="p">);</span>
<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>
<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>
<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="w"> </span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
<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="w"> </span><span class="n">step5</span><span class="p">);</span>
</pre></div>
</div>
<p>The intermediate images are shown here:</p>
<img alt="../_images/monkey_steps.jpg" src="../_images/monkey_steps.jpg" />
<p>Notice that no pixels are ever copied. All the work is done inside
<code class="docutils literal notranslate"><span class="pre">jpeg_write_view</span></code>. If we call our <code class="docutils literal notranslate"><span class="pre">luminosity_histogram</span></code> with
<code class="docutils literal notranslate"><span class="pre">step5</span></code> it will do the right thing.</p>
</section>
</section>
<div class="navbar" style="text-align:right;">
<a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a>
<a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
<a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a>
</div>
</div>
<div class="footer" role="contentinfo">
Last updated on 2026-01-23 01:01:39.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 7.2.6.
</div>
</body>
</html>