Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV - copy CUDA device data into GPU Mat

Tags:

opencv

cuda

Is there a way to directly copy previously allocated CUDA device data into an OpenCV GPU Mat? I would like to copy my data, previously initialized and filled by CUDA, into the OpenCV GPU mat. I would like to do so because I want solve a linear system of equations Ax = B by computing the inverse of the matrix A using OpenCV.

What I want to do is something like this:

float *dPtr; 
gpuErrchk( cudaMalloc( (void**) &dPtr, sizeof(float) * height * width));    
gpuErrchk( cudaMemset(dPtr, 0, sizeof(float) * height * width));

// modify dPtr in some way on the GPU 
modify_dPtr(); 

// copy previously allocated and modified dPtr into OpenCV GPU mat? 

// process GPU mat later - e.x. do a matrix inversion operation. 

// extract raw pointer from GPU mat

EDIT: The OpenCV documentation provides a GPU upload function.

Can the device pointer just be passed into that function as a parameter? If not, is there no other way to do such a data transfer? I don't want to copy data back and forth between the host and device memory, do my computation on a normal OpenCV Mat container, and copy back the results; my application is real-time. I am assuming that since there is no .at() function for a GPU Mat, as in the normal OpenCV Mat, there is no way to access the element at a particular location in the matrix? Also, does an explicit matrix inversion operation exist for the GPU Mat? The documentation does not provide a GPU Mat inv() function.

like image 250
Eagle Avatar asked Feb 11 '23 21:02

Eagle


1 Answers

Just as talonmies posted in the comments, there is a constructor in the header of the GPU mat structure that allows the creation of a GPUMat header pointing to my previously allocated CUDA device data. This is what I had used:

cv::gpu::GpuMat dst(height, width, CV_32F, d_Ptr);

There is no need to figure out the step size because the constructor automatically evaluates it, given the width and height of the image. Hopefully, when the support for OpenCV GPU functions becomes better, this post may be useful to someone.

EDIT

Another (probably) useful way is to utilize unified memory in CUDA. Pass the data into an OpenCV GPU and CPU mat, and continue operations from there.

like image 179
Eagle Avatar answered Feb 19 '23 03:02

Eagle