Given sample code like in this previous question (error checking deleted for brevity):
vx_image inputImage = vxCreateImage( graph, width, height, VX_DF_IMAGE_S16 );
vx_image outputImage = vxCreateImage( graph, width, height, VX_DF_IMAGE_S16 );
vx_graph graph = vxCreateGraph( context );
vx_image intermediate1 = vxCreateVirtualImage( graph, width, height, VX_DF_IMAGE_S16 );
vx_image intermediate2 = vxCreateVirtualImage( graph, width, height, VX_DF_IMAGE_S16 );
vx_image intermediate3 = vxCreateVirtualImage( graph, width, height, VX_DF_IMAGE_S16 );
vxSobel3x3Node(graph,inputImage,intermediate1,intermediate2);
vxMagnitudeNode(graph,intermediate1,intermediate2,intermediate3);
vxConvertDepthNode(graph,intermediate3,outputImage,VX_CONVERT_POLICY_WRAP,0);
vxVerifyGraph( graph );
vxProcessGraph( graph );
And the classic OpenCV reading video loop:
cv::VideoCapture cap;
cap.open("/Testing/test.avi");
for(;;)
{
cv::Mat frame;
cap >> frame;
if( frame.empty() ) break;
// TODO: what goes here?
vxProcessGraph( graph );
}
How do I get the frame
into the inputImage
so I can call vxProcessGraph()
correctly? I know that:
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
Is a helper for getting a vx_image
, but I cannot seem to find an example of what to do next. Some NVidia documentation I read suggested:
vxAccessImagePatch(...);
// copy pixel-by-pixel??
vxCommitImagePatch(...);
However, this seems a bit too brute-force-like, so is there some nicer way (vxSetParameter
, perhaps, but the documentation is very unclear) to do this?
I managed to work out the solution, as what was confusing me about examples was the use of a helper function not in the official API.
vx_status vxAddParameterToGraphByIndex(vx_graph g, vx_node n, vx_uint32 index)
{
vx_parameter p = vxGetParameterByIndex(n, index);
vx_status status = vxAddParameterToGraph(g, p);
vxReleaseParameter(&p);
return status;
}
Now, my sample code above needs a quick modification:
vx_node sobel = vxSobel3x3Node(graph,inputImage,intermediate1,intermediate2);
Then the magic line of:
vxAddParameterToGraphByIndex(graph, sobel, 0);
The 0
here means the 0th parameter to the sobel
node, excluding the graph
itself.
Next, my loop becomes:
if( frame.empty() ) break;
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
vxSetGraphParameterByIndex(graph, 0, (vx_reference) image);
vxProcessGraph( graph );
vxReleaseImage(&image);
Here, the 0 means the 0th parameter that we have added to the graph. If I had access the vx_parameter p
above, there is the slightly less unfriendly:
vxSetParameterByIndex(p, (vx_reference) image);
This might work on its own, but I don't know if there's extra work to do to notify the vx_graph
of the change.