c++ - OpenCV - 创建一个 Mat 对象数组

标签 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]);
}

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

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

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

最佳答案

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

  1. vidCap.get(CV_CAP_PROP_FRAME_COUNT); 大多数时候不会返回正确的帧数。就是这样,ffmpeg不能做得更好了。对于某些编解码器,它可以工作,而对于某些编解码器,则不能。

  2. Mat 矩阵有一个有趣的行为。它们实际上是指向矩阵数据的指针,而不是对象。当您说 new Mat 时,您只是创建了一个新指针。结合 videoCap 始终返回同一内存区域这一事实,仅使用新数据,您实际上将拥有一个指向最后一帧的指针 vector 。

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

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

请注意从指针数组到对象 vector 的变化。这避免了预先读取帧数的需要,也使代码更安全。

关于c++ - OpenCV - 创建一个 Mat 对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9138537/

相关文章:

c++ - 使用 openCV 在图像中查找 "Missing"对象

OpenCV 期望最大化

c++ - 为什么注释参数名称而不是保持原样

c++ - 删除 Glut/FreeGlut/GLFW 的控制台窗口?

python - 如何提取图像的边界(OCT/视网膜扫描图像)

python - OpenCV-检测颜色范围并在控制台上显示

Python OpenCV : Crop image to contents,并使背景透明

java - 如何构建 libprotobuf-lite.so

c++ - 将指针值转换为字符串并再次返回

c++ - 根据字符串中的索引在 C++ 中对字符串 vector 进行排序