Tahia Infantes Morris
Todd I. Delaune
CS7322
"Vision 2 Project Progress Report"
-
-
After much tedious work, we have come pretty darn close to accomplishing
our proposed goal for this week.
-
-
What we proposed a few weeks back was to employ active contours to track
the motion of the left ventricle (LV) of the heart. Specifically for this
progress report, we were going to follow the outer wall motion of the ventricle
from slice to slice in one axial plane (short axis). From the snake information,
we were going to create an animated wireframe of the outer wall of left
ventricle.
-
-
-
We began the project by collecting and converting the short axis plane
data to an acceptable format to use in Matlab. Just as a reminder,
each slice in the short axis plane contains about 10 images in time and
there are about 7 slices ~ about 70 images total. We chose Matlab because
Tahia was familiar with the software and had some code that she could modify
and enhance to make work with this project. After converting the
images and hacking with the code, we had to try playing with the snake
parameters, which affect the internal image energy. Specifically,
the Beta term needed to be adjusted to allow the contours to bend.
Also, the snake algorithm was modified to work in a ring-like structure,
so that the first and last snake points contribute to each other’s energy
sum. Once this was done, everything seemed like it should theoretically
work, but…
-
-
Our first problem occurred due in part to the tagging which appears in
the images. The snake points in general, converge to points of least energy
(like edges) but the tag lines are also rather strong edges. Therefore,
the snake tended to follow the tag lines to nowhere. We tried locating
untagged images, but had no such luck, as these images were the only ones
we had access to. So, we had problems with “unwanted” edges. But, on the
other hand, areas we wanted the snake to follow were fuzzy and not well
defined in the image. Such a case was the left most wall of the ventricle.
It was blurred at times and actually looked like it was part of the liver.
Therefore, to compensate, we computed the gradient for each image and we
decided to try following the inner wall instead of the outer wall of the
LV. The reason for this is because at this point in time, the snake can
follow the inner edges a lot better because there is a lot more contrast
in that area. When we tried the outer edge, part of the snake would end
up attached to the inner wall.
-
-
After deciding that we would track the inner most wall of the left ventricle,
the problem arose as to how many points to use per image. This was important
for later on when we wanted the points to connect from image to image to
create a wireframe. We decided to use 12 points as any more points would
clutter the image and would take way too much time to compute. We realize
that our final wireframe will be kind of blocky, but c'est le vie. The
next issue was in deciding which sequence to run the snake and how to place
the points so that it started in the same place from sequence to sequence.
In other words, at time slice 1, we wanted the snake to follow the 10 images
in the sequence because this was one complete cardiac cycle. However, we
also needed to connect these points to the corresponding points in the
next slice. Therefore, we needed to align the points from image to image
so that the wireframe would not be all twisted and distorted due to one
of us having to manually place the 12 initial points on the first image
of each slice. This involved another vision problem altogether, which was
finding which point in one image pertained to another in another image.
To get around this, we decided to begin by selecting the first slice and
manually placing the 12 initial points on the first image. We then let
the snake run through the sequence only in this slice (10 total images).
We then saved all the final snake points for each image in the first slice.
Next, instead of grabbing the next slice of images, we decided to take
the first image in each slice sequence (7 total) and run the snake against
them starting again with image 1, slice 1. We used the saved snake points
from the first image in the first slice as the beginning points and then
let the snake run its course. Once again we saved all the image snake points
for each image for later use. This helped out with the problem described
above because we could use the snake points from the first image in each
slice as starting points for each slice sequence. This was extremely
tedious and time consuming though because the Beta values had to be tweaked
depending on whether the set of images was in a slice sequence or a particular
image number in each slice. However, we started getting really promising
results. In viewing the initial 2D data, the snake points followed the
inner wall quite well and showed some slight twisting action – which is
typical for the heart. We were successful in obtaining good points for
six of the seven sequences. The last slice is difficult because it is a
view of the apex of the heart where the walls converge to a point and so
the inner wall is tiny and the snake screws up. Therefor we have enough
points to create an animated wireframe, but we need to go back to the original
images to extract the header information to determine the slice spacing.
We didn’t expect this to be a problem, but the format is weird and we need
to locate where that info is located. Otherwise, we will just have to eyeball
it, which is not what we want to do.
-
-
Therefore, we are on schedule as far as what we promised - with the exception
of the animated wireframe. The next step will be in getting the contours
to follow the outer wall. Once we get that working, the final step will
be in repeating it all with the long axis slice images so that we can see
the wall motion from front to back, as well as, side to side. Therefore,
we will have problems again with finding which points in the long axis
slice images correspond with those of the short axis images. The images
are very different in shape and there are only 6 slices in the long axis.
More importantly, we have to locate the long axis slices. Somehow, they
were not in the compressed image data file. Yikes.
-
-
So, yes, we are purposely omitting the part about following the tag lines
to find local contractile motion. While this certainly is possible to do,
neither one of us thinks we would have time to finish it. The reason is
because each image has approximately 10 tag lines running across the ventricle,
which means A LOT of processing time – not to mention the headache of aligning
the tag lines with the inner and outer wall points. We believe the project
is big enough, as is. =)
-
-

-
Short axis and long axis image
planes - Reminder of what the overall form of the LV looks like. We had
problems with the apex of the heart which is the bottom of the structure
(yes, counter-intuitive).

So, the first image
is of all the snake points in one single slice through time. There are
10 images per slice. You can see the movement and twisting action - which
is pretty cool. The second image is all the snake points from the first
image in each of the seven slices. This allows you to see the basic shape
of the inner wall of the LV (although squashed into 2-D). This was just
to show the kind of stuff that we are getting. =)
This is what a typical
image that we are working with looks like. The left ventricle is the doughnut
shape in the center.
.