CIS 2168: Lab-Assignment #4: Shape
Abstraction
Introduction
It's getting
serious. We will combine data structures with graphics and a real application
from computer vision.
Computer vision
is the science of image analysis, or short: to teach the computer to understand
(the beauty of) the visual world. A basic, yet complicated task is shape recognition. An object's shape can
for example be represented by its 2D boundary. The computer's task is to
recognize this boundary, and act accordingly (a deer: how cute!, a lion =>
run). The actual shape recognition is a bit too much for this semester, but we
will program an important pre-processing step: shape abstraction.
Shape
abstraction can be explained quite simply: given an object boundary of
connected points, remove those points that don't carry a visual significance.
You'll understand in a second. Let's first get a bit more into data-structures:
A 2-dimensional shape can be defined by its
boundary-polygon, which is an ordered list of all coordinates of its outline
points. See the following figure for an example:
The left picture shows the
original shape (defined by its AREA), the middle picture the outline (BOUNDARY)
of the shape. We want to create a LIST of all points of the outline. In order
to do so, we start at some arbitrarily chosen point and traverse the outline
clockwise. We store the coordinates of each point in a node, and therefore
create an ordered list of x,y-pairs of coordinates of all boundary vertices,
e.g.
x=12, y=14
x=13, y=14
x=13, y=15
...
Don't panic yet (you might want to
save that emotional state for later, when I'll describe what you should
implement). This list of points will be given to you as a textfile, so you
don't have to program a boundary tracing algorithm.
Now take a look at the rightmost
picture in the figure above. It shurely shows a very similar shape, it seems to
be an abstracted version of the original boundary. In fact it is: the rightmost
picture shows a certain subset of the original boundary vertices (points),
connected by lines.
The remaining subset consists of boundary vertices containing visually
significant information (in terms of human visual perception).
A very simple way to achieve this
is an algorithm called Discrete Curve Evolution (latecki/lakaemper 1999, click HERE if you want to read the original
paper): It keeps the important points, and dismisses unimportant ones. The
importance is measured by the amount of visual information in the following
way:
The figure above shows a cutout of
the boundary, L,P and R a vertices, the lengths of the segments connecting
these vertices are: LP = l1, PR = l2, RL = l3.
(Since someone from Greece long ago defined the length between two points as
the 'Euclidean distance', it is given by sqrt((x1-x2)^2 + (y1-y2)^2), as you
might know.)
The line LR shown in the figure is not part of the boundary, but we need it's
length for the significance measure:
Define the visual significance S of vertex P simply by S(P) = l1 + l2 - l3.
For better understanding, here are some properties of this significance measure
S(P) of point P:
- It is zero if
L,P,R are collinear (certainly P does not contain any visual information
then !)
- It increases
with P moving away from the baseline LR
- It is never
less than zero
Defining this significance-value allows us to assign the
significance to every single vertex of the boundary list.
Now comes the important part: the
abstraction. Remember we want to create a subset of the original boundary, i.e.
want to pick out certain 'important' vertices, dropping 'unimportant' ones.
A natural way to do this is the following:
- Assign the
signifcance value S() to every vertex except the first and last one (they
don't have 2 neighbors)
- set S for the
first and last vertex to INFINITY (they'll never be removed)
- LOOPSTART: Find
the vertex containing the minimum significance
- Drop the vertex
by removing it from the list
- compute the new
values S for the 2 points, that were the neighbors of the removed vertex
- loop (goto
'find the vertex...') until the list contains a predefined number of
vertices
Some remarks:
- No sorting is
necessary in this implementation, we search the minimum by traversing the
list (O(n))
- We need the
next and previous node of the removed node. This can be done either by using
a double linked list, or, if using a single linked list, memorizing the
previous node.
And here's your assignment:
(if you want to panic, now is the correct time to start)
Please plan your work in this
order!
- Read the
boundary-list (DOWNLOAD HERE!)
, given as a textfile of (x,y)-coordinates of boundary vertices, into a
linked list.
- YOU
HAVE TO define your own list-structure, you are NOT ALLOWED to use what
JAVA offers (LinkedList, ArrayList etc.). You will need to implement a
double linked list with start pointer.
- implement
an 'insertFirst(...)' method in your list class. Read each line of the
text file, extract the 2 points defined in that line, and store them in a
new node.
- add
that node at the beginning of the list, using your 'insertFirst(...)'
method. (this stores the points in reverse order, but that doesn't change
anything)
- Visualize the
List, connecting the vertices given in the file by lines. You need to
define your own JPanel to draw the list. The drawing itself will use the
g.drawLine(xStart, yStart, xEnd, yEnd) to connect 2 boundary points. Hence
your paintComponent(Graphics g) method will contain a loop that iterates
through the list, drawing the connection of 2 points in each step.
- Implement the
abstraction-algorithm. For this, you will need a "remove" method
in your double-linked-list.
- Skip the first
and last point in the list, they should never be removed. That makes it
much easier.
- Simplify the
polygon until only 38 points remain.
- Show the
simplified polygon
Points
for partial achievements:
·
reading the file & drawing the
original deer: 4 points
·
implementing the double linked list
with insertion and removal of points: 3 points
·
implementing the actual abstraction
algorithm: 3 points
Remark:
- Implementing
the boundary polygon as a double linked list is mandatory. No arrays this
time (zero points for arrays).
- The abstraction
in the first figure above, rightmost picture, is done by exactly this algorithm,
but it uses a different measure for the significance value. The simplified
image shown contains 38 vertices. Your results might look a bit different.
Earn 4 (!!!) bonus point for adding a slider to your application, showing each
step of the simplification. Because a slider can go back and forth, you have to
store the results of each single simplification step. You could use an Array of
Lists for that.
This is a serious assignment. One
week is a short time for it. Start immediately. Deadline: 2/19 (10 points).
2/26 (6 points).
Enjoy.