Articles in the neuro category

  • Holding a Face in an MRI scanner

    Recently I had an MRI done on me as part of an MRI scanner operator training session. I decided to hold a face for the T1 scan, which is actually quite difficult because the process takes 5 minutes. Muscles in your face, I believe, aren't supposed to hold the same expression for several minutes in a row, and if you ever try it you'll find your face muscles twitching quite a bit.

    I got a copy of my scan and used AFNI and Blender to render the voxel data as I described in an earlier post. I can't decide if the result is creepy or funny looking, haha.


  • Rendering a Brain in three.js

    In my last post I talked about using Blender to render MRI volumes. This had the benefit of creating fairly nice static images or movies. In an earlier post I also showed how to use XTK to render volumes in real time.1 In this post I'll show a similar method of rendering a brain volume in real time using three.js, a Javascript library providing facilities for WebGL.

    This process is relatively straightforward. Using these steps from my last post you can get a Wavefront OBJ file from an MRI volume. This object file will have a very large number of polygons, which may make loading and rendering the object in WebGL slower. In order to reduce the number of polygons, import the Object file into Blender and apply the decimate modifier on each hemisphere. Then export the hemispheres as an OBJ file. My resulting OBJ file is linked here.

    Then we can basically just modify the object loader three.js example to load our brain!

    I outside of the normal minified three.js library I have one main script that handles the interactive rotation and placement of the WebGL container and I've slightly modified the OBJLoader.js script to compute vertex normals (geom.computeVertexNormals();), making the brain appear smoother.


    Footnotes:

    1. XTK can actually handle FreeSurfer meshes, so using three.js isn't strictly necessary.

  • Rendering MRI volumes in Blender

    In one of my posts I talked about using rendering brain volumes in-browser using XTK. The results, I'll admit, weren't spectacular. The volume rendering didn't really give very defined edges. But now I'll show a couple methods of rendering a brain using Blender. The first method is using volumetric data in Blender, and the second uses surfaces generated by FreeSurfer. I think it gives pretty cool results, check it out below.

    Above is Colin 27 average brain that comes included with AFNI as "MNIa_caez_colin27_t1_18+tlrc".

    Blender takes in different formats for its voxel data, and the type that was easiest for me to work with is the image sequence. Basically you just need to get a bunch of JPEGs of each slice from your voxels. And here's an easy way to do this with AFNI:

    #!/bin/bash
    
    afni -com 'OPEN_WINDOW A.axialimage'             \
         -com 'SET_XHAIRS OFF'                       \
         -com "SAVE_ALLJPEG A.axialimage $2 "\
         -com 'QUIT'                                 \
         "$1"
    

    You just supply the shell script the volume name and a base name, like "stuff".

    From there, I just followed some YouTube Blender tutorials (like this one) for how to render voxel data. Briefly, though, here are the steps:

    1. Edit the material for the default cube and select "Volume".
    2. Change "Density" to 0, as you'll have the voxel data supply the density for you.
    3. Then go into the texture editor and use a "Voxel Data" type, and you'll have "Influence" only set to "Density", which you'll set to some high number like 200. This means that higher-signal voxels (like those that are whiter), will appear more dense.
    4. You may need to mess around with the ramping, too, if you're getting random particles outside the brain. The preview in the material panel should help a lot for this.
    5. Also in the material panel, you'll want to set "Step size" fairly small, so you get a bunch more particles which look nicer.
    6. Finally, set the amount of light your lamp gives to a fairly high number.

    Method 2, Freesurfer surfaces and OBJ files

    The second way you can visualize the brain is by having FreeSurfer do the surface construction for you.

    Here's how to take the Colin brain and create a cortical surface using FreeSurfer. Warning: It will take a really long time.

    3dAFNItoNIFTI MNIa_caez_colin27_T1_18+tlrc
    mkdir -p MYSUBJ/mri/orig
    export SUBJECTS_DIR=`pwd`
    source ~/freesurfer/SetUpFreeSurfer.sh   # Or wherever you store it
    mri_convert MNIa_caez_colin27_T1_18.nii MYSUBJ/mri/orig/001.mgz
    recon-all -s MYSUBJ -autorecon-all
    

    This just does all the FreeSurfer steps, which is overkill and takes several hours to complete. You could, though, read this page to find the necessary steps to just create "lh.pial". Also check out these flags that you can pass to recon-all.

    I should note at this point that the rest of this post is basically just a knock-off of this post. Anderson has a great gawk script that converts FreeSurfer ASCII to obj included in his post, so check it out ...


  • Rendering MRI volumes in-browser with XTK

    Recently I've been playing around with interactive visualizations, using tools like d3.js and GGobi. One of the things I like about interactive visualizations, as opposed to static graphics, is that with interactive visualizations you don't have to make all the information available at once. You can present a broad overview of your data. And by having the user query specific data points, you can present more data as needed. Take this example of airport flight connectivity in the United States. If you had to display all the airport names and all the connections in one graph, it'd probably look pretty gross and would be very confusing to disentangle.

    Similary, with MRI data, it's usually hard to see the big picture at once. MRI data is usually just displayed in 2D slices. If you're showing activations you may show a couple slices, perhaps one axial and one sagittal, so your audience can get an idea of where your clusters take place. If you wanted to show a whole brain, you could perhaps do an animated GIF, like so.

    Animated GIF displaying axial slices of a brain.

    But this is fairly annoying, as it doesn't allow you to stop the animation or zoom closer to points of interest.

    XTK, however, allows you to display MRI volumes interactively in-browser using the magic of WebGL. XTK takes in a number of formats, from volume .nii files to Freesurfer surface meshes. Their website has a lot of examples, and writing code for it seems fairly straightforward. One particularly cool example, though, is XTK's live reslicing demo, which allows you to see slices of the brain at any angle, in real time, instead of just axial, sagittal, and coronal slices.

    Here's a cool example of rendering the isosurface of the same brain above using XTK. Using the mouse you can rotate, pan, and zoom in. I still need to tweak the parameters a little more to get a clearer image of the brain, and I think what I'll eventually do is convert the brain into a FreeSurfer surface and have XTK render that. But this is a fun first attempt (initially written four months ago).

    A fun idea too, if you have a presentation involving MRI volumes, would be trying to throw this in a reveal.js presentation.

    Here's some of the code to extract a volume for XTK and generate a GIF image using AFNI.

    # Select a sub-brick from AFNI_data6
    # I use an EPI, because the anatomical would be huge without resizing/resampling
    3dAFNItoNIFTI -prefix example FT_epi_r2+orig'[5]'
    
    # Get rid of the skull, you may also be able to use 3dAutomask
    3dSkullStrip -input example.nii -prefix examplestrip.nii
    
    ## Trying to normalize intensity
    # MAX=$(3dBrickStat -max examplestrip.nii)
    # 3dcalc -a examplestrip.nii -prefix examplestripscale.nii -datum short -expr "a/$MAX*1000"
    ## For some reason this won't actually save it using a short data type
    ## (You can verify this with 3dinfo)
    ## XTK for me seems to have problems with volumes using floats ...

Page 1 / 1

Category
Tagcloud
neuro LaTeX js bad-tagging-scheme pelican R testing vim-is-okay-too emacs statistics wm sysadmin productivity
Latest posts