CS9629 Homework Assignment #2

Overview

You should implement live-wire and snake-based segmentation tools for 2D photo or medical images. The first one requires implementation of Dijkstra algorithm on image contrast weighted graph. The snake tool should use Dynamic Programming (Viterbi) algorithm to compute each iteration of local snake optimization.
You are given two starter Visual Studio projects for
"live-wire" and
"snake" using the same C++ libraries as in HW1.

PART I (Live Wire) The programming for this part requires mostly changing code in function "compute_paths" (inside wire.cpp). Provided starter project has BFS traversal of the graph. Instead, you should implement Dijkstra. Weight edges using direct approach on slides 8-12 (topic 5) using Gaussian function "g(x)=const*exp(-x*x/(2*sigma*sigma))" where
"sigma" is a sensitivity parameter. Your report should contain the following experiemnts:

Compare livewire on 4 and 8 connected graph. Demonstarte the differences and explain them in the report.

Compare the results for a range of values for contrast sensitivity parameter "sigma" in the edge-weighting function.
Explain your impirical observations and justify a strategy for selecting "sigma".

Open and closed snakes should be handled (GUI closes a snake on a right click).
You may set different default energies for these two cases. For example, open-ended snake could use "keep length"
internal energy mode.

Tune both "shrink" and "keep length" internal energy modes: "shrink" should use elastic term
while "keep_length" should use internal energy encouraging certain distance L between control points (see class
notes). Find a good way of selecting L automatically and describe it in your report.

Play with your snake's internal energy even before you introduce external/image energy.
When only internal energy is present, your snake should develop into a smooth rounded contour (which converges
to a dot in case of "SHRINK" ). Make sure to check your snake's internal energy operation before you turn its external
energy on. Demonstrate examples for "SHRINK" and "KEEP LENGTH" in your report (GUI has a menu to choose this mode).

Tune both "image gradients" and "distance transform" modes of the external energy (adapt GUI menu for this mode):
in the first case the internal energy should be based on the values of image gradients at each control point while the second
case should use the values of the generalized distance transform. Your report should demonstrate examples where
the two modes behave differently, and explain why.

Suggestion: precompute 2D table of the same size as the image for storing the results of computing image gradients
costs F(p) at each pixel p (like node-costs in live-wire where low cost corresponded to large gradients).
Then, you can compute another 2D array D(p) corresponding to the generalized distance transform of F(p).
Your snake should use either F(p) or D(p) according to the Extrenal Energy Mode
(you can create any types of "modes" selectable from the drop-down-list, see main.cpp).
Note that Gradient and Distance Transform modes may require very different tuning of parameter lambda
controling relative weight of internal and external energies.

Analyse the effect of parameter alpha in the generalized distance map computation. Provide and explain results
of empirical tests.

Implement interactive corrections via "nudging" (see class notes). Use distance transform to compute
distances from a nudge point to all pixels in the image. "Snake.h" contains all necessary interface components
('add...Nudge' functions).

Density of snake nodes (parameter dP) and/or their uneven distribution
along the contour changes the balance between the internal and external energy terms.
Find some example(s) where spacing of control points clearly affects the behaviour of the snake and report your results/analysis.
Suggest some solution for eliminating such dependence on parameterization.

OPTIONAL PART (may get small bonus, do this only if really interested): implement an alternative method (GD-snake) for moving "snake" towards local minima based on
gradient-descent (energy derivatives) and compare it with DP-snake. For example, inside snake.cpp
you can add a new function GD_move() that can be called instead of DP_move() when some "flag" is selected.
Note that inside GD_move you must use floating-point precision and select an additional parameter "dt".

Use any real or synthetic images for your tests. Some sample images are posted at
image samples section.
In general, you should come up with specific examples for your report that illustrate different snake properties (strong or weak). In general, as future developers and/or researchers you should learn to identify srengths/weaknesses of different algorithms based on your conceptual/theoretical knowledge. Such analytical skills are essential for many jobs in high-tech industries or in academia.

Set up

The starter projects allow you to load (bmp) images, to enter clicks for live wire or snale initialization,
to press keys/buttons calling your snake-moving methods, and to save your results as images.
You should be primarily concerned only with files wire.cpp and snake.cpp where you
can implementat all methods required to complete the tasks above. All functions in these files are called from main according to GUI functionality
implemented in there. The provided GUI is in a "working" condition (compiles and runs). Livewire GUI is mainly designed to enter clicks and change some parameters. Main GUI features for the snake project are: left click = add snake nodes, right click = "close" the snake, key 's' = one iteration of
DP-snake, key 'c' = run iterations until snake convergence (local minima is found),
hit 'n'-key followed by a left (right) mouse click to add an attractive (repulsive) nudge.

What to submit and grading

Submit a .pdf file with your report (at most 2 pages of text, but any number of images). Use OWL to submit wire.cppsnake.cpp and any other project files where you changed some code.
If you used special images, submit the corresponding image files.