代码之家  ›  专栏  ›  技术社区  ›  Ken Y-N

将新cv::Mat输入vx\U图形

  •  1
  • Ken Y-N  · 技术社区  · 8 年前

    给定的示例代码如下 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 回复  |  直到 8 年前
        1
  •  2
  •   Jack C.    8 年前

    可以创建 vx_image 仅引用存储在 cv::Mat .使用 vx\U图像 访问数据最终将实际访问存储在 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\U图像 以这种方式创建的。

        2
  •  1
  •   Ken Y-N    8 年前

    我设法找到了解决方案,因为让我对示例感到困惑的是 helper function 官方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 此处表示 sobel 节点,不包括 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 的变化。