我收到了一些代码,其中使用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是指向内存块开头的void指针。
我想将此代码移植到仅使用OpenCV C ++ Api。这是我先试过的:
cv::Mat image(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel), memory);
但图像是空的。
然后我尝试了这个:
cv::Mat image(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel));
memcpy(image.data, memory, imageWidth * imageHeight * bytesPerPixel);
这种方法有效,但是它占用了更多的RAM(大约100mb),所以我猜有一些不必要的复制。
这样做的正确方法是什么?
编辑:内存实际上是一个包装类。它会自动解除分配。为简单起见,我将其改为“记忆”。
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();
}
}
答案 0 :(得分:4)
问题是当矩阵仍然有效时,class-{-}.sublime-snippet
中的数据被释放。
OpenCV在基础数据上创建矩阵标头,但无法控制它。因此,您需要对这些基础数据进行深层复制。最简单的方法是使用memory->getSharedMemory()
:
clone()