OpenCV - 创建 Mat 对象数组
我本以为这是微不足道的,但我遇到了一些麻烦。
我想将视频文件读入内存并将其存储在数组中。我希望数组是指向 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);
我想,由于它显示最后一个图像,数组中的所有指针都是相同的,因此,它正在修改相同的内存。但是,当我 printf 指针时,它们是不同的。
I would have thought this is trivial, but I'm having some trouble with it.
I want to read a video file into memory and store it in an array. I want the array to be of pointers to Mat objects.
This is the code I'm using:
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]);
}
However, when I display an image (for example, the first image in the array), it displays the last frame. Where am I going wrong? This is the code for displaying the image:
cv::namedWindow("Movie", 1);
cv::imshow("Movie", *(frameArray[0]));
cv::waitKey(0);
I would imagine that, since it's displaying the last image, all the pointers in the array are the same and, therefore, it is modifying the same memory. However, when I printf the pointers, they are different.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码中还有更多缺陷。其中至少有两个是:
vidCap.get(CV_CAP_PROP_FRAME_COUNT);
大多数情况下不会返回正确的帧数。就这样,ffmpeg 不能做得更好了。对于某些编解码器它可以工作,对于某些编解码器则不行。Mat 矩阵有一个有趣的行为。它们实际上是指向矩阵数据的指针,而不是对象。当你说
new Mat
时,你只是创建了一个新的指针。结合 videoCap 始终返回相同内存区域(仅包含新数据)这一事实,您实际上将拥有一个指向最后一帧的指针向量。您必须在单独的图像中捕获该帧并将其复制到保留位置:
请注意从指针数组到对象向量的变化。这避免了预先读取帧数的需要,也使代码更安全。
There are more flaws in your code. At least two of them are:
vidCap.get(CV_CAP_PROP_FRAME_COUNT);
does not return the correct number of frames, most of the time. That's it, ffmpeg can't do better. For some codecs it works, for some, in doesn't.Mat matrices have an interesting behaviour. They are actually pointers to the matrix data, not objects. When you say
new Mat
you just create a new pointer. And combined with the fact that videoCap returns all the time the same memory area, just with new data, you acutually will have a vector of pointers pointing to the last frame.You have to capture the frame in a separate image and copy to the reserved location:
Please note the change from array of pointers to a vector of objects. This avoids the need for reading the number of frames beforehand, and also makes the code safer.
但实际上有没有一种方法可以创建 Mat 数组呢?在我的情况下,我确实没有看到其他选项,但尝试访问数组中的项目时会将数组视为单个 Mat,并认为我正在尝试访问其数据。
编辑:找到使用指针的解决方法:
But is there actually a way of creating Mat arrays? I really don't see other options in my case but trying to access an item in the array considers the array as a single Mat and thinks I'm trying to access its data.
Edit: Found a workaround using a pointer: