Information

Documentation

Get OpenRDK at SourceForge.net. Fast, secure and Free Open Source software downloads

edit SideBar

Using Magick++ and OpenCV libraries

The OpenRDK core provides some utility functions to interoperate with commonly used third-party libraries, for example Magick++ (from the ImageMagick suite) and OpenCV (Open Computer Vision library).

The main issue here is how to tranform an image in OpenRDK format (i.e., an object of the class RDK2::RImage) to the format that is used by these libraries (Magick::Image for Magick++ and IplImage for OpenCV).

Using Magick++ on a RImage

You can convert Magick::Image to RImage and vice-versa using the functions in rdkcore/interop/magick++.h. As an example, you can look at the code of the module ImageMagickExampleModule that you can find in the ${OpenRDK}/src/apps/modules/examples/imagemagickexamplemodule directory. A configuration file is also provided in ${OpenRDK}/data/config/examples/rq-demo-imagemagick.config (it requires a webcam and the video4linux support).

First of all, let's have a look at the CMakeLists.txt:

# This file has been generated by rdk-cmake-ragent-module.sh
IF(MagickPP_FOUND)
        RDK_ADD_RAGENT_MODULE(ALL_FILES)
        INCLUDE_DIRECTORIES(${MagickPP_INCLUDE_DIR})
        LINK_DIRECTORIES(${MagickPP_LINK_DIRECTORIES})
        TARGET_LINK_LIBRARIES(${RDK_THIS_MODULE_NAME} ${MagickPP_LIBRARIES})
ENDIF(MagickPP_FOUND)

This means that the module is compiled only if ImageMagick Magick++ library development package is found (this search is performed during the cmake call in OpenRDK). Moreover, header directories and libraries are included in the built system.

The code of the module is quite simple: it takes an RImage from the repository, converts it to a Magick::Image, does some processing on it and then converts back to an RImage, that is published in another property. Here is the code that you can find in the exec() function:

RImage* rin = session->getObjectCloneAs<RImage>(PROPERTY_IN_IMAGE);
Magick::Image mimg = convertToMagickImage(rin);
delete rin;

if (session->getBool(PROPERTY_ADD_NOISE)) mimg.addNoise(Magick::GaussianNoise);
if (session->getBool(PROPERTY_BLUR)) mimg.blur();
/* other Magick::Image methods */

RImage* rout = convertToRImage(mimg);
session->setObject(PROPERTY_OUT_IMAGE, rout);

The two functions of interest are convertToMagickImage() and convertToRImage(). They create another object so you have to take care of its deallocation (unless you give it to the repository). This is a simple example module, if you have a webcam you can run the example configuration file in ${OpenRDK}/data/config/examples/rq-demo-imagemagick.config and see some effects on the image taken from the webcam.

Using OpenCV on a RImage

The same approach can be used also for using OpenCV library. As with Magick++, OpenRDK provides both an example module ${OpenRDK}/src/apps/ragent/modules/examples/opencvexamplemodule and an example configuration file that runs this module on the webcam image: ${OpenRDK}/data/config/examples/rq-demo-opencv.config. Also the CMakeLists.txt of the module is similar to that of ImageMagick. The big difference is that, together with the functions convertToIplImage() and convertToRImage(), that work in the same way of the respective functions for Magick++, for OpenCV there is also a third option: createIplImageHeader().

An IplImage can be seen as made up of two parts: a header and a body. The header contains information about the image format, size, etc., while the body contains the actual bits. Since OpenRDK's RImage and OpenCV's IplImage share the same format for the image bits, you can simply create an IplImage's header that shares the RImage buffer, without the need of a memory copy. The situation is depicted in the following figure:

This means that you must pay attention at object deletion, since the two objects share information. That is, you cannot delete the RImage or use cvReleaseImage() on the IplImage if you still want to use the other object.

Let's make some examples:

RImage* rimg = new RImage(320, 240, RImage::RGB24);
IplImage* iplimg = createIplImageHeader(rimg);
delete rimg;
cvFlip(iplimg, ...);   // WRONG: rimg has been deleted, and thus the buffer of iplimg

RImage* rimg = new RImage(320, 240, RImage::RGB24);
IplImage* iplimg = createIplImageHeader(rimg);
session->setObject(..., rimg);
cvFlip(iplimg, ...);   // WRONG: rimg is now inside the repository and is not locked, so also the buffer of iplimg is shared in the repository

session->lock("image", HERE);
RImage* rimg = session->getObjectAsL<RImage>("image");
IplImage* iplimg = createIplImageHeader(rimg);
session->unlock("image");
cvFlipi(iplimg, ...);   // WRONG: the RImage has been unlocked, so it is not safe to use its buffer (that is the same of the IplImage)

The example module ${OpenRDK}/src/apps/ragent/modules/examples/opencvexamplemodule shows some legal use of this useful wrapping function. Here is an example that follows that structure:

RImage* rin = session->getObjectCloneAs<RImage>(PROPERTY_IN_IMAGE);
IplImage* cvin = createIplImageHeader(rin);

RImage* rout = (RImage*) rin->clone();
IplImage* cvout = createIplImageHeader(rout);

cvSmooth(cvin, cvout, CV_GAUSSIAN, 9);
cvReleaseImageHeader(&cvin);
cvReleaseImageHeader(&cvout);
delete rin;

session->setObject(PROPERTY_OUT_IMAGE, rout);

Once you have used the OpenCV functions, you should release the IplImage header object (only the header, not the image data, that is shared with the RImage object) using the OpenCV function cvReleaseImageHeader().

© 2004-2009 RoCoCo Laboratory Powered by PmWiki
Edit - History - Printable View - Recent Changes - Search
Page last modified on July 14, 2009, at 12:50 PM