我原本以为这是微不足道的,但我遇到了一些麻烦。
我想将视频文件读入内存并将其存储在数组中。我希望数组是指向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);
我会想象,因为它显示的是最后一个图像,所以数组中的所有指针都是相同的,因此,它正在修改相同的内存。但是,当我打印指针时,它们是不同的。
提前感谢您的帮助。
答案 0 :(得分:3)
您的代码中存在更多缺陷。其中至少有两个是:
vidCap.get(CV_CAP_PROP_FRAME_COUNT);
在大多数情况下都不会返回正确的帧数。就是这样,ffmpeg无法做得更好。对于某些编解码器,它可以工作,对某些人来说,它不适用。
Mat矩阵有一个有趣的行为。它们实际上是指向矩阵数据的指针,而不是对象。当你说new Mat
时,你只需创建一个新指针。结合videoCap一直返回相同内存区域的事实,只需要使用新数据,你实际上会有一个指向最后一帧的指针向量。
您必须在单独的图像中捕获帧并复制到保留位置:
std::vector<cv::Mat> frames;
cap >> frame;
frames.push_back(frame.clone());
请注意从指针数组到对象矢量的更改。这样就不需要事先读取帧数,也可以使代码更安全。
答案 1 :(得分:0)
但是实际上有一种创建Mat数组的方法吗?我确实没有看到其他选项,但是尝试访问数组中的项目会将数组视为单个Mat,并认为我正在尝试访问其数据。
编辑:找到了使用指针的解决方法:
Mat* array = new Mat[arraySize];