Подача нового cv :: Mat в vx_graph - PullRequest
0 голосов
/ 25 апреля 2018

Данный пример кода, такой как в этом предыдущем вопросе (проверка ошибок удалена для краткости):

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 голосов
/ 25 апреля 2018

Мне удалось найти решение, так как в примерах меня смутило использование вспомогательной функции , отсутствующей в официальном 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-й параметр для узла sobel, исключая *Сам 1014 *.

Далее мой цикл становится следующим:

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 изменения.

0 голосов
/ 25 апреля 2018

Можно создать vx_image, который ссылается только на данные, хранящиеся в cv::Mat.Что-то, использующее vx_image для доступа к данным, в конечном итоге получит доступ к данным, хранящимся в Mat.Этот подход использует только документированные функции OpenCV и OpenVX .Из этой документации Intel :

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, созданный таким образом.

...