Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > d5e74628f0e673bb8680aebce32b2c04 > files > 41

itk-doc-3.12.0-1mdv2010.0.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta name="robots" content="noindex">
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>ITK: Neighborhood Iterators</title>
<link href="DoxygenStyle.css" rel="stylesheet" type="text/css">
</head><body bgcolor="#ffffff">


<!--  Section customized for INSIGHT : Tue Jul 17 01:02:45 2001 -->
<center>
<a href="index.html" class="qindex">Main Page</a>&nbsp;&nbsp; 
<a href="modules.html" class="qindex">Groups</a>&nbsp;&nbsp;
<a href="namespaces.html" class="qindex">Namespace List</a>&nbsp;&nbsp;
<a href="hierarchy.html" class="qindex">Class Hierarchy</a>&nbsp;&nbsp;
<a href="classes.html" class="qindex">Alphabetical List</a>&nbsp;&nbsp;
<a href="annotated.html" class="qindex">Compound List</a>&nbsp;&nbsp; 
<a href="files.html" class="qindex">File
List</a>&nbsp;&nbsp; 
<a href="namespacemembers.html" class="qindex">Namespace Members</a>&nbsp;&nbsp; 
<a href="functions.html" class="qindex">Compound Members</a>&nbsp;&nbsp; 
<a href="globals.html" class="qindex">File Members</a>&nbsp;&nbsp;
<a href="pages.html" class="qindex">Concepts</a></center>


<!-- Generated by Doxygen 1.5.9 -->
<div class="contents">
<h1><a class="anchor" name="NeighborhoodIteratorsPage">Neighborhood Iterators </a></h1><h2><a class="anchor" name="IntroductionSection">
Introduction</a></h2>
This document provides a general overview of the intended use of the NeighborhoodIterator classes and their associated objects for low-level image processing in Itk. For a more detailed description of the API, please refer to the inline Itk documentation and manual.<p>
<dl class="user" compact><dt><b></b></dt><dd>Neighborhood iterators are the abstraction of the concept of <em>locality</em> in image processing. They are designed to be used in algorithms that perform calculations on a neighborhood of pixel values around a point in an image. For example, a classic neighborhood-based operation is to compute the mean of a set of pixels in order to reduce noise in an image. This is typically done by taking a region of 3x3 pixels and computing the average of their values. <a class="el" href="classA.html">A</a> new image with fewer narrow high frequency spikes (noise) is produced using the resulting means.</dd></dl>
<dl class="user" compact><dt><b></b></dt><dd>This code in classical <em>texbook</em> notation can look like:</dd></dl>
<div class="fragment"><pre class="fragment">  <span class="keywordtype">int</span> nx = 512;
  <span class="keywordtype">int</span> ny = 512;
  ImageType image(nx,ny);
  <span class="keywordflow">for</span>(<span class="keywordtype">int</span> x=1; x&lt;nx-1; x++) 
  {
    <span class="keywordtype">float</span> sum = 0;
    <span class="keywordflow">for</span>(<span class="keywordtype">int</span> y=1; y&lt;ny-1; y++) 
    {
      sum += image(x-1,y-1) + image(x  ,y-1) + image(x+1,y-1);
      sum += image(x-1,y  ) + image(x  ,y  ) + image(x+1,y  );
      sum += image(x-1,y+1) + image(x  ,y+1) + image(x+1,y+1);
    }
  }  
</pre></div><p>
<dl class="user" compact><dt><b></b></dt><dd>The code above is readable and straightforward to implement. But its efficiency is limited to the speed of random access into the image. It also assumes a two dimensional image. We can eliminate the random access bottleneck by using iterators to dereference pixels, and for a two-dimensional image, code-readability may not suffer much. But what if we want code for three or more dimensions? Before long, the code size and complexity will increase to unmanageable levels. In Itk, we have encapsulated this functionality for efficiency, readability, and reusability.</dd></dl>
<h2><a class="anchor" name="NeighborhoodIteratorsSection">
Neighborhood iterators</a></h2>
<a class="el" href="classitk_1_1Image.html" title="Templated n-dimensional image class.">itk::Image</a> neighborhood iteration and dereferencing is encapsulated in the <a class="el" href="classitk_1_1NeighborhoodIterator.html" title="Defines iteration of a local N-dimensional neighborhood of pixels across an itk::Image...">itk::NeighborhoodIterator</a> classes. ITK NeighborhoodIterators allow for code that is closer to the algorithmic abstraction,<p>
<div class="fragment"><pre class="fragment">  ForAllTheIndicies i in Image
     GetTheNeighbors n in a 3x3 region around i
       Compute the mean of all pixels n
         Write the value to the output at i
</pre></div><p>
Here is how the pseudocode above can be rewritten in ITK using neighborhood iterators: ( In the code examples that follow, some template parameters may have been omitted for clarity. )<p>
<div class="fragment"><pre class="fragment">1   <span class="keyword">typedef</span> <a class="code" href="classitk_1_1Image.html" title="Templated n-dimensional image class.">itk::Image&lt;float, 2&gt;</a> ImageType;
2   <span class="keyword">typedef</span> itk::SmartNeighborhoodIterator&lt;ImageType&gt; NeighborhoodIterator;
3   <span class="keyword">typedef</span> <a class="code" href="classitk_1_1ImageRegionIterator.html" title="A multi-dimensional iterator templated over image type that walks a region of pixels...">itk::ImageRegionIterator&lt;ImageType&gt;</a>       ImageIterator;
4
5   <a class="code" href="itkFEMMacro_8h.html#539cce1a3282ba59952dedcbf9cdb23f">ImageType::Pointer</a> input_image  = GetImageSomehow();
6   <a class="code" href="itkFEMMacro_8h.html#539cce1a3282ba59952dedcbf9cdb23f">ImageType::Pointer</a> output_image = GetImageSomehow();
7
8   <span class="comment">// A radius of 1 in all axial directions gives a 3x3x3x3x... neighborhood.</span>
9   NeighborhoodIterator::RadiusType radius;
10  <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; ImageType::ImageDimension; ++i) radius[i] = 1;
11
12  <span class="comment">// Initializes the iterators on the input &amp; output image regions</span>
13  NeighborhoodIterator it(radius, input_image, 
14                                  output_image-&gt;GetRequestedRegion());
15  ImageIterator out(output_image, output_image-&gt;GetRequestedRegion());
16
17  <span class="comment">// Iterates over the input and output</span>
18  <span class="keywordflow">for</span> (it.SetToBegin(), out = out.Begin(); ! it.IsAtEnd(); ++it, ++out )
19    {
20      <span class="keywordtype">float</span> accum = 0.0;
21      <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; it.Size(); ++i)
22        {    
23          accum += it.GetPixel(i);  
24        }
25      out.Set(accum/(<span class="keywordtype">float</span>)(it.Size()));
26    }
</pre></div><p>
<dl class="user" compact><dt><b></b></dt><dd>Note that the computational work is confined to lines 18-26. The code is also completely generalized for multiple dimensions. For example, changing line 1 to: <div class="fragment"><pre class="fragment">1   <span class="keyword">typedef</span> <a class="code" href="classitk_1_1Image.html" title="Templated n-dimensional image class.">itk::Image&lt;float, 5&gt;</a> ImageType;
</pre></div> produces an averaging filter for five-dimensional images.</dd></dl>
<dl class="user" compact><dt><b></b></dt><dd>The values in the neighborhood are dereferenced through the GetPixel(n) method of the iterator. Think of the iterator as a C array, storing neighborhood values in the same order that they are stored in the image, with the lowest dimension as the fastest increasing dimension.</dd></dl>
<h2><a class="anchor" name="OperatorsOperationsSection">
Neighborhood operators and operations</a></h2>
NeighborhoodOperators are container classes for generating and storing computational kernels such as LaPlacian, Gaussian, derivative, and morphological operators. They provide a generalized interface for creation and access of the operator coefficients.<p>
<dl class="user" compact><dt><b></b></dt><dd>Applying a NeighborhoodOperator to a NeighborhoodIterator requires defining some sort of operation. One common case is that of convolution with a kernel of coefficients. In Itk, convolution filtering of an image can be done in just a few lines of code using an inner product operation between a neighborhood iterator and an operator. The following convolution with a LaPlacian kernel demonstrates this concept.</dd></dl>
<div class="fragment"><pre class="fragment">1  LaPlacianOperator&lt;double, 3&gt; OP;
2  ImageIterator out( outputImage, regionToProcess );
3  NeighborhoodIterator it ( OP.GetRadius(), inputImage, regionToProcess );
4  NeighborhoodInnerProduct IP;
5
6  out = out.Begin();
7  <span class="keywordflow">for</span> (it.SetToBegin(); it != it.End(); ++it, ++out) 
8  {
9    out.Set( IP( it, OP) );
10 }
</pre></div><p>
<dl class="user" compact><dt><b></b></dt><dd>Sometimes it may be more appropriate and efficient to work outside of the operator/operation model. The mean calculation above is one example. <a class="el" href="classA.html">A</a> ``half'' directional derivative, shown below, is another example.</dd></dl>
<div class="fragment"><pre class="fragment">1  NeighborhoodIterator::RadiusType radius = {1, 0, 0};
2  NeighborhoodIterator it(radius, inputImage, regionToProcess)
3  ImageRegionIterator out( outputImage, regionToProcess );
4  <span class="keywordflow">for</span> (it.SetToBegin(); it != it.End(); ++it, ++out) 
5  {
6    out.Set( it.GetPixel(3) - it.GetPixel(2) );
7  }
</pre></div><p>
<dl class="user" compact><dt><b></b></dt><dd>In this example the neighborhood is defined as a three pixel strip with width along only the first axis. Mapping the spatial orientation of neighborhood pixels to the array location is the responsibility of the code writer. Some methods such as GetStride(n), which returns the stride length in pixels along an axis n, have been provided to help in coding algorithms for arbitrary dimensionality. The index of the center pixel in a neighborhood is always Size()/2.</dd></dl>
<h2><a class="anchor" name="ImageBoundariesSection">
Calculations at image boundaries</a></h2>
For any neighborhood operation, conditions at data set boundaries become important. SmartNeighborhoodIterator defines a special class of neighborhood iterators that transparently handle boundary conditions. These iterators store a boundary condition object that is used to calculate a value of requested pixel indicies that lie outside the data set boundary. New boundary condition objects can be defined by a user and plugged into SmartNeighboroodIterators as is appropriate for their algorithm.<p>
<dl class="user" compact><dt><b></b></dt><dd><a class="el" href="classA.html">A</a> SmartNeighborhoodIterator can be used in place of NeighborhoodIterator to iterate over an entire image region, but it will incur a penalty on performance. For this reason, it is desirable to process the image differently over distinct boundary and non-boundary regions. Itk's definition of image regions makes this easy to manage. The process is as follows: first apply the algorithm over all neighborhoods not on the image boundary using the fast NeighborhoodIterator, then process each region on the boundary using the SmartNeighborhoodIterator. The size of the boundary regions are defined by the radius of the neighborhood that you are using.</dd></dl>
<dl class="user" compact><dt><b></b></dt><dd>Rewriting the inner product code using this approach looks like the following. (Here we are using the default SmartNeighborhoodIterator boundary condition and omitting some template parameters for simplicity.)</dd></dl>
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> NeighborhoodAlgorithm::ImageBoundaryFacesCalculator RegionFinderType;

LaPlacianOperator&lt;double, InputImageType::ImageDimension&gt; OP;

RegionFinderType regionCalculator;
RegionFinderType::FaceListType regions;
RegionFinderType::FaceListType::iterator regions_iterator;

regions = regionCalculator( inputImage, regionToProcess, it.GetRadius() );
regions_iterator = regions.begin();

ImageIterator out;

<span class="comment">//</span>
<span class="comment">// Process non-boundary regions normally.</span>
<span class="comment">//</span>
out = ImageIterator(outputImage, *regions_iterator);
NeighborhoodIterator it (OP.GetRadius(), inputImage, *regions_iterator);
NeighborhoodInnerProduct IP;
out = out.Begin();
<span class="keywordflow">for</span> (it.SetToBegin(); it != it.End(); ++it, ++out) 
{
  out.Set( IP( it, OP) );
}

<span class="comment">//</span>
<span class="comment">// Process each boundary region with boundary conditions.</span>
<span class="comment">//</span>
SmartNeighborhoodInnerProduct SIP;
SmartNeighborhoodIterator sit;
<span class="keywordflow">for</span> (regions_iterator++ ; regions_iterator != regions.end(); regions_iterator++)
{
  out = ImageIterator(outputImage, *regions_iterator);
  sit = SmartNeighborhoodIterator(OP.GetRadius(), inputImage, *regions_iterator);
  <span class="keywordflow">for</span> (sit.SetToBegin(); sit != sit.End(); ++sit, ++out) 
  {
    out.Set( SIP( sit, OP) );
  }
}
</pre></div><p>
<dl class="user" compact><dt><b></b></dt><dd>The NeighborhoodAlgorithm::ImageBoundaryFacesCalculator is a special function object that returns a list of sub-regions, or faces, of an image region. The first region in the list corresponds to all the non-boundary pixels in the input image region. Subseqent regions in the list represent all of the boundary faces of the image (because an image region is defined only by a single index and size, no single composite boundary region is possible). The list is traversed with an iterator.</dd></dl>
<h2><a class="anchor" name="FurtherInformationSection">
Further information</a></h2>
Many filters in Itk use the neighborhood iterators and operators. Some canonical examples of their use include the class of AnisotropicDiffusionFunctions and the morphological image filters. itk::WatershedSegmenter also makes extensive use of the neighborhood iterators.<p>
<dl class="user" compact><dt><b></b></dt><dd>The best documentation of the API for these objects is are the class definitions themselves, since the API is subject to change as the tookit matures and is refined. </dd></dl>
</div>
<hr><address><small>
Generated at Fri May 8 00:42:55 2009 for ITK  by <a href="http://www.stack.nl/~dimitri/doxygen/index.html"> <img 
src="http://www.stack.nl/~dimitri/doxygen/doxygen.png" alt="doxygen"
align="middle" border=0 width=110 height=53>
</a> 1.5.9 written by <a href="mailto:dimitri@stack.nl">Dimitri van Heesch</a>,
 &copy;&nbsp;1997-2000</small></address>
</body>
</html>