EmguCv网络摄像头捕获与Windows Media Player冲突

时间:2014-01-08 17:09:41

标签: c# wpf opencv emgucv windows-media-player

对于我正在开发的教育游戏,我需要捕捉网络摄像头视频,进行实时人脸跟踪,做标记检测,显示增强和播放声音。由于这是对现有Silverlight游戏的重建,我决定在WPF中构建它,因此我可以重用XAML。

使用EmguCv库中的函数成功实现了所有与图形相关的要求(捕获,检测,跟踪等)。

据我所知,为了在WPF应用程序中播放音频(mp3文件),我有几个选择:

  1. 使用MediaElement(需要Windows Media Player)
  2. 使用MediaPlayer类(需要Windows Media Player)< == Preferred
  3. 使用(唯一的?)第三方库,如NAudio
  4. 现在,一切似乎都很好。我可以使用上述任何方法播放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文件!

    问题:

    1. 还有其他人遇到过这个问题吗? (我用谷歌搜索,但没有发现类似的报道)
    2. 有没有人知道解决方法?
    3. 我还有什么其他选择来播放我的WPF应用中的音频?
    4. 更新:我仅在Windows 8上对此进行了测试

0 个答案:

没有答案