This project deals with the problem of recognizing objects in images. The idea is that you have a model of a known object and want to determine if that object is present in a given image. Both the model and the image are represented as graphs, so the problem reduces to:
Specifically, as input your will be given two undirected graphs (from a file):
GM represents a structural model of an object that may appear in an image, and GD represents a structural description of the image itself.
PART I
Your program should find all isomorphic copies of GM in GD using a backtracking tree search. When it finds a mapping {(i1,j1),(i2,j2),...,(iN,jN)} that is a valid subgraph isomorphism from VM to VD, it should print the mapping and continue searching for others. If it finds no copies of GM in GD, it should print "NO ISOMORPHISMS FOUND."
PART II
Your Part II program should look for the best (least-error) mapping
from VM to VD. The mapping should be one-one, but it won't be onto, since
VD has more nodes than VM. It should print the best mapping after the search
terminates. (In case of ties, the best mapping is the FIRST of the least-error
mappings found.)
Note: This program should be executable on its own, rather than by
commenting out code from the program for PART I. Since there is expected to be a large
overlap between the two, we strongly encourage sharing utility functions
(e.g. for printing out a mapping, etc.).
1. The graphs are undirected, the nodes of each graph are integers between 1 and the total number of nodes. The format of the input file is as follows:
The output of PART I on this small input file would be:
Note that this tiny problem has so many isomorphisms, because the model graph is a tiny and symmetric structure, so there are 6 ways it can be mapped to the image graph. (Try drawing the two graphs.) The test data sets will, in general, not have so many possibilities.
2. You may decide on your own structures for representing
the node sets, edge sets, and mappings required for the problem.
Warning: Keep in mind that if you pass a pointer to some list
to a function and it changes the list somewhere deep into the recursion,
then the list will be changed when it comes back, which is not what you
want. So you must be careful what you pass and how you pass it. Also, be careful
with memory allocation and deallocation. Careless memory management could
cause disaster as the number of recursive calls grows.
3. For Part II, add another function to your program to find
the least-error mapping from GM to GD.
(FORWARD ERROR ONLY) This can be done by a branch-and-bound tree search,
which has two extra arguments:
For the tiny example above (with 6 isomorphisms), Part II would print out:
4. Documentation should include:
5. Input graphs and required tests
The input graphs and their images can be found
here.
Note: The same images (pictures) are given for your convenience in both PDF and PS formats.
Test PART I on all four data sets.
Test PART II as follows:
6. Turn-in BOTH the commented program listing AND the output from each of the above tests.
Extra Credit up to 15% can be earned by adding intelligence to the searches and/or trying other search methods and comparing the results. Note, that extra credit only counts if it is in addition to, not instead of the requirements described above. You should fully solve the initial problem before proceeding to any extra credit endeavors.
Good luck!