Draw graphs using OpenCV

Here is a basic graphing library to allow plotting graphs on the screen or into an image using OpenCV. This can be very useful to view the contents of a numerical array, such as during testing of an algorithm.

This “library” is just a collection of functions that can be used to simply plot a graph of an array in its own window, or to overlay graphs into existing an IplImage. This makes it both easy to use and powerful enough for more complex uses such as combining multiple graphs into one.

Showing a simple graph of an array

Here is a simple example to see a graph of a float array in a new window, by calling:

showFloatGraph("Rotation Angle", floatArray, numFloats );

The same sort of graph could be shown from a std::vector of floats or ints or even a byte array:

showFloatGraph("Rotation Angle", &floatVector;[0], floatVector.size());
showIntGraph("Rotation Angle", &intVector;[0], intVector.size());
showUCharGraph("Pixel Values", pixelData, numPixels);

Note that the window will only stay active for half a second by default. To make it wait until the user hits a key, add “0” as the wait time, by calling:

showIntGraph("Rotation Angle", &intVector;[0], intVector.size(), 0);

Drawing multiple graphs into an IplImage

It is also possible to draw a graph into an existing image of your own, such as to overlay a graph on top of your work, or to graph multiple values in the same graph:

IplImage *graphImg = drawFloatGraph(&floatVec1;[0], floatVec1.size(), NULL,
	-25,25, 400,180, "X Angle (blue is truth, green is POSIT)" );
drawFloatGraph(&floatVec2;[0], floatVec2.size(), graphImg, -25,25, 400,180);
cvSaveImage("my_graph.jpg", graphImg);
cvReleaseImage(&graphImg);

Overlaying graphs onto an existing IplImage

You can also plot the graphs onto existing images, as shown here:

IplImage *bgImg = cvLoadImage("my_background_photo.jpg");
int w = bgImg->width;
int h = bgImg->height;
drawFloatGraph(floatArray, numFloats, bgImg, -25,25, w, h, "Yaw (in degrees)");
showImage(bgImg, 0, "Rotation Angle");
cvReleaseImage(&bgImg);

Here is a more complex example, where 3 graphs are drawn over a larger photo:

IplImage *dstImage = cvLoadImage("my_background_photo.jpg");
int W = 400, H = 200;
float RANGE = 25.0f;
char *name;

name = "X Angle (blue is truth, green is POSIT)";
setGraphColor(0);	// Start with a blue graph
// Set the position of the graph within the image
CvRect region = cvRect(dstImage->width-1 - W-10, 10, W+20, H+20);
cvSetImageROI(dstImage, region);
drawFloatGraph(&vecX1;[0], vecX1.size(), dstImage, -RANGE,+RANGE, W,H, name);
drawFloatGraph(&vecX2;[0], vecX2.size(), dstImage, -RANGE,+RANGE, W,H);

name = "Y Angle (blue is truth, green is POSIT)";
setGraphColor(0);	// Start with a blue graph
// Set the position of the graph within the image
region.y += H+20;
cvSetImageROI(dstImage, region);
drawFloatGraph(&vecY1;[0], vecY1.size(), dstImage, -RANGE,+RANGE, W,H, name);
drawFloatGraph(&vecY2;[0], vecY2.size(), dstImage, -RANGE,+RANGE, W,H);

name = "Z Angle (blue is truth, green is POSIT)";
setGraphColor(0);	// Start with a blue graph
// Set the position of the graph within the image
region.y += H+20;
cvSetImageROI(dstImage, region);
drawFloatGraph(&vecZ1;[0], vecZ1.size(), dstImage, -RANGE,+RANGE, W,H, name);
drawFloatGraph(&vecZ2;[0], vecZ2.size(), dstImage, -RANGE,+RANGE, W,H);

cvResetImageROI(dstImage);

showImage(dstImage);
cvReleaseImage(&dstImage);

Download GraphUtils

The source-code is available here, to use as you wish for non-military projects only. Tested on VS2008, but should generally work on Windows, Linux and Mac.

To use this graphing library, download this file: graphutils.zip (4kB ZIP file of C/C++ source files)

Leave a Reply

Your email address will not be published. Required fields are marked *