将一个新的cv :: Mat提供给一个vx_graph

时间:2018-04-25 01:36:53

标签: c++ opencv openvx

给出示例代码,例如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,也许,但文档很不清楚)这样做?

2 个答案:

答案 0 :(得分:1)

可以创建vx_image,仅引用cv::Mat中存储的数据。使用vx_image访问数据的某些内容最终会实际访问存储在Mat中的数据。此方法仅使用记录的OpenCV和OpenVX函数。从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一样长。

答案 1 :(得分:0)

我设法解决了这个问题,因为令我困惑的是关于示例的问题是在官方API中没有使用helper function

private val mySelectedIndex get () {
    return mCustomAdapter.getSelectedIndex()
}

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

private val mySelectedIndex get () =
    mCustomAdapter.getSelectedIndex()

然后是魔术线:

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本身。

接下来,我的循环变为:

sobel

这里,0表示我们添加到图表中的第0个参数。如果我访问了上面的graph,那么就会有一些不友好的东西:

if( frame.empty() ) break;
vx_image image = nvx_cv::createVXImageFromCVMat(frame);
vxSetGraphParameterByIndex(graph, 0, (vx_reference) image);
vxProcessGraph( graph );
vxReleaseImage(&image);

这可能会自行解决,但我不知道是否有额外的工作要做,以通知vx_parameter p更改。