Example a/volume_texture: Visualisation and segmentation of 3-D images of the foot

Reads a series of images from the Visible Human Dataset into one large 3-dimensional texture. This is viewed on slice planes of constant x, y or z coordinate. Scalar fields based on the colours in the texture are established to distinguish regions of muscle, bone and the exterior skin of the foot and isosurfaces are used to show the boundaries of these structures.

Note that a fast computer is needed to calculate isosurfaces at high resolution and a high-end graphics card with lots of texture memory and capable of hardware 3-D textures is required to show the 3-D texture on slice planes.

Note that all images used are copyright to and obtained under license from The Visible Human Project.

VHP Home Page

Screenshot of example a/volume_texture


The comfile run by this example is as follows:

# Visualisation and segmentation of 3-D images of the foot
#
# Reads a series of images from the Visible Human Dataset into one large
# 3-dimensional texture.  This is viewed on slice planes of constant x,
# y or z coordinate.  Scalar fields based on the colours in the texture
# are established to distinguish regions of muscle, bone and the exterior
# skin of the foot and isosurfaces are used to show the boundaries of
# these structures.
#
# Notes:
# - A big & fast computer is needed to calculate isosurfaces at high
#   resolution.
# - A high-end graphics card with lots of texture memory and capable of
#   hardware 3-D textures is required to show the 3-D texture on slice
#   planes.
#
# Note that all images are copyright to and obtained under license
# from the Visible Human Project:
# http://www.nlm.nih.gov/research/visible/visible_human.html
#
# Read in 128 images of 256x400 resolution into 3-D texture 'foot'. These
# are a cropped subset of the Visible Human Dataset containing just the
# left foot. (You might as well use power-of-two resolutions as I have
# since internal storage is padded to the next highest power-of-two.
# Otherwise keep 3-D textures as small as possible for speed!)
# Since this data has one texture-pixel (or texel) per mm, we set the
# physical size of the texture to 256x400x128.
# Note the image file numbers are substituted into the pattern "0000"
# and go from 1860 to 1733 with an increment of -1.
# The compress parameter requests the graphics hardware to compress the texture
# in its representation of the texture allowing the image to be stored in much less
# memory than uncompressed.
# It takes a few seconds to read in this much image data.
gfx create texture foot width 256 height 400 depth 128 clamp_wrap linear_filter image $example/foot0000.jpg number_pattern "0000" number_series 1860 1733 -1 compress;
#
# Create a material containing the texture that we may select along
# with appropriate texture coordinates, to visualise the 3-D image
# on our graphics.
gfx create material foot texture foot;
#
# Create some more materials to colour parts of the model with.
gfx create material bone ambient 0.7 0.7 0.3 diffuse 0.9 0.9 0.8 emission 0 0 0 specular 0.05 0.05 0.05 alpha 1 shininess 0.1;
gfx create material muscle ambient 0.17 0.06 0.06 diffuse 0.35 0.12 0.12 emission 0 0 0 specular 0.17 0.06 0.06 alpha 1 shininess 0.1;
gfx create material skin ambient 0.8 0.8 0.4 diffuse 0.7 0.29 0.16 emission 0.06 0.05 0.03 specular 0.12 0.12 0.08 alpha 1 shininess 0.1;
gfx create material green ambient 0 1 0 diffuse 0 1 0
gfx cre mat bluey ambient 0 0.25 0.5 diffuse 0 0.4 1 emission 0 0 0 specular 0.5 0.5 0.5 alpha 1 shininess 0.3
#
# Create a grayscale spectrum that may be useful for drawing
# individual components (see exercises at end).
gfx create spectrum grayscale clear overwrite_colour;
gfx modify spectrum grayscale linear range 0 1 extend_above extend_below red colour_range 0 1 ambient diffuse component 1;
gfx modify spectrum grayscale linear range 0 1 extend_above extend_below green colour_range 0 1 ambient diffuse component 1;
gfx modify spectrum grayscale linear range 0 1 extend_above extend_below blue colour_range 0 1 ambient diffuse component 1;
#
# Read in a 256x400x128 mm single-element block to view the texture in.
# These dimensions match the physical size and location of the texture.
# Later we will use the "coordinates" field as texture coordinates.
gfx read nodes $example/texture_block.exnode
gfx read elements $example/texture_block.exelem
#
# Since it is expensive to compute high-res iso-surfaces, a slightly
# smaller mesh that just envelopes the foot is read in.  It contains
# a block of elements that are each exactly 32x32x32 mm in size. The
# corners of each element are offset to lie at exactly the centre of
# a 3-D texel.  Hence, we can subdivide these elements in powers of 2
# up to 32 and get the most accurate isosurfaces for the least effort.
gfx read nodes $example/iso_block.exnode
gfx read elements $example/iso_block.exelem
#
# Define the components of the coordinate field as individual scalar
# fields for defining slice planes.
gfx define field x component coordinates.x;
gfx define field y component coordinates.y;
gfx define field z component coordinates.z;
#
# Define the "tex" field to return the red, green and blue components
# of the texture (each on [0,1]) by looking up the texture at the
# position of the "coordinates" field in any element.
gfx define field tex sample_texture coordinates coordinates field foot minimum 0.0 maximum 1.0;
#
# Extract several scalar quantities from tex, notably its colour
# components which the user may choose to visualise.
gfx define field tex.1 component tex.1;
gfx define field tex.2 component tex.2;
gfx define field tex.3 component tex.3;
gfx define field mag_tex magnitude field tex;
gfx define field tex_avg sum_components field tex weights 0.333 0.334 0.333;
# Black and white scalar weighting of red, green and blue reflects the
# relative brightness of the three components to our eyes.
gfx define field tex_bw sum_components field tex weights 0.3 0.55 0.15;
#
# Draw the 3-D texture on the surfaces x = 128.5 and y = 185.5.  The
# .5 makes the slice in the centre of a row of texels.
gfx modify g_element texture_block general clear circle_discretization 6 default_coordinate coordinates element_discretization "1*1*1" native_discretization none;
gfx modify g_element texture_block lines select_on material default selected_material default_selected;
gfx modify g_element texture_block iso_surfaces iso_scalar x iso_value 128.5 use_elements select_on material foot texture_coordinates coordinates selected_material default_selected render_shaded;
gfx modify g_element texture_block iso_surfaces iso_scalar y iso_value 185.5 use_elements select_on material foot texture_coordinates coordinates selected_material default_selected render_shaded;
#
# Note that by opening the "Scene editor" you are free to choose other
# values of x and y to view the texture on, or even another slice plane by
# changing the iso-scalar field in iso_surfaces of the "texture_block"
# group.
#
# Draw the lines of the iso_block mesh.
gfx modify g_element iso_block general clear circle_discretization 6 default_coordinate coordinates element_discretization "16*16*16" native_discretization none;
gfx modify g_element iso_block lines select_on material green selected_material default_selected;
#
if (!$TESTING)
{
  # Create a 3d window
  gfx create window 1
  gfx mod win 1 view perspective
  gfx mod win 1 image view_all
}
#
# Visualise the bones (and some of the fat since they are very similar in
# colour). We do this by generating a scalar field "mag_non_bone" which
# measures the distance in colourspace from an average bone colour of
# Red, Green, Blue = 0.9, 0.75, 0.6.
# This takes a long time to calculate so they are made invisible by default;
# you will have to check their visibility box in the scene editor to see them.
gfx define field non_bone offset field tex offsets -0.9 -0.75 -0.6;
gfx define field mag_non_bone magnitude field non_bone;
gfx modify g_element iso_block iso_surfaces iso_scalar mag_non_bone iso_value 0.2 use_elements select_on material bone texture_coordinates coordinates selected_material default_selected render_shaded invisible;
#
# Visualise the muscles (and some blood vessels) in a similar fashion
# using field "mag_non_muscle" which measures the distance the colour
# is from an average muscle tone.
# This also takes a little while to calculate.
gfx define field non_muscle coordinate_system rectangular_cartesian offset field tex offsets -0.35 -0.12 -0.12;
gfx define field mag_non_muscle coordinate_system rectangular_cartesian magnitude field non_muscle;
gfx modify g_element iso_block iso_surfaces iso_scalar mag_non_muscle iso_value 0.2 use_elements select_on material muscle texture_coordinates coordinates selected_material default_selected render_shaded;
#
# Many combinations of colours adequately differentiate the skin from
# the surrounding blue resin. In the following we promote blue values and
# penalise red and green components. Experimentation gave the value of
# -0.25 which gives a good indication of the skin, although admittedly it
# is slightly outside of it.
gfx define field blue coordinate_system rectangular_cartesian sum_components field tex weights -1 -1 1;
gfx modify g_element iso_block iso_surfaces iso_scalar blue iso_value -0.25 use_elements select_on material skin texture_coordinates coordinates selected_material default_selected render_shaded;
#
# Open the Scene Editor to enable visibility of parts of the image
# to be switched on and off, discretization to be controlled or
# new graphics to be added.
if (!$TESTING)
{
  gfx edit scene;
}
if ($TESTING)
{
  # Turn off all graphics but a lo-res foot skin and export VRML
  gfx modify g_element texture_block general clear circle_discretization 6 default_coordinate coordinates element_discretization "1*1*1" native_discretization none;
  # Use 6*6*6 discretization to test linear filtering with sample_texture
  gfx modify g_element iso_block general clear circle_discretization 6 default_coordinate coordinates element_discretization "6*6*6" native_discretization none;
  gfx modify g_element iso_block iso_surfaces iso_scalar blue iso_value -0.25 use_elements select_on material skin texture_coordinates coordinates selected_material default_selected render_shaded;
  gfx export vrml file foot.wrl
}
#
# Notes & further exercises:
# - There are lots of combinations of colours that will adequately
#   segment many of the features in such 3-D images.  However, subtle
#   changes such as the edges of bones in visible light images and
#   fat are not easy to decipher with such simple methods.
# - If you have the time, try computing the iso-surfaces at 32*32*32
#   resolution to see the best quality possible from these images.
# - On any of the above graphics you may choose the "foot" material
#   to colour the iso-surfaces.  For this to look right you will
#   have to allow proper lighting of the foot texture with the
#   command "gfx modify texture foot modulate". The result tells
#   how well you have segmented and can help remove visual clutter.
#   The muscle layers are particularly good in this example,
#   being slightly redish-brown.
# - One way to help find appropriate scalars and values of scalars
#   for segmentation is to make hi-res slice planes with the same
#   resolution as the texture in the plane.  Choose your scalar
#   field as the data field for the iso-surface and play around
#   with the spectrums to see what threshold will work for you.
# - The original Visible Human dataset is twice the resolution in
#   each direction as the images used here, enabling even more
#   anatomical detail to be gained.
# - Enjoy!

Files used by this example are:

Name                        Modified     Size

example_volume_texture.com 17-Mar-2014 10k COPYRIGHT 17-Mar-2014 504 foot1733.jpg 17-Mar-2014 39k foot1734.jpg 17-Mar-2014 39k foot1735.jpg 17-Mar-2014 38k foot1736.jpg 17-Mar-2014 37k foot1737.jpg 17-Mar-2014 38k foot1738.jpg 17-Mar-2014 37k foot1739.jpg 17-Mar-2014 38k foot1740.jpg 17-Mar-2014 37k foot1741.jpg 17-Mar-2014 32k foot1742.jpg 17-Mar-2014 35k foot1743.jpg 17-Mar-2014 35k foot1744.jpg 17-Mar-2014 34k foot1745.jpg 17-Mar-2014 35k foot1746.jpg 17-Mar-2014 37k foot1747.jpg 17-Mar-2014 38k foot1748.jpg 17-Mar-2014 41k foot1749.jpg 17-Mar-2014 42k foot1750.jpg 17-Mar-2014 45k foot1751.jpg 17-Mar-2014 47k foot1752.jpg 17-Mar-2014 49k foot1753.jpg 17-Mar-2014 52k foot1754.jpg 17-Mar-2014 54k foot1755.jpg 17-Mar-2014 58k foot1756.jpg 17-Mar-2014 51k foot1757.jpg 17-Mar-2014 52k foot1758.jpg 17-Mar-2014 51k foot1759.jpg 17-Mar-2014 50k foot1760.jpg 17-Mar-2014 50k foot1761.jpg 17-Mar-2014 51k foot1762.jpg 17-Mar-2014 54k foot1763.jpg 17-Mar-2014 53k foot1764.jpg 17-Mar-2014 52k foot1765.jpg 17-Mar-2014 52k foot1766.jpg 17-Mar-2014 53k foot1767.jpg 17-Mar-2014 54k foot1768.jpg 17-Mar-2014 55k foot1769.jpg 17-Mar-2014 52k foot1770.jpg 17-Mar-2014 52k foot1771.jpg 17-Mar-2014 52k foot1772.jpg 17-Mar-2014 53k foot1773.jpg 17-Mar-2014 52k foot1774.jpg 17-Mar-2014 51k foot1775.jpg 17-Mar-2014 49k foot1776.jpg 17-Mar-2014 51k foot1777.jpg 17-Mar-2014 50k foot1778.jpg 17-Mar-2014 50k foot1779.jpg 17-Mar-2014 49k foot1780.jpg 17-Mar-2014 49k foot1781.jpg 17-Mar-2014 48k foot1782.jpg 17-Mar-2014 48k foot1783.jpg 17-Mar-2014 48k foot1784.jpg 17-Mar-2014 48k foot1785.jpg 17-Mar-2014 47k foot1786.jpg 17-Mar-2014 48k foot1787.jpg 17-Mar-2014 48k foot1788.jpg 17-Mar-2014 47k foot1789.jpg 17-Mar-2014 47k foot1790.jpg 17-Mar-2014 47k foot1791.jpg 17-Mar-2014 47k foot1792.jpg 17-Mar-2014 47k foot1793.jpg 17-Mar-2014 46k foot1794.jpg 17-Mar-2014 46k foot1795.jpg 17-Mar-2014 45k foot1796.jpg 17-Mar-2014 45k foot1797.jpg 17-Mar-2014 44k foot1798.jpg 17-Mar-2014 44k foot1799.jpg 17-Mar-2014 43k foot1800.jpg 17-Mar-2014 43k foot1801.jpg 17-Mar-2014 43k foot1802.jpg 17-Mar-2014 43k foot1803.jpg 17-Mar-2014 42k foot1804.jpg 17-Mar-2014 43k foot1805.jpg 17-Mar-2014 43k foot1806.jpg 17-Mar-2014 43k foot1807.jpg 17-Mar-2014 43k foot1808.jpg 17-Mar-2014 43k foot1809.jpg 17-Mar-2014 43k foot1810.jpg 17-Mar-2014 43k foot1811.jpg 17-Mar-2014 42k foot1812.jpg 17-Mar-2014 42k foot1813.jpg 17-Mar-2014 42k foot1814.jpg 17-Mar-2014 42k foot1815.jpg 17-Mar-2014 42k foot1816.jpg 17-Mar-2014 42k foot1817.jpg 17-Mar-2014 42k foot1818.jpg 17-Mar-2014 41k foot1819.jpg 17-Mar-2014 42k foot1820.jpg 17-Mar-2014 42k foot1821.jpg 17-Mar-2014 43k foot1822.jpg 17-Mar-2014 44k foot1823.jpg 17-Mar-2014 46k foot1824.jpg 17-Mar-2014 49k foot1825.jpg 17-Mar-2014 52k foot1826.jpg 17-Mar-2014 55k foot1827.jpg 17-Mar-2014 55k foot1828.jpg 17-Mar-2014 48k foot1829.jpg 17-Mar-2014 45k foot1830.jpg 17-Mar-2014 44k foot1831.jpg 17-Mar-2014 35k foot1832.jpg 17-Mar-2014 46k foot1833.jpg 17-Mar-2014 45k foot1834.jpg 17-Mar-2014 44k foot1835.jpg 17-Mar-2014 45k foot1836.jpg 17-Mar-2014 45k foot1837.jpg 17-Mar-2014 44k foot1838.jpg 17-Mar-2014 44k foot1839.jpg 17-Mar-2014 43k foot1840.jpg 17-Mar-2014 42k foot1841.jpg 17-Mar-2014 35k foot1842.jpg 17-Mar-2014 32k foot1843.jpg 17-Mar-2014 31k foot1844.jpg 17-Mar-2014 31k foot1845.jpg 17-Mar-2014 31k foot1846.jpg 17-Mar-2014 29k foot1847.jpg 17-Mar-2014 29k foot1848.jpg 17-Mar-2014 30k foot1849.jpg 17-Mar-2014 31k foot1850.jpg 17-Mar-2014 31k foot1851.jpg 17-Mar-2014 31k foot1852.jpg 17-Mar-2014 32k foot1853.jpg 17-Mar-2014 30k foot1854.jpg 17-Mar-2014 28k foot1855.jpg 17-Mar-2014 23k foot1856.jpg 17-Mar-2014 23k foot1857.jpg 17-Mar-2014 21k foot1858.jpg 17-Mar-2014 21k foot1859.jpg 17-Mar-2014 20k foot1860.jpg 17-Mar-2014 20k iso_block.exelem 17-Mar-2014 128k iso_block.exnode 17-Mar-2014 10k texture_block.exelem 17-Mar-2014 3.5k texture_block.exnode 17-Mar-2014 424

Download the entire example:

Name                              Modified     Size

examples_a_volume_texture.tar.gz 09-Mar-2016 12M

Testing status by version:

StatusTestedReal time (s)
i686-linux
cmgui-wxFailureSun Mar 6 00:14:21 20163
last breakThu Sep 11 00:07:00 20143
cmgui-wx-debugFailureSun Mar 6 00:13:40 20163
last breakThu Sep 11 00:09:00 20142
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:11:40 20162
last breakThu Sep 11 00:07:00 20142
cmgui-wx-debug-valgrindFailureSun Mar 6 01:22:58 201684
last breakTue Feb 24 00:34:00 201592
x86_64-linux
cmgui-wxFailureSun Mar 6 00:01:54 20161
last breakThu Sep 11 00:04:00 20142
cmgui-wx-debugFailureSun Mar 6 00:01:54 20162
last breakThu Sep 11 00:04:00 20143
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:01:54 20162
last breakThu Sep 11 00:04:00 20143
cmgui-wx-debug-valgrindFailureSun Mar 6 00:07:51 201680
last breakSun Mar 6 00:06:00 201680
cmgui-wx-gcc-cad-debug-valgrindSuccessThu Jan 7 00:07:36 201651

Testing status by file:


Html last generated: Wed Mar 9 16:03:01 2016

Input last modified: Wed Mar 9 15:49:42 2016


CMISS Help / Examples / a / volume_texture