1

给定上一个问题中的示例代码(为简洁起见,删除了错误检查):

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);

是获得 a 的帮手vx_image,但我似乎找不到下一步该做什么的例子。我读过的一些 NVidia 文档建议:

vxAccessImagePatch(...);
// copy pixel-by-pixel??
vxCommitImagePatch(...);

但是,这似乎有点太蛮力了,所以有没有更好的方法(vxSetParameter也许,但文档很不清楚)来做到这一点?

4

2 回答 2

2

可以创建vx_image仅引用存储在 a 中的数据的 a cv::Mat。使用vx_image来访问数据的东西最终会实际访问存储在Mat. 此方法仅使用记录在案的 OpenCV 和OpenVX函数。从这个英特尔文档

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以这种方式创造的任何东西一样长。

于 2018-04-25T02:48:46.810 回答
1

我设法找到了解决方案,因为让我对示例感到困惑的是使用了不在官方 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;
}

现在,我上面的示例代码需要快速修改:

vx_node sobel = vxSobel3x3Node(graph,inputImage,intermediate1,intermediate2);

然后是魔法线:

vxAddParameterToGraphByIndex(graph, sobel, 0);

这里表示节点0的第 0 个参数,不包括自身。sobelgraph

接下来,我的循环变为:

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更改。

于 2018-04-25T03:28:37.723 回答