Is it possible to directly map the NvBuffer to a OpenCV GpuMat?

Currently, I was able to convert a NvBuffer directly to CPU opencv Mat by using NvBufferMemMap, NvBufferMemSyncForCpu, NvBufferMemUnMap. I was also able to convert NvBuffer to a OpenCV GpuMat by firstly converting the NvBuffer to CUEglFrame and then to OpenCV GpuMat. The second route is a little redundant cus I need to copy data from NvBuffer to CUEglFrame and then to OpenCV GpuMat. I saw there is also a NvBufferMemSyncForDevice function so i’m wondering if I can do it like the first route directly from NvBuffer to Opencv GpuMat. I quickly tried this API but I got the below error

error: (-217:Gpu API call) invalid argument in function 'download'

Not sure if my usage is correct. Is there any example? Thanks.

This is the code snippet:

                void *pdata = NULL;

                NvBufferMemMap(fd, 0, NvBufferMem_Read, &pdata);
                NvBufferMemSyncForDevice(fd, 0, &pdata);
                cv::cuda::GpuMat imgBuf = cv::cuda::GpuMat(512,
                                                  512,
                                                  CV_8UC4, pdata);

                cv::Mat cpuImgBuf;
                bb.download(cpuImgBuf);
                NvBufferMemUnMap(fd, 0, &pdata);

If I change the NvBufferMemSyncForDevice to NvBufferMemSyncForCpu, it works

Hi,
Please refer to the patches:
LibArgus EGLStream to nvivafilter - #14 by DaneLLL
Nano not using GPU with gstreamer/python. Slow FPS, dropped frames - #8 by DaneLLL

Hi, I checked both links you shared, but both links are doing NvBuffer → EglFrame → GpuMat route. My question is actually that is there a way to do NvBuffer → GpuMat directly. The reason I asked is that for Cpu Mat, I can use NvBufferMemMap and NvBufferMemSyncForCpu to directly map the NvBuffer to Mat without an intermediate EglFrame representation. But I couldn’t achieve the same when I change to NvBufferMemSyncForDevice. However, I think from the performance perspective, directly converting NvBuffer to GpuMat should be faster than relaying with EglFrame, correct?

Hi,
For mapping to GpuMat, the pointer has to be CUDA pointer, so the CUDA function calls are required. For calling NvBufferMemMap(), can get CPU pointer and map to cv::Mat.

On AGX Xavier, both GPU engine and CPU cores have good capability, so it depends on your use-case. If you need CUDA filters in OpenCV, can use GpuMat. If GPU is at high loading, it is good to use cv::Mat to shift the loading got CPU.

OK, got it. thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.