How to use Mat as a C++ member correctly?
Using VS 2012 with OpenCV 2.4.10
I am grabbing an image from a Basler camera in a thread class in my DLL and and converting it to an OpenCV Mat. I then pass it to an CameraImage class that is created using new and add it to a queue where another thread writes it out to disk and deletes the instance.
I find that whether I assign, clone(), copyTo(), or create/memcpy image to CameraImage.mImage when I delete the instance of CameraImage, mImage does not delete the image data and around the 86th image the create Mat throws an exception which means that it cannot allocate the memory for the new image. I thought the smart pointer takes care of the data memory allocation/deallocation automatically as well as refcount. I even call mImage.release() in the CameraImage destructor. I have used assert() to check on the refcount(s) (not shown).
Image Grab function called by thread
void CImageWriter::Grab()
{
...
mCamera.GrabImage(result);
cv::Mat image;
ConvertToMat(image, result.GetImage());
CameraImage *cameraImage = new CameraImage(image);
// Send it to the write queue thread.
mWriteQueueThread.QueueToWrite(cameraImage);
...
}
Converting to Mat
void CImageWriter::ConvertToMat(cv::Mat &image, Pylon::IImage &pylonImage, ImageRotation rotateDegrees)
{
Pylon::CImageFormatConverter converter;
Pylon::CPylonImage target;
converter.OutputPixelFormat = Pylon::PixelType::PixelType_BGR8packed;
converter.OutputBitAlignment = Pylon::OutputBitAlignmentEnums::OutputBitAlignment_MsbAligned;
converter.Convert(target, pylonImage);
image.create(target.GetHeight(), target.GetWidth(), CV_8UC3);
// copies from Result.Buffer into img
memcpy(image.ptr(), target.GetBuffer(), 3*target.GetWidth()*target.GetHeight());
Rotate(image, image, rotateDegrees);
}
The Image Class
class CameraImage
{
public:
CameraImage(cv::Mat &image);
~CameraImage();
void WriteToDisk(void);
protected:
cv::Mat mImage;
};
CameraImage::CameraImage(cv::Mat &image)
{
mImage = image; or mImage = image.clone(); or image.copyTo(mImage);
or
mImage.create(image.rows, image.cols, CV_8UC3);
memcpy(mImage.ptr(), image.ptr(), 3 * image.rows * image.cols);
}
CameraImage::~CameraImage()
{
mImage.release();
}
Is this the proper way to use Mat as a C++ member? What am I doing wrong?
Hello I have a similar problem with opencv. I try to keep in Memory some pointer to Mat object in a buffer. For freed my Mat object, i use mat->release then à delete on this ptr. When I let the delete the program crash. When I suppress the delete it creates a Memory leak. Could you please propose a solution?