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.