deform an image which matches the initial mesh, treating the image data as material points within the mesh.
#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.
Name Modified Size
embedded_texture.com 20-Apr-2012 10k COPYRIGHT 19-Apr-2012 504 breast_MOD211_refin.exelem 20-Apr-2012 278k breast_MOD211_refin.exnode 20-Apr-2012 151k def_neutral_1.exelem 20-Apr-2012 279k def_neutral_1.exnode 20-Apr-2012 157k def_neutral_10.exnode 20-Apr-2012 157k def_neutral_2.exnode 20-Apr-2012 157k def_neutral_3.exnode 20-Apr-2012 157k def_neutral_4.exnode 20-Apr-2012 157k def_neutral_5.exnode 20-Apr-2012 157k def_neutral_6.exnode 20-Apr-2012 157k def_neutral_7.exnode 20-Apr-2012 157k def_neutral_8.exnode 20-Apr-2012 157k def_neutral_80.exnode 20-Apr-2012 157k def_neutral_9.exnode 20-Apr-2012 157k def_neutral_90.exnode 20-Apr-2012 157k def_neutral_95.exnode 20-Apr-2012 157k def_neutral_prone.exnode 20-Apr-2012 157k def_neutral_supine.exnode 20-Apr-2012 157k neutralImage21.dcm 20-Apr-2012 588k neutralImage21.exelem 20-Apr-2012 1.8k neutralImage21.exnode 20-Apr-2012 644
Name Modified Size
examples_a_backup_embedded_texture.tar.gz 12-Aug-2014 2.5M
Status | Tested | Real time (s) | |
i686-linux | |||
cmgui-wx | Success | Sun Mar 6 00:10:36 2016 | 3 |
cmgui-wx-debug | Success | Sun Mar 6 00:10:37 2016 | 2 |
cmgui-wx-debug-memorycheck | Success | Sun Mar 6 00:16:30 2016 | 4 |
cmgui-wx-debug-valgrind | Failure | Sun Mar 6 01:11:41 2016 | 51 |
last break | Sun Mar 6 01:10:00 2016 | 51 | |
last success | Tue Feb 10 00:58:00 2015 | 52 | |
x86_64-linux | |||
cmgui-wx | Failure | Sun Mar 6 00:01:37 2016 | 0 |
last break | Sun Mar 6 00:01:00 2016 | 0 | |
last success | Wed Jun 3 00:06:00 2015 | 1 | |
cmgui-wx-debug | Failure | Sun Mar 6 00:01:37 2016 | 0 |
last break | Sun Mar 6 00:01:00 2016 | 0 | |
last success | Wed Jun 3 00:05:00 2015 | 1 | |
cmgui-wx-debug-memorycheck | Failure | Sun Mar 6 00:01:37 2016 | 0 |
last break | Sun Mar 6 00:01:00 2016 | 0 | |
last success | Wed Jun 3 00:05:00 2015 | 1 | |
cmgui-wx-debug-valgrind | Failure | Sun Mar 6 00:02:37 2016 | 10 |
last break | Sun Mar 6 00:02:00 2016 | 10 | |
last success | Wed Jun 3 00:33:00 2015 | 38 | |
cmgui-wx-gcc-cad-debug-valgrind | Success | Thu Jan 7 00:02:14 2016 | 6 |
x86_64-linux | |||
139 | cmgui-wx: | error exit status 139. | |
139 | cmgui-wx-debug: | error exit status 139. | |
139 | cmgui-wx-debug-memorycheck: | error exit status 139. | |
139 | cmgui-wx-debug-valgrind: | error exit status 139. |
i686-linux | |||
Success | cmgui-wx: | diff test: no differences with generic answer. | |
Success | cmgui-wx-debug: | diff test: no differences with generic answer. | |
Success | cmgui-wx-debug-memorycheck: | diff test: no differences with generic answer. | |
Failure | cmgui-wx-debug-valgrind: | diff test: differences with generic answer; Test output. | |
x86_64-linux | |||
Failure | cmgui-wx: | diff test: differences with generic answer; Test output. | |
Failure | cmgui-wx-debug: | diff test: differences with generic answer; Test output. | |
Failure | cmgui-wx-debug-memorycheck: | diff test: differences with generic answer; Test output. | |
Failure | cmgui-wx-debug-valgrind: | diff test: differences with generic answer; Test output. |
Html last generated: Sun Mar 6 05:50:56 2016
Input last modified: Fri Apr 20 15:58:16 2012