对于我正在开发的教育游戏,我需要捕捉网络摄像头视频,进行实时人脸跟踪,做标记检测,显示增强和播放声音。由于这是对现有Silverlight游戏的重建,我决定在WPF中构建它,因此我可以重用XAML。
使用EmguCv库中的函数成功实现了所有与图形相关的要求(捕获,检测,跟踪等)。
据我所知,为了在WPF应用程序中播放音频(mp3文件),我有几个选择:
现在,一切似乎都很好。我可以使用上述任何方法播放mp3文件。
问题是播放mp3文件,同时捕获网络摄像头帧导致Emgu.CV.Capture
以某种方式总是返回相同的帧。如果我要求Capture对象在默认情况下水平翻转框架(更自然),我会在每个请求上翻转相同的框架(所以ltr-rtl-ltr-rtl-ect。)。即使在完成mp3文件的播放之后,Capture对象也会陷入这种明显的无限循环中。
在我看来,Capture实际上不再捕获任何东西了,但只是一遍又一遍地返回最后抓取的帧。
不会抛出任何异常,但会出现CPU峰值。分析器(Jetbrains)告诉我Capture.QueryFrame
方法使用大多数CPU周期。
在一个小型演示程序下面重现问题:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Emgu.CV;
namespace DI.Sandbox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly Capture _capture;
private readonly MediaPlayer _player;
private readonly DispatcherTimer _timer;
public MainWindow()
{
InitializeComponent();
_capture = new Capture { FlipHorizontal = true };
_player = new MediaPlayer { Volume = 1 };
_timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(1000/24)};
_timer.Tick += GameLoop;
}
private void GameLoop(object sender, EventArgs e)
{
using (var grab = _capture.QueryFrame())
{
Capture.Source = BitmapSourceConvert.ToBitmapSource(grab);
}
}
private void Start_Click(object sender, RoutedEventArgs e)
{
_timer.Start();
}
private void Play_Click(object sender, RoutedEventArgs e)
{
_player.Open(new Uri("assets\\test.mp3", UriKind.Relative));
_player.Play();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
_player.Stop();
_timer.Stop();
}
}
}
......和......
<Window x:Class="DI.Sandbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpenCV Face Tracking Experiment" Width="800" Height="600" ResizeMode="NoResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Name="Start" Width="100" Height="25" Click="Start_Click" Grid.Column="0">Start</Button>
<Button Name="Play" Width="100" Height="25" Click="Play_Click" Grid.Column="1">Play</Button>
<StackPanel Orientation="Horizontal" Grid.Column="1">
<TextBlock Name="Answer" TextAlignment="Center" VerticalAlignment="Center" Width="100"></TextBlock>
<TextBlock Name="Elapsed" TextAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>
<Button Name="Stop" Width="100" Height="25" Click="Stop_Click" Grid.Column="2">Stop</Button>
</Grid>
<Image Name="Capture" Grid.Row="1" Width="640" Height="480" Margin="5"></Image>
</Grid>
</Window>
最奇怪的是,我可以复制同样的问题,运行我的应用程序而不播放音频,然后在Windows Media Player中播放任何mp3文件!
问题:
更新:我仅在Windows 8上对此进行了测试