C++/cv::Mat相当于使用memcpy创建IplImage

C++ / cv::Mat equivalent of creating IplImage using memcpy

本文关键字:memcpy 创建 IplImage 相当于 cv Mat C++      更新时间:2023-10-16

我收到了一些代码,其中使用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);

内存是指向内存块开头的空指针。

我想移植此代码以仅使用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),所以我想会涉及到一些不必要的复制。

正确的方法是什么?

编辑:内存实际上在一个包装类中。它会自动解除分配。为了简单起见,我把它改成了"记忆"。

编辑2:这是完整的代码,包括内存来自的对象:

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();
    }
}

问题是memory->getSharedMemory()中的数据被释放,而矩阵仍然有效。

OpenCV在基础数据上创建了一个矩阵头,但无法控制它。因此,您需要对这些基础数据进行深入复制。最简单的方法是使用clone():

cv::Mat image = Mat(cv::Size(imageWidth, imageHeight), CV_MAKETYPE(CV_8U, bytesPerPixel), memory->getSharedMemory()).clone();