OpenCV - 创建Mat对象数组

时间:2012-02-04 04:57:34

标签: c++ opencv

我原本以为这是微不足道的,但我遇到了一些麻烦。

我想将视频文件读入内存并将其存储在数组中。我希望数组是指向Mat对象的指针。

这是我正在使用的代码:

cv::VideoCapture vidCap = cv::VideoCapture("file.avi");
int frames = (int)vidCap.get(CV_CAP_PROP_FRAME_COUNT);
cv::Mat** frameArray = new cv::Mat*[frames];
for (int num = 0; num < frames; num++) {
     frameArray[num] = new cv::Mat;
     vidCap >> *(frameArray[num]);
}

但是,当我显示图像(例如,数组中的第一个图像)时,它会显示 last 帧。我哪里错了?这是显示图像的代码:

cv::namedWindow("Movie", 1);
cv::imshow("Movie", *(frameArray[0]));
cv::waitKey(0);

我会想象,因为它显示的是最后一个图像,所以数组中的所有指针都是相同的,因此,它正在修改相同的内存。但是,当我打印指针时,它们是不同的。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

您的代码中存在更多缺陷。其中至少有两个是:

  1. vidCap.get(CV_CAP_PROP_FRAME_COUNT);在大多数情况下都不会返回正确的帧数。就是这样,ffmpeg无法做得更好。对于某些编解码器,它可以工作,对某些人来说,它不适用。

  2. Mat矩阵有一个有趣的行为。它们实际上是指向矩阵数据的指针,而不是对象。当你说new Mat时,你只需创建一个新指针。结合videoCap一直返回相同内存区域的事实,只需要使用新数据,你实际上会有一个指向最后一帧的指针向量。

  3. 您必须在单独的图像中捕获帧并复制到保留位置:

    std::vector<cv::Mat> frames;
    cap >> frame;
    frames.push_back(frame.clone());
    

    请注意从指针数组到对象矢量的更改。这样就不需要事先读取帧数,也可以使代码更安全。

答案 1 :(得分:0)

但是实际上有一种创建Mat数组的方法吗?我确实没有看到其他选项,但是尝试访问数组中的项目会将数组视为单个Mat,并认为我正在尝试访问其数据。

编辑:找到了使用指针的解决方法:

Mat* array = new Mat[arraySize];