• 04/03/2020
  • Public Content

Creating a Simple OpenVX* Graph Application

This section describes a simple example of graph design and execution. The graph based application computes the gradient magnitude and gradient phase from a blurred input image using standard OpenVX* kernels that are part of the Intel® Distribution of OpenVX*. The following figure describes the algorithm in a form of a DAG:
Example OpenVX* Graph
In an OpenVX* based application, a developer needs to create a context and a graph in the beginning of the application:
//The code to create context and graph vx_context context = vxCreateContext(); vx_graph graph = vxCreateGraph(context);
Images, virtual images, arrays, and other data-objects are the means to connect nodes of the graph, as well as communicating the data into and out of the graph:
//The code to create input and output image data objects vx_image images[] = { vxCreateImage(context, 640, 480,VX_DF_IMAGE_UYVY), vxCreateImage(context, 640, 480,VX_DF_IMAGE_U8), vxCreateImage(context, 640, 480,VX_DF_IMAGE_U8), }; //The code to create virtual images that connect nodes vx_image virts[] = { vxCreateVirtualImage(graph, 0, 0,VX_DF_IMAGE_VIRT), vxCreateVirtualImage(graph, 0, 0,VX_DF_IMAGE_VIRT), vxCreateVirtualImage(graph, 0, 0,VX_DF_IMAGE_VIRT), vxCreateVirtualImage(graph, 0, 0,VX_DF_IMAGE_VIRT) };
Notice that for intermediate (virtual) images you do not need to specify either type or size, as the graph compiler is able to deduce this data automatically. As we discussed earlier, these are actually stubs that have no associated accessible memory.
There other special types of images, for example, uniform images that hold single uniform value in all pixels. Also you can create an image object that references a memory that was externally allocated (refer to the
), the Interoperability with other APIs section.
The data-flow of the graph is created by adding the nodes in the graph and providing data objects as input and output to those nodes. In the graph, which is shown in the figure above, the example UYVY image is (non-virtual) input image. It is passed as argument to the luma extracting node
, and that is then connected to the blur node
.The blur node is connected to the
node that computes gradients. In turn, the gradients node is connected to both magnitude node
and phase node
Notice that both output nodes produces non-virtual images, which otherwise would not be accessible by the host code:
//Create nodes and connect them in the graph vxChannelExtractNode(graph, images[0],VX_CHANNEL_Y, virts[0]); vxGaussian3x3Node(graph, virts[0], virts[1]; vxSobel3x3Node (graph, virts[1], virts[2], virts[3]); vxMagnitudeNode(graph, virts[2], virts[3], images[1]); vxPhaseNode (graph, virts[2], virts[3], images[2]);
The OpenVX* graph must go through a validation process before the graph can be executed:
//Verify the graph status = vxVerifyGraph (graph); //Finally let’s execute the graph and wait for completion: //Execute the graph synchronously vxProcessGraph(graph);
The very last step is to free resources associated with graph, context, images and so on:
vxReleaseGraph(&graph); ... vxReleaseContext(&context);
For a more complete example including error handling, refer to the samples, described in the Sample Applications chapter.
Notice that to compile the code, you need to include the header files for OpenVX:
#include <VX/vx.h>
You also should link your code with OpenVX libraries. Refer to the
Quick Start Guide
for the details on the necessary environment setup.

Product and Performance Information


Performance varies by use, configuration and other factors. Learn more at www.Intel.com/PerformanceIndex.