Laura's Brain

Doug Blank, cs.brynmawr.edu/~dblank

A friend (let's call her "Laura") recently (last night) had an MRI performed on her head. She brought back a CDROM which we were surprised to find had the images in a easily-readable format called DICOM.

Laura is fine (as far as we know) but she did decide to donate her virtual brain to science, or, at least us!

Each image is a slice of Laura's brain. Looking at an individual image shows something like this:

I converted the DICOM images to jpg, for easy reading into Mediacomp-enabled systems, such as Myro. First, here is an animated gif from the set of images:

To produce an image like this, one could do something along the lines of:
# Process a set of MRI images
# Doug Blank
from myro import *
filenames = getFilenames("z??.jpg")
savePicture(map(makePicture, filenames), "animated.gif")

Cool, but could we combine these into a single image? We could overlay each image on top of the previous, but only where there is something "interesting". Interestingness could be defined as "not black". Here is the result (left, looking head-on; right, from behind):

Here is the code for that:

# Process a set of MRI images
# Doug Blank
from myro import *
filenames = getFilenames("z??.jpg")
image = None
for filename in filenames:
    print "Processing", filename
    if image == None:
        image = loadPicture(filename)
    else:
        newimage = loadPicture(filename)
        for pixel in getPixels(newimage):
            if distance(getRGB(pixel), getRGB(black)) > 50: # not black
                setPixel(image, getX(pixel), getY(pixel), pixel)
savePicture(image, "composite.jpg")

Finally, could we peak inside the skull, too? If we define a section that we ignore, then it won't show that. Also, if we change the section slightly on each image, we can see a bit of the interior:

That could be constructed with:

from myro import *
filenames = getFilenames("z??.jpg")
image = None
x, y = 256 + (21 * 3), 300 - (21 * 3)
for filename in filenames:
    print "Processing", filename
    if image == None:
        image = loadPicture(filename)
        for pixel in getPixels(image):
            if getX(pixel) > x and getY(pixel) < y:
                setColor(pixel, black)
    else:
        newimage = loadPicture(filename)
        for pixel in getPixels(newimage):
            if distance(getRGB(pixel), getRGB(black)) > 50: # not black
                if getX(pixel) > x and getY(pixel) < y:
                    pass
                else:
                    setPixel(image, getX(pixel), getY(pixel), pixel)
    x, y = x - 3, y + 3
savePicture(image, "removed.jpg")

I wasn't very happy with the blind copy of closer images over the previous ones, and tried a way of blending the images:

Which is more smooth, and allows you to see more of the internal structure, but still isn't quite right.

I suspect that many more interesting things could be done with some simple code. (Of course, much more could be done with some complex code.) Some other ideas can be found at http://imaginaryfriends.typepad.com/. Let me know, if you do anything of the kind!

The images can be found here:


Doug Blank, cs.brynmawr.edu/~dblank April 15, 2008