Ask Your Question
1

How to give ownership of Mat data to other structure

asked 2012-07-25 21:27:34 -0500

Pat gravatar image

updated 2012-07-26 01:20:01 -0500

Andrey Pavlenko gravatar image

I'm using OpenCV and SDL in tandem, I've declared a Mat in a function and once I'm done with it I give it's data to create an SDL_Surface, I'm assuming that once we leave the function scope the mat is recycled? I'm getting an access violation as soon as I use the sdl_surface and the data it contains is garbage.

I can also say that the function SDL_CreateRGBSurfaceFrom doesn't copy the data it uses what's stored at the pointer location.

Here's the function, I haven't written C++ in a while so perhaps I'm making a big mistake: http://pastie.org/4333990

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2012-07-26 01:09:02 -0500

sammy gravatar image

There are two ways to do it: first, use a cv::Mat whose lifetime is longer than SDL_Surface, or manually allocate a pointer.

Use an external buffer Mat. cv::Mat objects share ownership to the data. Pass a matrix to your func. Make sure it does not get deallocated until you're finished with SDL_Surface

SDL_Surface* OpenCvHandler::buildPuzzleSprite(std::string imagePath, cv::Mat& buffer)
{
     // ...
     buffer = cv::imread(imagePath.c_str());
     // ...
     SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)tiledImage.data,
            tiledImage.size().width, tiledImage.size().height, 
        imageBytes(tiledImage.depth()) * tiledImage.channels(), 
            tiledImage.step, 0xff0000, 0x00ff00, 0x0000ff, 0);
     // ...
}

Use a simple raw pointer for your data

SDL_Surface* OpenCvHandler::buildPuzzleSprite(std::string imagePath)
{
     // ...
     cv::Mat image = cv::imread(imagePath.c_str());
     char* rawPtr = new char[image.step() * image.rows()];
     memcpy(rawPtr, (char*)image.data, image.step() * image.rows())
     // ...
     SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)tiledImage.data,
            tiledImage.size().width, tiledImage.size().height, 
        imageBytes(tiledImage.depth()) * tiledImage.channels(), 
            tiledImage.step, 0xff0000, 0x00ff00, 0x0000ff, 0);
     // ...
     // Now you've got a real problem with rawPtr - 
     // you need to store it somewhere to be able to release it when the time comes
}
edit flag offensive delete link more

Comments

Consider the cv:Ptr template class usage that provides basic reference counting and stored object clean up. (http://docs.opencv.org/modules/core/doc/basic_structures.html#ptr)

Andrey Pavlenko gravatar imageAndrey Pavlenko ( 2012-07-26 01:19:06 -0500 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2012-07-25 21:27:34 -0500

Seen: 1,423 times

Last updated: Jul 26 '12