Assignment 3
Methods In Medical Image Analysis (BioE 2630 : 16-725 : 42-735) - Spring 2009
John Galeotti

30 points total

Disclamer: Hour estimates are very approximate, and may be way too short if something goes wrong for you. They reflect the time required for a TA to finish each section.

Due Date: You have over 1 week to do this assignment. Your code must be checked into the svn repository by 12 PM Wednesday night, Feb. 18. Always, try to finish early! E-mail your TA or instructor with questions or problems.

Acknowledgement: This assignment is based in part on the work of others from previous sessions of this class.

This is your first real programming assignment, and your first use of SVN. Upon completing this assignment, you should feel comfortable not only using ITK, but also programming for arbitrary pixel types and dimensionality. This assignment requires that you have ITK installed and working. This assignment includes:

  1. Using SVN
  2. Using an ITK Filter
  3. Finding Partial Derivatives

For further guidance you should consult the ITK software guide and the lecture slides, especially those from lectures 5 and 7. Additionally, Part 3 requires content from lecture 9.

1. Using SVN (5 points, apx. 0.5-2 hours)

Usage of SVN was discussed in Lecture 3, starting on slide 13. You will be required to submit your code for all remaining assignments using SVN. You should have received your SVN username and password in class. All of the instructions given here will be for the command line version of SVN. You may want to use a GUI instead (see lecture 3), but it is up to you to learn the interface of the GUI of your choice.

Begin by confirming access to your SVN module, by listing the current contents of your module:

svn list --verbose --username {Your_SVN_User_Name} https://svn.vialab.org/svn/miia09/{Your_SVN_User_Name}
{Provide your SVN password when prompted.}

Your password should be accepted, and you should not have any connection errors.

Change to the directory you previously created (in HW2) to contain ITK, VTK, etc. (e.g. cd c:\MIIA), and then checkout your module:

svn co --username {Your_SVN_User_Name} https://svn.vialab.org/svn/miia09/{Your_SVN_User_Name}
{SVN will probably remember your password for you, but if not then provide it again when requested.}

You should now have a new directory named C:\MIIA\{Your_SVN_User_Name}. This directory should contain all of your code for the remainder of this class.

Now add a directory to your SVN module to contain this assignment. You must first create the directory locally, then tell SVN to add it to your module, and then commit your changes to the SVN server:

cd c:\MIIA\{Your_SVN_User_Name}
mkdir hw3
svn add hw3
svn ci hw3 -m "Setting up module for hw3"

This is the general template you must follow to add any new file or directory to your SVN repository. When you change a file that already exists, you only need to run the last line above (the commit line) to update the server's copy of your file. Notice the -m option, followed by a quoted string. SVN requires that every committed change be given a brief description, and this is how to do it. (Warning: If you get strange errors when trying to commit, then make sure you are using the double-quote characters around your commit description.)

Now, to further test and exemplify things, you are going to create a directory for this part of the assignment, add a file containing the one word "Hello", commit the directory + file, change the file by adding the word "World" to the end, and then commit the change:

cd c:\MIIA\{Your_SVN_User_Name}\hw3
mkdir Part1
echo "Hello"> Part1\file.txt
svn add Part1
svn commit Part1 -m "Initializing Part 1"
echo "World">> Part1\file.txt
svn commit Part1 -m "Fixed file.txt"

In the above, if you prefer you could also use a text editor, such as Windows Notepad, instead of the echo commands. Also, as you may have noticed, running an svn command on a directory runs the command on all of the files and directories it contains. This can be nice...or not. Use with caution.

In the future, the source code for each part of each assignment should be in an appropriately numbered hw#\Part# directory structure, but...

NEVER build your source code inside your svn module. Always do an out-of-source build!

2. Using an ITK Filter (15 points, apx. 2-5 hours)

As a last reminder (see above), this part of this assignment should be stored in your svn module in hw3\Part2. For example, create a directory such as c:\MIIA\{Your_SVN_User_Name}\hw3\Part2 and then add it to svn; write and edit your code in that directory, not forgetting to (re-)commit your code to svn each time you "significantly" change your code.

Remember, NEVER build your code in your svn module. Instead, I recommend creating a Bin directory structure that mirrors your SVN module, e.g. the code for part2 would be built in c:\MIIA\Bin\hw3\Part2. Hence, you only submit your source code, not your compiled program.

Now, on to Part2...

Write a command line program (source file named blur.cxx with a CMakeLists.txt file that generates a program named "blur") that does all of the following using ITK (feel free to borrow from the code in InsightToolkit-3.4.0/Examples/Filtering):

  1. Create a 100x100 image of unsigned char pixels, with origin (0,0) and spacing (1,1).
  2. Fill the image with pixel value 0. Draw a filled circle centered at (50, 50) with radius 25 and pixel value 255. Draw a second filled circle centered at (50, 50) with radius 10 and pixel value 160. To iterate though the image you will use an image region iterator and its GetIndex() function. This circle-drawing code does NOT need to be N-dimensional; consider the Euclidean distance function d(u,v)=sqrt(uv) as a starting point...
  3. Blur the image with a filter of your choice. The software guide describes blur filters. Feel free to apply other filters as well, just for fun.
  4. Write the final image to an 8-bit grayscale PNG file named "blur.png" using an itkImageFileWriter object. Again, the software guide is invaluable here.

Hint #1: I recommend skipping step 3 at first, just to make sure you are correctly creating and writing the image. After verifying that you are (and committing your code), then go back and implement step 3 as well. Don't forget to commit the final version of your code.

Hint #2: Be aware that some blur filters can only output signed pixel types. If your program crashes for no obvious reason, this is something to check. Even if you use a signed "blur output" pixel type, please make sure your "input" image, created in step 1, uses unsigned char as the pixel type.

Apart from the software guide, you may also wish to consult the online ITK documentation at www.itk.org. Either resource will likely spare you much anguish.

3. Finding Partial Derivatives (10 points, apx. 1-3 hours)

Do not begin this section until after Lecture 9.

Begin by copying Part2\blur.cxx to Part3\partials.cxx. Copy and update your CMakeLists.txt file as well; the compiled program should be named "derivatives". Add and commit your code (CMakeLists.txt is part of your code) to SVN. Now, replace your blur filter with a chain of two filters, the first of which is itk::NeighborhoodOperatorImageFilter. Create a first-order itk::DerivativeOperator to use as your kernel. The second filter in your filter chain should be itk::RescaleIntensityImageFilter (consult the software guild or online documentation), which should scale the (-255 to 255 range) output of the derivative-computing image filter to the range of a png file (0 to 255). As a word of warning here, make sure the pixel type you specify for the output of NeighborhoodOperatorImageFilter and the input of RescaleIntensityImageFilter can handle the range of -255 to 255, float is probably a good choice. (I suggest that your "input" image of 2 circles continues to use unsigned char as the pixel type.)

Your code should first create the pipeline, and then second loop through the number of image dimensions. For each dimension:

  1. Update the direction of NeighborhoodOperatorImageFilter's (derivative) operator to that of the current dimension. Note that since the filter's SetOperator() function makes a COPY of the operator, we need to first change the direction of our DerivativeOperator, and then once again call the filter's SetOperator() member function with the new version of our operator.
  2. Change the output filename to "partial_x.png", where x is the number of the current dimension.
  3. Update the image writer (which should cause the pipeline to re-execute using the updated operator).

Hint: The following two ITK files may be of some assistance: