OpenCV - 创建一个垫对象数组
Posted
技术标签:
【中文标题】OpenCV - 创建一个垫对象数组【英文标题】:OpenCV - Creating an Array of Mat Objects 【发布时间】:2012-02-04 04:57:34 【问题描述】:我原以为这是微不足道的,但我遇到了一些麻烦。
我想将视频文件读入内存并将其存储在数组中。我希望数组是指向 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);
我想,因为它显示的是最后一张图像,所以数组中的所有指针都是相同的,因此它正在修改相同的内存。但是,当我打印指针时,它们是不同的。
【问题讨论】:
您可能在以下线程中遇到了问题。 ***.com/questions/1356543/… 【参考方案1】:您的代码中存在更多缺陷。其中至少有两个是:
vidCap.get(CV_CAP_PROP_FRAME_COUNT);
在大多数情况下不会返回正确的帧数。就是这样,ffmpeg不能做得更好。对于某些编解码器,它可以工作,而对于某些编解码器,则不能。
Mat 矩阵有一个有趣的行为。它们实际上是指向矩阵数据的指针,而不是对象。当您说new Mat
时,您只需创建一个新指针。结合 videoCap 始终返回相同内存区域的事实,仅使用新数据,您实际上将有一个指向最后一帧的指针向量。
您必须在单独的图像中捕获帧并复制到保留位置:
std::vector<cv::Mat> frames;
cap >> frame;
frames.push_back(frame.clone());
请注意从指针数组到对象向量的变化。这样就避免了事先读取帧数的需要,也让代码更安全。
【讨论】:
感谢您的回答!我发现“cap >> frame”填充了每个 Mat 对象的参数,但没有复制数据。为了解决这个问题,我从堆中获取了一些内存,将数据复制到该内存,然后设置“frame.data = myMemoryPtr”,其中 myMemoryPtr 是指向已分配内存的指针。 这与 frame.copyTo() 相同。我更喜欢我的版本,因为它很干净,而且 OpenCV 会在不再使用时自动释放内存 关于你的第一点,有没有办法解决这个问题?如何找到视频中的帧数? 没有什么值得努力的。但是您可以使用动态数组来保存帧。vector但实际上有一种方法可以创建 Mat 数组吗?在我的情况下,我真的没有看到其他选项,但尝试访问数组中的项目会将数组视为单个 Mat 并认为我正在尝试访问其数据。
编辑:找到使用指针的解决方法:
Mat* array = new Mat[arraySize];
【讨论】:
我是否理解正确,您创建此帖子是为了提出与此页面顶部的问题不同的问题,然后对其进行了编辑,以回答您自己的问题,该问题没有回答本页顶部? 即使我错了,请拿tour阅读How to Answer。 这没有提供问题的答案。您可以search for similar questions,或参考页面右侧的相关和链接问题找到答案。如果您有一个相关但不同的问题,ask a new question,并包含指向此问题的链接以帮助提供上下文。见:Ask questions, get answers, no distractions以上是关于OpenCV - 创建一个垫对象数组的主要内容,如果未能解决你的问题,请参考以下文章