Ask Your Question
0

C++ Pointer to GpuMat

asked 2015-10-03 19:13:17 -0600

jpistorino gravatar image

updated 2015-10-05 13:03:44 -0600

I am using OpenCV 3.0 with VS2012C++/CLI on a Win 8.1 64 bit machine.

I am wondering what the proper way is to create a C++ pointer to a Gpumat.

Currently, I define a class like:

public class gpuImages
{
public:
    cuda::GpuMat *d_gpuLoadFrame;
    cuda::GpuMat *d_gpuLoadFrameClone;
    cuda::GpuMat *d_gpuAnalysisFrame;
    cuda::GpuMat *d_gpuGrayFrame;
    cuda::GpuMat *d_gpuMaskFrame;
    cuda::GpuMat *d_gpuFalseMaskFrame;    
    gpuImages();    
    ~gpuImaes();
};

gpuImages::gpuImages()
{
    d_gpuLoadFrame = new cuda::GpuMat();
    d_gpuLoadFrameClone = new cuda::GpuMat();
    d_gpuAnalysisFrame = new cuda::GpuMat();
    d_gpuGrayFrame = new cuda::GpuMat();
    d_gpuMaskFrame = new cuda::GpuMat();
    d_gpuFalseMaskFrame = new cuda::GpuMat();
}

Then, in my main code, I do things like:

dImages = new gpuImages();
dImages->d_gpuLoadFrame->upload(Some-nongpu-CVMat);
dImages->d_gpuLoadFrameClone = dImages->d_gpuLoadFrame->clone();
...

Other errors I am seeing make me think that the pointer to the GpuMats are being lost and that I might need to explicitly allocate GPU memory and track it. Seems like it kind of defeats the some of the ease of use.

If I do need to explicitly allocate and track the GPU memory, is there any example or guide? I assume that it is something like this: link. If I need to do that, cudaMalloc2d does not seem to exist any longer. What would be the correct way to do it to store a Mat with an HD image in it.

Thanks for any help. James

edit retag flag offensive close merge delete

Comments

1

why the pointers/new at all ?

i got no hands-on exp. with GpuMat, but imho, it's the same problem as with cv::Mat or cv::UMat, - if you use (raw) pointers, chances are high, that you'll wreck the internal refcount by e.g. aliasing/duplicating pointers

berak gravatar imageberak ( 2015-10-04 03:20:27 -0600 )edit

ohh, did not see the CLI thing. Please accept my condolences ;)

berak gravatar imageberak ( 2015-10-04 03:25:10 -0600 )edit

Obviously would have made a different choice had I known, but now I am too far into it. In any event, this is a WinForms app so I am not sure I had much choice. Given the other behavior I am seeing, this is clearly the issue.

jpistorino gravatar imagejpistorino ( 2015-10-04 08:08:41 -0600 )edit

why not make a struct mygpudata { gpumat a, b,c,d,e } and have a single pointer (with new) to that ?

berak gravatar imageberak ( 2015-10-04 10:26:10 -0600 )edit

So, I think the issue is that I create things like above. Then I upload some Mats to the GpuMats and also clone some GpuMats into each other. Somewhere in the process, the C++ pointers here are lost. I am wondering if you need to allocate memory on the GPU and then try and get the pointer to that using GpuMat.ptr<float>(). What do you think? I can't figure out how to ask Valdislav directly.

jpistorino gravatar imagejpistorino ( 2015-10-04 18:33:07 -0600 )edit

hmm, i meant more like:

public class gpuImages
{
public:
    cuda::GpuMat d_gpuLoadFrame;
    cuda::GpuMat d_gpuLoadFrameClone;
    ...
}; // no constructor nessecary

in other words, use new once for the struct, then just pass all cuda::GpuMat inside by reference

berak gravatar imageberak ( 2015-10-06 12:55:32 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-10-06 12:49:34 -0600

jpistorino gravatar image

The above approach will not work. The C++ pointers lose reference to the GpuMats and eventually something will be overwritten. Like all overwrite type errors, you often don't see them right away and when you do see it, it is often in a totally different area. That makes tracking these down difficult.

To fix this, I explicitly allocated the memory on the GPU and then created a GpuMat that pointed to that. So, the initialization function now looks like:

gpuImages::gpuImages(int theight,int twidth)
{
    void **LoadFrameData;

    cudaMalloc((void**)&LoadFrameData, twidth * sizeof(float) * theight);
    d_gpuLoadFrame = new cuda::GpuMat(theight,twidth,CV_32FC1,LoadFrameData);
    ... 
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-10-03 19:13:17 -0600

Seen: 2,081 times

Last updated: Oct 06 '15