[英]C++ / cv::Mat equivalent of creating IplImage using memcpy
I was handed some code where an IplImage is created using memcpy and then converted to a cv::Mat: 我被传递了一些代码,其中使用memcpy创建了IplImage,然后转换为cv :: Mat:
IplImage* iplImage = cvCreateImage(cv::Size(imageWidth, imageHeight), IPL_DEPTH_8U, bytesPerPixel);
memcpy(iplImage->imageData, memory, imageWidth * imageHeight * bytesPerPixel);
cv::Mat image = cv::cvarrToMat(iplImage, true, true, 0);
cvReleaseImage(&iplImage);
memory is a void pointer to the beginning of a memory block. memory是指向内存块开头的void指针。
I want to port this code to use only the OpenCV C++ Api. 我想将此代码移植到仅使用OpenCV C ++ Api。 This is what I tried first:
这是我首先尝试的:
cv::Mat image(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel), memory);
But the image is empty. 但是图像是空的。
Then I tried this: 然后我尝试了这个:
cv::Mat image(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel));
memcpy(image.data, memory, imageWidth * imageHeight * bytesPerPixel);
This method works, however it uses up a lot more RAM (about 100mb), so I guess there is some unnecessary copying involved. 这种方法有效,但它占用了更多的RAM(大约100mb),所以我猜有一些不必要的复制。
What would be the correct way to do this? 这样做的正确方法是什么?
EDIT: Memory is really in a wrapper class. 编辑:内存实际上是一个包装类。 It gets deallocated automatically.
它会自动解除分配。 I changed it to just "memory" for simplicity.
为简单起见,我将其改为“记忆”。
EDIT2: Here is the complete code, including the object the memory comes from: EDIT2:这是完整的代码,包括内存来自的对象:
cv::Mat RecordingPlayer::next() {
if (currentContainer.getDataType() == odcore::data::image::SharedImage::ID()) {
odcore::data::image::SharedImage sharedImage = currentContainer.getData<odcore::data::image::SharedImage>();
std::shared_ptr<odcore::wrapper::SharedMemory> memory = odcore::wrapper::SharedMemoryFactory::attachToSharedMemory(sharedImage.getName());
IplImage* iplImage = cvCreateImage(imageSize(), IPL_DEPTH_8U, bytesPerPixel);
memcpy(iplImage->imageData, memory->getSharedMemory(), imageWidth * imageHeight * bytesPerPixel);
cv::Mat image = cv::cvarrToMat(iplImage, true, true, 0);
cvReleaseImage(&iplImage);
return image;
} else {
return cv::Mat();
}
}
The issue is that data in memory->getSharedMemory()
are deallocated while the matrix is still valid. 问题是当矩阵仍然有效时,
memory->getSharedMemory()
中的数据被释放。
OpenCV creates a matrix header on the underlying data, but doesn't have control over it. OpenCV在基础数据上创建矩阵标头,但无法控制它。 So you need to make a deep copy of those underlying data.
因此,您需要对这些基础数据进行深层复制。 Easiest way is to use
clone()
: 最简单的方法是使用
clone()
:
cv::Mat image = Mat(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel), memory->getSharedMemory()).clone();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.