Skip to content

neurolabusc/nii2mesh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About

This tool converts a NIfTI 3D voxel image to a triangulated mesh. It can save meshes in in the GIfTI (.gii), mz3, obj, ply, FreeSurfer (.pial), stl, vtk, formats. You can use dcm2niix to convert DICOM images to NIfTI. The software is written in pure C (rather than C++).

nii2mesh is a minimal tool. niimath includes all the features of nii2mesh along with many voxel-based image processing features. Users are recommended to use niimath, while nii2mesh is ideal for developers who want to use the core code in other projects.

Live Demo

  • The live demo web page allows you to use nii2mesh without installing any software on your computer.

Compiling

For Unix computers (Linux, macOS), you can build the executable using the make command:

git clone https://github.com/neurolabusc/nii2mesh
cd nii2mesh/src
make

You can also compile as WebAssembly see this live demo.

git clone https://github.com/neurolabusc/nii2mesh
cd nii2mesh/src
make wasm

Usage

Here are the instructions for using this tool (you can also run the executable without any arguments to see this help):

Converts a NIfTI voxelwise volume to triangulated mesh.
Usage: ./nii2mesh inputNIfTI [options] outputMesh
Options
    -a s    atlas text file (e.g. '-a D99_v2.0_labels_semicolon.txt')
    -b v    bubble fill (0=bubbles included, 1=bubbles filled, default 0)
    -i v    isosurface intensity (d=dark, m=mid, b=bright, number for custom, default medium)
    -l v    only keep largest cluster (0=all, 1=largest, default 1)
    -o v    Original marching cubes (0=Improved Lewiner, 1=Original, default 0)
    -p v    pre-smoothing (0=skip, 1=smooth, default 1)
    -r v    reduction factor (default 0.25)
    -q v    quality (0=fast, 1= balanced, 2=best, default 1)
    -s v    post-smoothing iterations (default 0)
    -v v    verbose (0=silent, 1=verbose, default 0)
mesh extension sets format (.gii, .mz3, .obj, .ply, .pial, .stl, .vtk)
Example: './nii2mesh voxels.nii mesh.obj'
Example: './nii2mesh bet.nii.gz -i 22 myOutput.obj'
Example: './nii2mesh bet.nii.gz -i b bright.obj'
Example: './nii2mesh img.nii -v 1 out.ply'
Example: './nii2mesh img.nii -p 0 -r 1 large.ply'
Example: './nii2mesh img.nii -r 0.1 small.gii'

Processing Steps

The program provides several options to allow you to fine tune the conversion. To illustrate these options, we will show how they influence the included image bet.nii.gz. You can use MRIcroGL to view this voxel-based data. The raw data looks like this:

MRIcroGL view of NIfTI image

Specifically, it is a T1 image that has been brain extracted (we have removed the scalp). Note that there is a hollow ball near the left frontal cortex and a solid ball near the right posterior lobe.

In the images below, we will view the resulting meshes using Surfice. Another good tool for viewing meshes is MeshLab.

  1. You can choose to pre-smooth your data (-p 1) or not (-p 0) prior to making a mesh. This emulates a Gaussian blur with a narrow kernel, which tends to attenuate noise in the image.
nii2mesh bet.nii.gz -p 0  p0.ply
nii2mesh bet.nii.gz -p 1 p1.ply

Influence of p 0 vs p 1

  1. You can choose to only retain the largest connected object (-l 1) or keep all objects (-l 0). The image below shows that the balls and other small blobs do not appear when -l 1 is selected.
nii2mesh bet.nii.gz -l 0 l0.ply
nii2mesh bet.nii.gz -l 1 l1.ply

Influence of l 0 vs l 1

  1. You can choose to fill bubbles (-b 1) or retain bubbles (-b 0). Filling holes will create solid objects if you print them. If you look at the cut-away views below you will notice that this option determines whether the ventricles inside the brain and the interior sphere exist in the mesh file.
nii2mesh bet.nii.gz -i 122 -l 0 -b 0 b0.ply
nii2mesh bet.nii.gz -i 122 -l 0 -b 1 b1.ply

Influence of b 0 vs b 1

  1. You can choose an isosurface value. This is the voxel brightness used to distinguish air from tissue. If you click on the voxel data with MRIcroGL, you will note that the brightness of the selected voxel location is shown in the title bar, allowing you to estimate a good boundary. The options -i d, -i m, -i b choose dark, medium and bright values based on multi-Otsu thresholding. You can also specify an explicit numeric value, for example -i 128. If you do not specify a value, the program will default to the medium intensity.
nii2mesh bet.nii.gz -i d d.ply
nii2mesh bet.nii.gz -i m m.ply
nii2mesh bet.nii.gz -i b b.ply
nii2mesh bet.nii.gz -i 122 122.ply

Influence of isosurface adjustment

  1. The -s option allows you to specify the number of iterations for the smoothing of your mesh. Unlike the pre-smooth, the smooth is applied after the voxels are converted into a triangular mesh. This effect is much more subtle than the pre-smooth. This option is best suited for low resolution, block images. It is worth noting that the reduction factor also will tend to smooth images, attenuating small variations. Therefore, to illustrate the effect we are turning off both the pre-smoothing and the mesh reduction.
nii2mesh bet.nii.gz -i 120 -r 1 -p 0 -s 0 s0.ply
nii2mesh bet.nii.gz -i 120 -r 1 -p 0 -s 100 s100.ply

Influence of smoothing

  1. The reduction factor allows you to simplify the mesh, resulting in a much smaller file size and faster rendering on slow hardware. This stage uses Sven Forstmann's simplification method which is adaptive, using smaller triangles in regions of curvature and large triangles in flat regions. Choosing a value of -r 0.15 will eliminate 85% of the triangles. Notice how similar the top row appears, while the bottom row illustrates a dramatic reduction in complexity.
nii2mesh bet.nii.gz -r 0.5 r50.ply
nii2mesh bet.nii.gz -r 0.15 r15.ply 

Influence of r 0.5 vs r 0.15

Atlases

Atlases identify different discrete brain regions, such as Brodmann Area. Most NIfTI atlases store each voxel intensity as an integer, identifying the region. Here, we consider this example dataset. The nii2mesh -a 1 argument is similar to the AFNI isosurface -isorois option, to create an isosurface for each unique value in the input volume.

The simplest usage would be:

nii2mesh D99_atlas_v2.0_right.nii.gz -a 1 D99.gii

Note that the presmooth may slightly erode very small or thin regions. If this is undesirable, you could turn off the pre-smoothing and consider applying a small amount of smoothing after the mesh is created:

nii2mesh D99_atlas_v2.0_right.nii.gz -p 0 -s 10 -a 1 D99s10roi.mz3

Alternatively, you can provide the file name for a semicolon delimited text file. The format should have the index number in the first column, and the nickname in the second column. Consider the provided example file D99_v2.0_labels_semicolon.txt:

1;pu;putamen;Basal ganglia;Striatum
2;cd;caudate nucleus;Basal ganglia;Striatum
3;NA;nucleus accumbens;Basal ganglia;Striatum_ventral striatum
...

We could use this with the command:

nii2mesh D99_atlas_v2.0_right.nii.gz -a D99_v2.0_labels_semicolon.txt D99_.gii

with the resulting meshes have the file names D99_pu.k1.gii, D99_cd.k2.gii, etc.

Supported Mesh Formats

nii2mesh can save meshes to the GIfTI (.gii), json, jmsh, mz3, obj, off, ply, FreeSurfer (.pial), stl, vtk. MeshLab can export meshes to many other formats. Therefore, one option is to create a PLY mesh with nii2mesh and use MeshLab to export to your favorite format.

  • GIfTI is a popular Geometry format for Neuroimaging. The usage of base64 encoding leads to relatively large files and slow loading.
  • OBJ format is very popular, and may be a great choice for 3D printing. The use of ASCII rather than binary encoding makes these files large, slow to read and typically suggests limited precision.
  • OFF is a classic ASCII format.
  • PLY is an old format that is widely supported. The binary form created by nii2mesh yields small files and quick loading time.
  • MZ3 is the native format of Surfice. It is small and fast, but not widely supported.
  • FreeSurfer format is simple and used by FreeSurfer.
  • json creates human readable ASCII JSON files in the format described by jmesh. Be aware that other tools create legal JSON files to describe triangular meshes using a structure that is not compatible with json.
  • jmsh files are in the jmesh format, which inserts a compressed binary stream into a human readable JSON file. Supporting this format slightly increases the size of the executable (using the optional -DHAVE_JSON compiler flag and cJSON files).
  • VTK refers to the legacy VTK format, which is supported by many tools (unlike the more flexible modern XML-based VTK formats).
  • STL format is popular for 3D printing. You should use any other format unless required. This format does not re-use vertices across triangles, this results in very large files. Further, this means the meshes are either slow to load or appear to have a faceted jagged appearance.

Printing

You can use this tool to generate meshes suitable for 3D printing.

  1. If your MRI is in DICOM format, convert it to NIfTI with dcm2niix.
  2. Brain extract your image. You could use SSwarper, 3dSkullStrip, BET, FAST or HD-BET for this step.
  3. Apply nii2mesh to generate a mesh you can print locally or using a service like Shapeways or Kraftwurx

nii2mesh is a general mesh making method, which can be applied to any NIfTI image: a MRI or CT scan of any region of the body, a high-quality scan of any object including the animals of DigiMorph, phenome10k, MorphoSource, the NIH 3D Print Exchange or other 3D databases.

For brain specific printing, you may want to look at these tutorials.

Limitations

Similar to most mesh tools, nii2mesh uses fast algorithms that can generate self intersecting triangles. If you are conducting analyses where this is undesirable (e.g boundary element method (BEM) and finite element method (FEM) computations) you should consider (slower) algorithms that prevent these features. If you are interested in these applications, you may want to consider iso2mesh.

If you generate meshes that are only a single object (-l 1) that is watertight (e.g. bubble-filled, -b 1) you can fix self intersections with MeshFix:

nii2mesh bet.nii.gz -b 1 -l 1 bet.ply
MeshFix bet.ply better.ply

Links