Wrap cv::cuda::GpuMat with VPIImage

Is it possible to wrap a GPU based OpenCV Mat with a VPIImage?

I know how to get the Cpu cv::Mat into an Image but upon inspection it doesnt seem clear on how to get a device memory GPU pointer to be wrapped in a VPIImage. I see vpiImageCreateHostMemWrapper which seems close, but its not clear how to tell it the source is a GPU pointer and not CPU like the vpiImageCreateOpenCVMatWrapper implies.

1 Like

Hi,

Suppose yes.
Let us give it a try and update more later.

Hi,

We modify one of our example to use GpuMat.
Please check below patch with /opt/nvidia/vpi1/samples/01-convolve_2d:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f642d1..e3f1556 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ find_package(vpi 1.0 REQUIRED)
 find_package(OpenCV REQUIRED)

 add_executable(${PROJECT_NAME} main.cpp)
+include_directories("/usr/local/cuda-10.2/include/")
 target_link_libraries(${PROJECT_NAME} vpi opencv_core)

 if(OpenCV_VERSION VERSION_LESS 3)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f642d1..e3f1556 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ find_package(vpi 1.0 REQUIRED)
 find_package(OpenCV REQUIRED)

 add_executable(${PROJECT_NAME} main.cpp)
+include_directories("/usr/local/cuda-10.2/include/")
 target_link_libraries(${PROJECT_NAME} vpi opencv_core)

 if(OpenCV_VERSION VERSION_LESS 3)
diff --git a/main.cpp b/main.cpp
index cd71d1e..246b068 100644
--- a/main.cpp
+++ b/main.cpp
@@ -29,11 +29,14 @@
 #include <opencv2/core/version.hpp>
 #if CV_MAJOR_VERSION >= 3
 #    include <opencv2/imgcodecs.hpp>
+#    include <opencv4/opencv2/core/cuda.hpp>
 #else
 #    include <opencv2/highgui/highgui.hpp>
 #endif

 #include <vpi/OpenCVInterop.hpp>
+#include <vpi/CUDAInterop.h>
+

 #include <vpi/Image.h>
 #include <vpi/Status.h>
@@ -85,6 +88,8 @@ int main(int argc, char *argv[])

         assert(cvImage.type() == CV_8UC1);

+        cv::cuda::GpuMat cvGpuImage(cvImage);
+
         // Now parse the backend
         VPIBackend backendType;

@@ -110,7 +115,15 @@ int main(int argc, char *argv[])
         CHECK_STATUS(vpiStreamCreate(backendType, &stream));

         // We now wrap the loaded image into a VPIImage object to be used by VPI.
-        CHECK_STATUS(vpiImageCreateOpenCVMatWrapper(cvImage, 0, &image));
+        VPIImageData imgData;
+        memset(&imgData, 0, sizeof(imgData));
+        imgData.format               = VPI_IMAGE_FORMAT_U8;
+        imgData.numPlanes            = 1;
+        imgData.planes[0].width      = cvGpuImage.cols;
+        imgData.planes[0].height     = cvGpuImage.rows;
+        imgData.planes[0].pitchBytes = cvGpuImage.step;
+        imgData.planes[0].data       = cvGpuImage.data;
+        CHECK_STATUS(vpiImageCreateCUDAMemWrapper(&imgData, 0, &image));

         // Now create the output image, single unsigned 8-bit channel.
         CHECK_STATUS(vpiImageCreate(cvImage.cols, cvImage.rows, VPI_IMAGE_FORMAT_U8, 0, &gradient));
$ sudo cmake .
$ sudo make
$ sudo ./vpi_sample_01_convolve_2d cuda ../assets/kodim08.png

Thanks.