<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PaulNovo.org &#187; Tutorials</title>
	<atom:link href="http://paulnovo.us/category/tutorials/feed" rel="self" type="application/rss+xml" />
	<link>http://paulnovo.us</link>
	<description>paul novotny&#039;s internet home</description>
	<lastBuildDate>Fri, 23 Dec 2011 21:22:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Getting Started with Python-InsightToolkit</title>
		<link>http://paulnovo.us/wrapitktutorial</link>
		<comments>http://paulnovo.us/wrapitktutorial#comments</comments>
		<pubDate>Fri, 07 Mar 2008 16:15:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[This short tutorial will get you started using the <a href="http://www.itk.org/">Insight Toolkit (ITK)</a> with Python in Ubuntu. We will explore basic file reading, image processing, and volume rendering. It is an introduction, the <a href="http://www.itk.org/ItkSoftwareGuide.pdf">ITK Software Guide</a> and <a href="http://docs.python.org/tut/">Python Tutorial</a> contain more in depth information.

]]></description>
			<content:encoded><![CDATA[<p>This short tutorial will get you started using the <a href="http://www.itk.org/">Insight Toolkit (ITK)</a> with Python in Ubuntu. We will explore basic file reading, image processing, and volume rendering. It is an introduction, the <a href="http://www.itk.org/ItkSoftwareGuide.pdf">ITK Software Guide</a> and <a href="http://docs.python.org/tut/">Python Tutorial</a> contain more in depth information.<br />
<span id="more-3"></span></p>
<h3>Basics</h3>
<p>This tutorial requires installation of the packages as described in my previous <a href="http://paulnovo.org/repository">tutorial</a>. Also, a few other packages are needed.</p>
<p><code>sudo apt-get install python-scipy insighttoolkit-examples</code></p>
<p>Insighttoolkit-examples contains images we are going to use in this demo. Uncompress the image first.</p>
<p><code>sudo gunzip /usr/share/doc/insighttoolkit-examples\<br />
/examples/Data/BrainProtonDensity3Slices.raw.gz</code></p>
<p>I prefer to use IPython instead of python for the command line. IPython gives nice features like auto-completion, text coloring, and debugging. It&#8217;s great.</p>
<p><code>sudo apt-get install ipython<br />
ipython</code></p>
<p>Alright, we are ready to start using python. All the following code samples are typed into the IPython command line. Begin by importing the ITK module.</p>
<p><code>import itk</code></p>
<p>ITK is a heavily templated system. As a result, everything requires an image type. For example, a three dimensional image of type unsigned char is defined by</p>
<p><code>image_type = itk.Image[itk.UC, 3]</code></p>
<p>A large combination of image types are available, in fact ITK puts no restriction of data types and image dimensions. Unfortunately, this template system doesn&#8217;t translate into python. I had to compromise and include a sub-set of dimensions and data-types. If you need more functionality, let me know and I can add it to subsequent versions of python-insighttoolkit. The following data-types for 2, 3, and 4 dimensional images are included</p>
<ul>
<li>unsigned char</li>
<li>signed short</li>
<li>unsigned short</li>
<li>RGB unsigned short</li>
<li>float</li>
<li>complex float</li>
<li>vector float</li>
<li>covariant vector float</li>
</ul>
<h3>Reading and Writing Files</h3>
<p>How do we read files? Just enter</p>
<p><code>file_name = '/usr/share/doc/insighttoolkit-examples/\<br />
examples/Data/BrainProtonDensity3Slices.mha'<br />
<br />
reader = itk.ImageFileReader[image_type].New()<br />
reader.SetFileName( file_name )<br />
reader.Update()</code></p>
<p>That&#8217;s it. See how the reader required an image_type. This is slightly restrictive because you need to know the dimensionality and data type of the image before you read it. But not so bad.</p>
<p>These four short lines of code will read TIFF, JPEG, PNG, BMP, DICOM, GIPL, Bio-Rad, LSM, Nifti, Analyze, SDT/SPR (Stimulate), Nearly Raw Raster Data (Nrrd), and VTK images. I don&#8217;t know what half of those file formats are, but someone will find them useful.</p>
<h3>Simple Image Processing Example</h3>
<p>Alright, an image is loaded into memory and ready to go. We&#8217;ll start with a simple example, a median filter.</p>
<p><code>median_filter = itk.MedianImageFilter[image_type, image_type].New()</code></p>
<p>Notice that image_type is used not once, but twice. The first and second image type refer to the input and output type, respectively. One image type definition was necessary for the reader above, because there is only an output image type. Filters require an input and output type.</p>
<p>Filters often expose parameters to adjust their function. For example, setting the radius to 1 specifies the median filter will operate on 3x3x3 neighborhoods.</p>
<p><code>median_filter.SetRadius( 1 )</code></p>
<p>Set the filter input to the output of the reader and update.</p>
<p><code>median_filter.SetInput( reader.GetOutput() )<br />
median_filter.Update()</code></p>
<p>Remember earlier when we called reader.Update(). Well, this isn&#8217;t necessary. When median_filter.Update() is called, ITK will look at its input, and if necessary update it. If you put together a long string of filters, an update on the final filter will cascade all the way back to the beginning and update everything. Of course ITK is even smarter than this and will only rerun filters if its parameters or input has changed.</p>
<p>There are many more operations you can perform on your images, but we need to move on.</p>
<h3>ITK and VTK</h3>
<p>ITK is great for reading, writing, and processing images. However, ITK is not equipped for visualization. This is where the <a href="http://www.vtk.org/">Visualization Toolkit (VTK)</a> comes in. Fortunately, ITK and VTK were created by some of the same people, so the concepts are very similar. In addition, connecting ITK and VTK is trivial with the python-insighttoolkit-extras package.</p>
<p><code>itk_vtk_converter = itk.ImageToVTKImageFilter[image_type].New()<br />
itk_vtk_converter.SetInput( median_filter.GetOutput() )<br />
itk_vtk_converter.Update()</code></p>
<p>Now itk_vtk_converter.GetOutput() returns VTK data. Very handy, especially if you want to render the volume.</p>
<h3>Volume Rendering with VTK</h3>
<p>This section is a quick introduction to volume rendering with VTK. It is low on details because there are better introductions to VTK and python already available.</p>
<p>First we need to import VTK.</p>
<p><code>import vtk</code></p>
<p>A volume mapper determines how image data is rendered to the screen. In this case we use a high quality ray casting mapper. Depending on your video card, you can use the higher performance vtk.vtkVolumeTextureMapper3D() or vtk.vtkVolumeTextureMapper2D() mappers.</p>
<p><code>volume_mapper = vtk.vtkVolumeRayCastMapper()<br />
volume_mapper.SetInput( itk_vtk_converter.GetOutput() )</code></p>
<p>The Ray Cast Mapper requires a composite function.</p>
<p><code>composite_function = vtk.vtkVolumeRayCastCompositeFunction()<br />
volume_mapper.SetVolumeRayCastFunction( composite_function )</code></p>
<p>Our input image is 8 bit data with values from 0 to 255. A mapping is required between these values and the displayed color. For instance, the following code will map the image intensity to the blue channel. This is a linear function; 0 will map to black (0.0, 0.0, 0.0) and 255 will map to solid blue (0.0, 0.0, 1.0). Everything in between will be a linear interpolation between the two end points, i.e. 127 will map to dark blue (0.0, 0.0, 0.5).</p>
<p><code>color_transfer_func = vtk.vtkColorTransferFunction()<br />
color_transfer_func.AddRGBPoint( 0, 0.0, 0.0, 0.0 )<br />
color_transfer_func.AddRGBPoint( 255, 0.0, 0.0, 1.0 )</code></p>
<p>Each voxel in the input image must also map to opacity. The following maps image intensities of 0 to completely transparent (0.0), and 255 to completely opaque (1.0). Again, values between 0 and 1 are interpolated.</p>
<p><code>opacity_transfer_func = vtk.vtkPiecewiseFunction()<br />
opacity_transfer_func.AddPoint( 0, 0.0 )<br />
opacity_transfer_func.AddPoint( 255, 1.0 )</code></p>
<p>Encapsulate the above properties in a vtkVolumeProperty.</p>
<p><code>volume_properties = vtk.vtkVolumeProperty()<br />
volume_properties.SetColor( color_transfer_func )<br />
volume_properties.SetScalarOpacity( opacity_transfer_func )</code></p>
<p>If you are familiar with VTK, a VTK volume is similar to a VTK actor. It encapsulates the data, properties, and rendering method for one &#8216;object&#8217; in the scene.</p>
<p><code>volume = vtk.vtkVolume()<br />
volume.SetMapper( volume_mapper )<br />
volume.SetProperty( volume_properties )</code></p>
<p>Now lets create a few objects used for rendering.</p>
<p><code>renderer = vtk.vtkRenderer()<br />
render_window = vtk.vtkRenderWindow()<br />
window_interactor = vtk.vtkRenderWindowInteractor()<br />
</code></p>
<p>The renderer handles the volume rendering, the render window is where the rendered volume will appear, and the window interactor handles user input to adjust the viewpoint (zoom, rotate, move, etc). Hook &#8216;em up, and add our volume.</p>
<p><code>render_window.AddRenderer( renderer )<br />
window_interactor.SetRenderWindow( render_window )<br />
renderer.AddVolume( volume )</code></p>
<p>Just render the scene and start the window interactor so you can rotate the volume with your mouse.</p>
<p><code>render_window.Render()<br />
window_interactor.Start()</code></p>
<p>To stop the interactor hit &#8216;q&#8217;.</p>
<h3>Numpy and ITK</h3>
<p>Working with images with ITK is great, but when working in python, you want all the functionality of python. Fortunately, converting ITK images to python arrays is simple with the python-insighttoolkit-extras package.</p>
<p><code>itk_py_converter = itk.PyBuffer[image_type]<br />
image_array = itk_py_converter.GetArrayFromImage( reader.GetOutput() )</code></p>
<p>How about converting a 10x10x10 python array to an ITK image.</p>
<p><code>import scipy<br />
another_image_array = scipy.zeros( (10,10,10) )<br />
itk_image = itk_py_converter.GetImageFromArray( another_image_array.tolist() )</code></p>
<p>Does it get any easier?</p>
]]></content:encoded>
			<wfw:commentRss>http://paulnovo.us/wrapitktutorial/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>

