我希望从~30秒(30fps)的视频中获取并保存所有帧。
程序VirtualDub向我显示我的电影有930帧,但我的程序只保存了474.我的代码如下:
string name = @"D:\movie-01-no.avi";
Capture _capture = new Capture(name);
int frame = 0;
while (_capture.Grab())
{
frame++;
Image<Bgr, byte> image = _capture.RetrieveBgrFrame();
Bitmap bmp = new Bitmap(image.ToBitmap());
bmp.Save(@"D:\" + frame + ".bmp");
bmp.Dispose();
}
或
string name = @"D:\movie-01-no.avi";
Capture _capture = new Capture(name);
int frame = 0;
bool Reading = true;
while (Reading)
{
frame++;
Image<Bgr, Byte> image = _capture.QueryFrame();
if (image != null)
{
Bitmap bmp = new Bitmap(image.ToBitmap());
bmp.Save(@"D:\" + frame + ".bmp");
bmp.Dispose();
}
else
{
Reading = false;
}
}
在这两种情况下,它都不会保存930帧。为什么?我怎么解决它?
答案 0 :(得分:0)
我找到了解决方案。这个程序工作正常。在视频描述中是视频具有30 FPS的信息。 VirtualDub还显示30 FPS。但VirtualDub复制帧以从描述中获取帧的值。视频有15 FPS,但ViurualDub每隔一帧复制一次,看起来像30 FPS。如果使用标准摄像机录制视频,则必须知道当视频中的帧较暗时,摄像机会记录15 FPS。相机在明亮的地方记录30 FPS。我已经用Lumix相机和笔记本电脑Acer中的内置网络相机检查了这个。
答案 1 :(得分:0)
我很难在Egmu CV V3.0.0下找到有关Capture的任何文档
执行一些追踪和错误测试,我发现它看起来Grab和QueryFrame都处理一个帧,有效地使Grab()每个循环丢弃一帧。 此代码似乎提供了所需的结果:
video = new Capture(filename);
bool reading;
int nframes = (int)video.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameCount);
nframes++;
Mat frame;
Image<Bgr, byte> image;
int i = 0;
reading = true;
while (reading)
{
frame = video.QueryFrame();
if (frame != null)
{
image = frame.ToImage<Bgr, byte>();
mainPic.Image = image.ToBitmap();
image.Dispose();
frame.Dispose();
}
else
{
reading = false;
}
i++;
}