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

时间:2016-05-17 12:20:00

标签: c++ opencv

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

1 个答案:

答案 0 :(得分:4)

问题是当矩阵仍然有效时,class-{-}.sublime-snippet中的数据被释放。

OpenCV在基础数据上创建矩阵标头,但无法控制它。因此,您需要对这些基础数据进行深层复制。最简单的方法是使用memory->getSharedMemory()

clone()