Here is the source code for a simple program in C that uses the OpenCV library. The OpenCV package already contains several examples and fairly decent documentation, but the code you’ll find here is extra commented. It doesn’t do anything terribly interesting by itself: it captures images from the camera, finds edges and contours and displays them. When the user clicks on the window, it tries to find a contour that surrounds the location the user clicked in. If there is one, it prints out the area of this contour.
This example is meant to show how to use the basic GUI support offered by OpenCV, such as creating windows, trackbars (sliders) and responding to mouse and keyboard events. It shows a basic image processing chain (resize, convert to greyscale, find edges, dilate), but most importantly it also shows how one can work with sequences.
Sequences are a type of linked list used extensively in OpenCV, but the documentation is somewhat less than perfectly clear about how they’re organized. There are utility functions to iterate through these sequences, but accessing the pointers directly, as I do in this example can be just as clear.
In the example, I use the function cvFindContours, which returns sequences of points that are connected together along an image edge. The flag CV_RETR_TREE tells the function to organize the contours in a hierarchical tree. What does this mean? The contours are stored in a structure called CvSeq. You can tell how many points are in the contour stored in a CvSeq by looking at its total member. If you have a CvSeq called contour, you can iterate through its points like this:
CvPoint *point = (CvPoint *)CV_GET_SEQ_ELEM(CvPoint,&contour,i);
You can access other contours using the h_next and v_next members of CvSeq. If you specified CV_RETR_TREE, the pointer v_next points to the first contour that is inside the current contour. On the other hand, h_next points to the first contour that is outside the current contour. For example:
If we give the binary image above to cvFindContours, it will find the contours shown on the left below, labeled A to L. You can access A through the CvSeq structure cvFindContours expects as its third argument. All the other contours can be accessed through the h_next and v_next pointers, as shown on the right.
If you are running this example on OS X, the #include commands expect OpenCV to be packaged as a framework. Alter these lines accordingly if this is not the case.