Example a/embedded_texture: A texture deformed as material points in a mesh.

deform an image which matches the initial mesh, treating the image data as material points within the mesh.

Screenshot of example a/embedded_texture


The comfile run by this example is as follows:

#Warping medical images using finite element models.
#Author: Vijay Rajagopal with help from Shane Blackett
#
#---------------------------------------------------------------------------------------------------------------------
#This example was created with breast modelling in mind. The breast modelling group wants to be able to create a
# patient-specific finite element model of the breast and predict breast deformation. For instance, we want to predict
# the shape of the breast when a person changes position from prone (on their stomach in an MR machine) to supine (on
# their back for ultrasound imaging). We would create a finite element model of the breast using the prone images, and
# then predict the shape in the supine position. 
#
#In order to measure the accuracy of our modelling techniques, we want to embed a medical image from the prone position
# MR image dataset into the FE model, then warp the image and create a synthetic image in the supine position. We would
# then use cross-correlation or other techniques to measure the error between the synthetic image and an actual supine
# MR image obtained from the patient.
#
#This com file was created to illustrate this warping technique. We obtained images of the breast in a neutrally buoyant
# configuration by immersing the breast in water. Then we created a model from these images and then assuming the breast
# to be homogeneous and isotropic with a neo-Hookean material type we simulated the prone configuration of the breast
# using gravity loading conditions. We warped a neutral buoyancy image to the simulated prone configuration.
#---------------------------------------------------------------------------------------------------------------------

# define the quality of graphics within finite elements; linear in linear elements, 8*8*8 in non-linear
# this can be edited in the scene editor.
gfx define tessellation default minimum_divisions "1" refinement_factors "8";

# The neutral buoyancy images are interleaved MR images with 0.68 mm resolution in plane and 2.5 mm resolution out of
# plane. The images have 512x512 pixel dimensions and there are 52 of these images. 
# In this example, we wanted to warp image slice number 21 from the neutral buoyancy image dataset.
#
#
# load neutral buoyancy image 21's exnode and exelem file that is used to do digitisation.
gfx read node $example/neutralImage21.exnode
gfx read elem $example/neutralImage21.exelem

#just a command to clear any default graphics
gfx modify g_element "/" general clear;
gfx modify g_element neutralImage21 general clear;

#create a texture from the dicom image "neutralImage21.dcm" that will show up on screen.
#Note that the texture width and height is 1.0. This means that the texture in memory right now
# is of unit square dimensions.
gfx create texture "breast_neutralImage21" image "$example/neutralImage21.dcm" width 1.0 height 1.0 decal


# The following command below transforms the neutralImage21 into alignment with the breast model we created.
# This transformation isn't something that you would worry about usually...its just specific to us at this time.
#gfx set transform name neutralImage21 -0.9902681 -0.1391731 0 0 0.1391731 -0.9902681 0 0 0 0 1 0 11 -16 0 1
# since groups can no longer have graphical transformations, we change this to define the transformed_coordinates
# via a projection field:
gfx define field transformation_matrix constant -0.9902681 0.1391731 0 11 -0.1391731 -0.9902681 0 -16 0 0 1 0 0 0 0 1;
gfx define field transformed_coordinates projection field coordinates projection_matrix transformation_matrix

# We now create a material type that uses the texture we have just created.
# You can make sure that black portions of a texture are removed by inserting 0 in the if bracket below. But, this
# didn't help for the image we had, so we just created a material without modifying the texture.
# Note that in this case we are using the finite element coordinate system as the texture coordinates. These texture
# coordinates provide a mapping between the texture loaded in memory (unit square dimensions remember) and the geometry
# we want to fill with the texture, the neutralImage21 element. The neutralImage21 element is the physical space we want
# to fill with the texture. The physical space is 350 mm x 350 mm (0.68 mm times 512 pixels). The texture in memory is
# 1mm x 1mm. The xi-coordinate system provides a great way to map from the texture to the physical object. CMGUI wants 
# to figure out where to look in the texture to pick an intensity from and fill a specific spot on the physical object. 
# The texture coordinates (in this case xi coordinates) give the rule that the program should use. 

if(1) #normal texture
{
    gfx create material "breast_neutralImage21"  texture "breast_neutralImage21"
    gfx modify g_element neutralImage21 surfaces coordinate transformed_coordinates material "breast_neutralImage21" texture_coordinates xi
    gfx modify g_element neutralImage21 lines coordinate transformed_coordinates material default
} else {
    # remove the black portion of the textures
    gfx define field "breast_neutralImage21" sample_texture coordinates xi texture "breast_neutralImage21";
    gfx create texture "breast_neutralImage21_noblack" mod line width 1 height 1 depth 0 specify_width 512 specify_heigh 512 specify_format rgba evaluate_image element_group neutralImage21 field "breast_neutralImage21" spectrum noblack texture_coord xi;
    gfx create material "breast_neutralImage21" texture "breast_neutralImage21_noblack";
    gfx modify g_element neutralImage21 surfaces coordinate transformed_coordinates material "breast_neutralImage21" texture_coord xi
}

#create a window and set the view....this is once again specific to us...you might want to change the view 
# to look at the image and model from a different direction
gfx create window
gfx modify window 1 view parallel eye_point -43.3558 -296.283 1268.61 interest_point -91.3688 -208.321 48.7427 up_vector -0.208369 0.974895 0.0784991 view_angle 9.73314 near_clipping_plane 12.2397 far_clipping_plane 4374.06 relative_viewport ndc_placement -1 1 2 2 viewport_coordinates 0 0 1 1;
gfx modify window 1 set transform_tool current_pane 1 std_view_angle 40 normal_lines no_antialias depth_of_field 0.0 fast_transparency blend_normal;
# give the window a stronger background colour so the dark textures stand out.
gfx modify window 1 background colour 0 0.4 0.7

#Now we load in the breast model we created from the neutral buoyancy image dataset and align with the image slice.
$neutralbreast = "$example/breast_MOD211_refin"
gfx read node ${neutralbreast}.exnode
gfx read elem ${neutralbreast}.exelem

#NOTE: WE HAVE NOT EMBEDDED THE BREAST IMAGE TEXTURE INTO THE MODEL! WE HAVE ONLY EMBEDDED THE IMAGE TEXTURE INTO
# THE 2-D PLANE WE CREATED. YOU CAN SEE THIS BY OPENING THE SCENE EDITOR AND UNCHECKING THE neutralImage21 GRAPHICS. 

#Now we start loading in the deformed configurations of the breast. We have obtained these using cmiss after each
# "fem solv inc 0.1" to obtain intermediate configurations of the breast till the final increment of 0.1 gives
# the predicted prone shape. 

#load first increment with time 1. 
$pronebreast  = "$example/def_neutral_1"
gfx read node ${pronebreast}.exnode time 1;
gfx read elem ${pronebreast}.exelem
gfx modify g_element def_neutral general clear;
gfx modify g_element def_neutral lines coordinate deformed select_on material default selected_material default_selected;
#
#load the rest of the breast meshes (of the different stages of the deformation)
for ($i = 2 ; $i < 11 ; $i++)
{
 gfx read node $example/def_neutral_${i}.exnode time $i;
}

#We now embed the neutral image texture in the deforming breast. To do this, we need to provide a mapping
#again between the texture and the breast model. Remember that the mapping texture coordinates for the plane
# were simply xi coordinates. In this case, the mapping is first, the transformation that we imposed previously
# on the 2d plane so that the texture is aligned with the breast mesh. Then, we need a scaling as the texture is
# in memory as a unit square. 

#Add on the offsets for the image - this is the translation that we made to the 2D image before - "gfx set transform
# name neutralImage21 -0.9902681 -0.1391731 0 0 0.1391731 -0.9902681 0 0 0 0 1 0 11 -16 0 1".
#The command below only deals with the translation
gfx define field to_image_A offset field coordinates offset -11 16 0

#we then need to store the rotations that were made in that transformation in a matrix form
gfx define field matrix constant -0.9902681 -0.1391731 0 0.1391731 -0.9902681 0 0 0 1;
#
#We calculate the inverse of this matrix and multiply with the translation component (to_image_A)
#to give the transformation matrix to align the texture to the breast mesh
gfx define field to_image_B matrix_multiply number_of_rows 3 fields matrix to_image_A;
# we then scale this transformation for the correct mapping between breast coordinates and texture coordinates.
# note that 350 is the physical dimensions of the image plane, we don't scale in z (0.0) because we are only
# dealing with one plane. If we deal with 3D textures, then we will have to sort out the scaling in z too.
gfx define field to_image_C scale field to_image_B scale_factors 1.0/350.0 1.0/350.0 0.0;

#So, to_image_C is the mapping between the physical breast and the unit square texture in memory. We use this matrix
# as the texture coordinates. We create an iso-surface on the breast mesh at z=50. This is the z-coordinate of the
# 2d plane that we created earlier. This iso-surface inside the mesh is now coloured with the neutral image texture.
# this command below now embeds the texture into the mesh. 
# The coordinates used are for the geometry are specified above
# in the line "gfx modify g_element def_neutral lines/etc. coordinate deformed ..."
# so they are updated by the deforming geometry,
# however the calculation of where the isosurface is placed withing the model uses the 
# initial field "coordinates", specifically coordinates.z equals 50, so it draws the initial
# coordinates.z equals 50 surface at the location of the now deformed coordinates.
# Similaraly the texture coordinates for displaying the image are based on the initial
# undeformed field "coordinates" and so stay materially in the same place.
gfx modify g_element def_neutral iso_surfaces coordinate deformed iso_scalar coordinates.z iso_values 50 use_elements select_on material breast_neutralImage21 texture_coordinates to_image_C selected_material default_selected render_shaded;

#Now on the graphics window, scroll through the time bar and you will see the warping image.
#job done.


Files used by this example are:

Name                        Modified     Size

embedded_texture.com 17-Mar-2014 10k COPYRIGHT 17-Mar-2014 504 breast_MOD211_refin.exelem 17-Mar-2014 278k breast_MOD211_refin.exnode 17-Mar-2014 151k def_neutral_1.exelem 17-Mar-2014 279k def_neutral_1.exnode 17-Mar-2014 157k def_neutral_10.exnode 17-Mar-2014 157k def_neutral_2.exnode 17-Mar-2014 157k def_neutral_3.exnode 17-Mar-2014 157k def_neutral_4.exnode 17-Mar-2014 157k def_neutral_5.exnode 17-Mar-2014 157k def_neutral_6.exnode 17-Mar-2014 157k def_neutral_7.exnode 17-Mar-2014 157k def_neutral_8.exnode 17-Mar-2014 157k def_neutral_80.exnode 17-Mar-2014 157k def_neutral_9.exnode 17-Mar-2014 157k def_neutral_90.exnode 17-Mar-2014 157k def_neutral_95.exnode 17-Mar-2014 157k def_neutral_prone.exnode 17-Mar-2014 157k def_neutral_supine.exnode 17-Mar-2014 157k neutralImage21.dcm 17-Mar-2014 588k neutralImage21.exelem 17-Mar-2014 1.8k neutralImage21.exnode 17-Mar-2014 644

Download the entire example:

Name                                Modified     Size

examples_a_embedded_texture.tar.gz 09-Mar-2016 2.5M

Testing status by version:

StatusTestedReal time (s)
i686-linux
cmgui-wxFailureSun Mar 6 00:14:07 20163
last breakTue Feb 24 03:11:00 20152
cmgui-wx-debugFailureSun Mar 6 00:09:51 20163
last breakTue Feb 24 00:02:00 20153
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:15:31 20162
last breakTue Feb 24 03:16:00 20153
cmgui-wx-debug-valgrindFailureSun Mar 6 01:13:22 201651
last breakSun Mar 6 01:12:00 201651
x86_64-linux
cmgui-wxFailureSun Mar 6 00:01:30 20161
last breakSun Mar 6 00:01:00 20161
cmgui-wx-debugFailureSun Mar 6 00:01:30 20161
last breakSun Mar 6 00:01:00 20161
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:01:30 20161
last breakSun Mar 6 00:01:00 20161
cmgui-wx-debug-valgrindFailureSun Mar 6 00:02:26 20169
last breakSun Mar 6 00:02:00 20169
cmgui-wx-gcc-cad-debug-valgrindSuccessThu Jan 7 00:02:08 20166

Testing status by file:


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

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


CMISS Help / Examples / a / embedded_texture