Draw graphs using OpenCV:
I have created 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:
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:showFloatGraph
("Rotation Angle", &floatVector[0], floatVector.size());showIntGraph
("Rotation Angle", &intVector[0], intVector.size());showUCharGraph
("Pixel Values", pixelData, numPixels);
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)";Here is the result: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);