将新的 cv::Mat 喂入 vx_graph
Feeding a new cv::Mat into a vx_graph
给定的示例代码如 in this previous question(为简洁起见删除了错误检查):
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 );
以及经典的OpenCV阅读视频循环:
cv::VideoCapture cap;
cap.open("/Testing/test.avi");
for(;;)
{
cv::Mat frame;
cap >> frame;
if( frame.empty() ) break;
// TODO: what goes here?
vxProcessGraph( graph );
}
如何将 frame
放入 inputImage
以便正确调用 vxProcessGraph()
?我知道:
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
是获得 vx_image
的帮手,但我似乎无法找到下一步该做什么的示例。我阅读的一些 NVidia 文档建议:
vxAccessImagePatch(...);
// copy pixel-by-pixel??
vxCommitImagePatch(...);
然而,这似乎有点过于暴力,那么有没有更好的方法(vxSetParameter
,也许,但文档非常不清楚)来做到这一点?
可以创建仅引用存储在 cv::Mat
中的数据的 vx_image
。使用 vx_image
访问数据的东西最终会实际访问存储在 Mat
中的数据。此方法仅使用已记录的 OpenCV 和 OpenVX functions. From this Intel documentation:
vx_image get_vx_image_from_Mat(vx_context graph, cv::Mat &mat) {
vx_imagepatch_addressing_t frame_format {};
frame_format.dim_x = mat.cols;
frame_format.dim_y = mat.rows;
return vxCreateImageFromHandle(graph,
VX_DF_IMAGE_S16,
&format,
&((void*)mat.data),
VX_IMPORT_TYPE_HOST);
}
据推测,cv:Mat
至少需要与以这种方式创建的 vx_image
一样长的时间存在。
我设法找到了解决方案,因为让我困惑的是示例中使用了官方 API 中没有的 helper function。
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;
}
现在,我上面的示例代码需要快速修改:
vx_node sobel = vxSobel3x3Node(graph,inputImage,intermediate1,intermediate2);
然后是魔法线:
vxAddParameterToGraphByIndex(graph, sobel, 0);
这里的0
表示sobel
节点的第0个参数,不包括graph
本身。
接下来,我的循环变成:
if( frame.empty() ) break;
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
vxSetGraphParameterByIndex(graph, 0, (vx_reference) image);
vxProcessGraph( graph );
vxReleaseImage(&image);
在这里,0 表示我们添加到图中的第 0 个参数。如果我访问了上面的vx_parameter p
,那么不友好的情况会稍微少一些:
vxSetParameterByIndex(p, (vx_reference) image);
这可能会单独起作用,但我不知道是否需要做额外的工作来通知 vx_graph
更改。
给定的示例代码如 in this previous question(为简洁起见删除了错误检查):
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 );
以及经典的OpenCV阅读视频循环:
cv::VideoCapture cap;
cap.open("/Testing/test.avi");
for(;;)
{
cv::Mat frame;
cap >> frame;
if( frame.empty() ) break;
// TODO: what goes here?
vxProcessGraph( graph );
}
如何将 frame
放入 inputImage
以便正确调用 vxProcessGraph()
?我知道:
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
是获得 vx_image
的帮手,但我似乎无法找到下一步该做什么的示例。我阅读的一些 NVidia 文档建议:
vxAccessImagePatch(...);
// copy pixel-by-pixel??
vxCommitImagePatch(...);
然而,这似乎有点过于暴力,那么有没有更好的方法(vxSetParameter
,也许,但文档非常不清楚)来做到这一点?
可以创建仅引用存储在 cv::Mat
中的数据的 vx_image
。使用 vx_image
访问数据的东西最终会实际访问存储在 Mat
中的数据。此方法仅使用已记录的 OpenCV 和 OpenVX functions. From this Intel documentation:
vx_image get_vx_image_from_Mat(vx_context graph, cv::Mat &mat) {
vx_imagepatch_addressing_t frame_format {};
frame_format.dim_x = mat.cols;
frame_format.dim_y = mat.rows;
return vxCreateImageFromHandle(graph,
VX_DF_IMAGE_S16,
&format,
&((void*)mat.data),
VX_IMPORT_TYPE_HOST);
}
据推测,cv:Mat
至少需要与以这种方式创建的 vx_image
一样长的时间存在。
我设法找到了解决方案,因为让我困惑的是示例中使用了官方 API 中没有的 helper function。
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;
}
现在,我上面的示例代码需要快速修改:
vx_node sobel = vxSobel3x3Node(graph,inputImage,intermediate1,intermediate2);
然后是魔法线:
vxAddParameterToGraphByIndex(graph, sobel, 0);
这里的0
表示sobel
节点的第0个参数,不包括graph
本身。
接下来,我的循环变成:
if( frame.empty() ) break;
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
vxSetGraphParameterByIndex(graph, 0, (vx_reference) image);
vxProcessGraph( graph );
vxReleaseImage(&image);
在这里,0 表示我们添加到图中的第 0 个参数。如果我访问了上面的vx_parameter p
,那么不友好的情况会稍微少一些:
vxSetParameterByIndex(p, (vx_reference) image);
这可能会单独起作用,但我不知道是否需要做额外的工作来通知 vx_graph
更改。