我正在尝试从磁盘打开一个视频文件,并尝试在visual studio c#中使用openCV wrapper: Emgu CV播放它。我正在使用Emgu CV提供的imagebox在表单上显示我的视频。我使用以下代码计算显示下一帧视频的等待时间:
await Task.Delay(Convert.ToInt32( 1000.0 / FPS));问题是视频的播放速度比计算公式慢。我打开一个29.97FPS的视频文件,公式应该返回(1000/30)=33。但当我播放视频时,我可以立即看到视频的播放速度低于33FPS。如果我右击imagebox转到imagebox属性,它会显示FPS为21,我猜这是正在播放的实际FPS视频。这是怎么回事?
这是我的代码。这很基本:
public partial class Form1 : Form
{
VideoCapture videoCapture;
double FPS;
double totalFrames;
int currentFrameNo;
public Form1()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
videoCapture = new VideoCapture(ofd.FileName);
FPS = videoCapture.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps);
totalFrames = videoCapture.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameCount);
currentFrameNo = 0;
}
}
private async void btnPlay_Click(object sender, EventArgs e)
{
while (currentFrameNo<totalFrames)
{
imageBox1.Image = videoCapture.QueryFrame();
currentFrameNo += 1;
await Task.Delay(Convert.ToInt32( 1000.0 / FPS));
}
}
}我想要的是一个流畅的演奏。应该做些什么改变?很抱歉我说了这么糟糕的话。
发布于 2018-03-27 00:14:56
正如其他评论所建议的那样-问题是,无论循环处理时间是多少,都会增加一个恒定的延迟。
更好的解决方案是使用计时器(粗略地说!)如下所示:
bool playingVideo = false;
Timer frameTimer = new Timer(this.GrabFrame, null, 0, 1000 / 33);
private void btnPlay_Click(object sender, EventArgs e)
{
playingVideo = true;
}
private void GrabFrame(object sender, EventArgs e)
{
if(playingVideo)
{
while (currentFrameNo<totalFrames)
{
imageBox1.Image = videoCapture.QueryFrame();
currentFrameNo += 1;
}
}
}这样,无论捕获时间如何,都将每隔33ms请求一次帧
https://stackoverflow.com/questions/49364876
复制相似问题