Image Analysis

Computer vision is a field in computer science that focuses on extracting information from images and using this to solve tasks. Two important problems that are fundamental to many computer vision algorithms are image segmentation and image comparison. Image segmentation algorithms take images represented as 2D arrays of colored pixels and divide them up into regions, with the intention that the regions correspond to meaningful objects or parts of the image. Image comparison attempts to compare images (or parts of images) and can be used for answering questions such as classifying an image as a particular type of scene (outdoor vs. indoor) or type of object (human face, car, etc.). A variety of image segmentation algorithms have been proposed, one of the most popular being the watershed transform. This page documents a variant on this algorithm that is similar to an approach used in geometry segmentation called variational shape approximation. The segmentations produced by this algorithm are then run through an image classification algorithm based on graph kernels which compares two images by comparing their segmentation graphs. This is similar to this SIGGRAPH 2011 paper which does the same thing for 3D scenes.

Image Segmentation

The image segmentation algorithm I use generates a segmentation with a pre-specified number of clusters (N). First, N pixels are chosen at random in the image and act as the seeds for the clusters. The clusters are then grown using a priority queue that favors adding pixels whose color is similar to the cluster's seed. Once all pixels are assigned a cluster, new seeds are chosen for each cluster that are more representative of that cluster, and the algorithm iterates until the clusters reach equilbrium (or close enough.) When a small number of regions are used the segmentation approximately captures the overall color structure and style of the images, and when a large number of regions are used the algorithm acts more like a superpixel segmentation. Here we show results on 3 images varying the number of clusters used:

Original 250 Clusters 1000 Clusters 1000 Clusters

The image on the right uses a false coloring to make it easier to see the cluster size. More results can be found here, which show the results of the algorithm using a different number of clusters for a variety of different image categories.

Image Classification

Once an image has been segmented, we can turn it into a graph. There is a node in the graph for each segment in the image. Two nodes are connected by an edge if the two segments represented by those nodes are touching in the image. Once images have been reduced to graphs, we can apply standard graph kernel techniques to compare any two images. The graph kernel just needs a way of comparing two nodes --- in this case, I compare two nodes by comparing the average colors of the two clusters. The interesting computational details of the graph kernels are all described in this CVPR paper. I don't have any more significant results to show, but the code below might serve as a useful reference for anyone who has to implement graph kernels themselves.


This code is all based off my BaseCode. Specifically you will need the contents of on your include path, on your library path, and on your system path.

x (includes project file)

ImageSegmentation Code Listing

x App.cpp, Web Version
x App.h, Web Version
x BipartiteSolver.cpp, Web Version
x BipartiteSolver.h, Web Version
x Config.h, Web Version
x Engine.cpp, Web Version
x Engine.h, Web Version
x ImageColorTransfer.cpp, Web Version
x ImageColorTransfer.h, Web Version
x ImageMorpher.cpp, Web Version
x ImageMorpher.h, Web Version
x ImageSegmenter.cpp, Web Version
x ImageSegmenter.h, Web Version
x Main.cpp, Web Version
x Main.h, Web Version
x Matrix.h, Web Version
x Munkres.cpp, Web Version
x Munkres.h, Web Version
xx Edge.h, Web Version
xx Graph.cpp, Web Version
xx Graph.h, Web Version
xx Node.h, Web Version
xx Walk.h, Web Version
xx EdgeKernel.cpp, Web Version
xx EdgeKernel.h, Web Version
xx GraphKernel.cpp, Web Version
xx GraphKernel.h, Web Version
xx NodeKernel.cpp, Web Version
xx NodeKernel.h, Web Version
xx RootedGraphKernel.h, Web Version
xx RootedGraphKernelDynamicProgramming.cpp, Web Version
xx RootedGraphKernelDynamicProgramming.h, Web Version
xx RootedGraphKernelEnumerateWalks.cpp, Web Version
xx RootedGraphKernelEnumerateWalks.h, Web Version
xx WalkKernel.cpp, Web Version
xx WalkKernel.h, Web Version

Total lines of code: 3130