www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 嵌入式 > 嵌入式硬件

1. 使用定向麥克風進行波速追蹤(Beam Tracking for a Directional Microphone)

可以使用這4個麥克風來模擬定向麥克風產生的效果,這個過程稱之為波束追蹤(beam tracking),為此我們新建一個WPF項目,過程如下:

1. 創(chuàng)建一個名為KinectFindAudioDirection的WPF項目。

2. 添加對Microsoft.Kinect.dll和Microsoft.Speech.dll的引用。

3. 將主窗體的名稱改為“Find Audio Direction”

4. 在主窗體中繪制一個垂直的細長矩形。

界面上的細長矩形用來指示某一時刻探測到的說話者的語音方向。矩形有一個旋轉變換,在垂直軸上左右擺動,以表示聲音的不同來源方向。前端頁面代碼:

<Rectangle Fill="#1BA78B" HorizontalAlignment="Left" Margin="240,41,0,39" Stroke="Black" Width="10" RenderTransformOrigin="0.5,0">    <Rectangle.RenderTransform>        <TransformGroup>            <ScaleTransform/>            <SkewTransform/>            <RotateTransform Angle="{Binding BeamAngle}"/>            <TranslateTransform/>        </TransformGroup>    </Rectangle.RenderTransform></Rectangle>

pic1

上圖是程序的UI界面。后臺邏輯代碼和之前的例子大部分都是相同的。首先實例化一個KinectAudioSource對象,然后將主窗體的DataContext賦值給本身。將BeamAngleMode設置為Adaptive,使得能夠自動追蹤說話者的聲音。我們需要編寫KinectAudioSource對象的BeamChanged事件對應的處理方法。當用戶的說話時,位置發(fā)生變化時就會觸發(fā)該事件。我們需要創(chuàng)建一個名為BeamAngle的屬性,使得矩形的RotateTransform可以綁定這個屬性。

public partial class MainWindow : Window, INotifyPropertyChanged{    public MainWindow()    {        InitializeComponent();        this.DataContext = this;        this.Loaded += delegate { ListenForBeamChanges(); };    }    private KinectAudioSource CreateAudioSource()    {        var source = KinectSensor.KinectSensors[0].AudioSource;        source.NoiseSuppression = true;        source.AutomaticGainControlEnabled = true;        source.BeamAngleMode = BeamAngleMode.Adaptive;        return source;    }    private void ListenForBeamChanges()    {        KinectSensor.KinectSensors[0].Start();        var audioSource = CreateAudioSource();        audioSource.BeamAngleChanged += audioSource_BeamAngleChanged;        audioSource.Start();    }    public event PropertyChangedEventHandler PropertyChanged;    private void OnPropertyChanged(string propName)    {        if (PropertyChanged != null)            PropertyChanged(this, new PropertyChangedEventArgs(propName));    }    private double _beamAngle;    public double BeamAngle    {        get { return _beamAngle; }        set        {            _beamAngle = value;            OnPropertyChanged("BeamAngle");        }    }}

以上代碼中,還需要對BeamChanged事件編寫對應的處理方法。每次當波束的方向發(fā)生改變時,就更改BeamAngle的屬性。SDK中使用弧度表示角度。所以在事件處理方法中我們需要將弧度換成度。為了能達到說話者移到左邊,矩形條也能夠向左邊移動的效果,我們需要將角度乘以一個-1。代碼如下:

void audioSource_BeamAngleChanged(object sender, BeamAngleChangedEventArgs e){    BeamAngle = -1 * e.Angle;}

運行程序,然后在房間里不同地方走動,可以看到矩形條會根據你的位置左右擺動。

pic2w

2. 語音命令識別

在這一部分,我們將會結合KinectAudioSource和SpeechRecognitionEngine來演示語音命令識別的強大功能。為了展示語音命令能夠和骨骼追蹤高效結合,我們會使用語音命令向窗體上繪制圖形,并使用命令移動這些圖形到光標的位置。命令類似如下:

Create a yellow circle, there.

Create a cyan triangle, there.

Put a magenta square, there.

Create a blue diamond, there.

Move that ... there.

Put that ... there.

Move that ... below that.

Move that ... west of the diamond.

Put a large green circle ... there.

程序界面大致如下:

pic4w

和之前的應用程序一樣,首先創(chuàng)建一下項目的基本結構:

1. 創(chuàng)建一個名為KinectPutThatThere的WPF項目。

2. 添加對Microsoft.Kinect.dll和Microsoft.Speech.dll的引用。

3. 將主窗體的名稱改為“Put That There”

4. 添加一個名為CrossHairs.xaml的用戶自定義控件。

CrossHair用戶控件簡單的以十字光標形式顯示當前用戶右手的位置。下面的代碼顯示了這個自定義控件的XAML文件。注意到對象于容器有一定的偏移使得十字光標的中心能夠處于Grid的零點。

<Grid Height="50" Width="50" RenderTransformOrigin="0.5,0.5">    <Grid.RenderTransform>        <TransformGroup>            <ScaleTransform/>            <SkewTransform/>            <RotateTransform/>            <TranslateTransform X="-25" Y="-25"/>        </TransformGroup>    </Grid.RenderTransform>    <Rectangle Fill="#FFF4F4F5" Margin="22,0,20,0" Stroke="#FFF4F4F5"/>    <Rectangle Fill="#FFF4F4F5" Margin="0,22,0,21" Stroke="#FFF4F4F5"/>  </Grid>

在應用程序的主窗體中,將根節(jié)點從grid對象改為canvas對象。Canvas對象使得將十字光標使用動畫滑動到手的位置比較容易。在主窗體上添加一個CrossHairs自定義控件。在下面的代碼中,我們可以看到將Canvas對象嵌套在了一個Viewbox控件中。這是一個比較老的處理不同屏幕分辨率的技巧。ViewBox控件會自動的將內容進行縮放以適應實際屏幕的大小。設置MainWindows的背景色,并將Canvas的顏色設置為黑色。然后在Canvas的底部添加兩個標簽。一個標簽用來顯示SpeechRecognitionEngine將要處理的語音指令,另一個標簽顯示匹配正確的置信度。CrossHair自定義控件綁定了HandTop和HandLeft屬性。兩個標簽分別綁定了HypothesizedText和Confidence屬性。代碼如下:

<Window x:Class="KinectPutThatThere.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:local="clr-namespace:KinectPutThatThere"        Title="Put That There"  Background="Black">    <Viewbox>        <Canvas x:Name="MainStage" Height="1080" Width="1920" Background="Black" VerticalAlignment="Bottom">            <local:CrossHairs Canvas.Top="{Binding HandTop}" Canvas.Left="{Binding HandLeft}" />                <Label  Foreground="White"  Content="{Binding HypothesizedText}" Height="55"   FontSize="32" Width="965"  Canvas.Left="115" Canvas.Top="1025" />            <Label Foreground="Green" Content="{Binding Confidence}" Height="55"  Width="114" FontSize="32" Canvas.Left="0" Canvas.Top="1025"  />        </Canvas>    </Viewbox></Window>

在后臺邏輯代碼中,讓MainWindows對象實現INofityPropertyChanged事件并添加OnPropertyChanged幫助方法。我們將創(chuàng)建4個屬性用來為前臺UI界面進行綁定。

public partial class MainWindow : Window, INotifyPropertyChanged{    private double _handLeft;    public double HandLeft    {        get { return _handLeft; }        set        {            _handLeft = value;            OnPropertyChanged("HandLeft");        }    }    private double _handTop;    public double HandTop    {        get { return _handTop; }        set        {            _handTop = value;            OnPropertyChanged("HandTop");        }    }    private string _hypothesizedText;    public string HypothesizedText    {        get { return _hypothesizedText; }        set        {            _hypothesizedText = value;            OnPropertyChanged("HypothesizedText");        }    }    private string _confidence;    public string Confidence    {        get { return _confidence; }        set        {            _confidence = value;            OnPropertyChanged("Confidence");        }    }    public event PropertyChangedEventHandler PropertyChanged;    private void OnPropertyChanged(string propertyName)    {        if (PropertyChanged != null)        {            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));        }    }}

添加CreateAudioSource方法,在該方法中,將KinectAudioSource對象的AutoGainControlEnabled的屬性設置為false。

private KinectAudioSource CreateAudioSource(){    var source = KinectSensor.KinectSensors[0].AudioSource;    source.AutomaticGainControlEnabled = false;    source.EchoCancellationMode = EchoCancellationMode.None;    return source;}

接下來實現骨骼追蹤部分邏輯來獲取右手的坐標,相信看完骨骼追蹤那兩篇文章后這部分的代碼應該會比較熟悉。首先創(chuàng)建一個私有字段_kinectSensor來保存當前的KienctSensor對象,同時創(chuàng)建SpeechRecognitionEngine對象。在窗體的構造函數中,對這幾個變量進行初始化。例外注冊骨骼追蹤系統(tǒng)的Skeleton事件并將主窗體的DataContext對象賦給自己。

KinectSensor _kinectSensor;SpeechRecognitionEngine _sre;KinectAudioSource _source;public MainWindow(){    InitializeComponent();    this.DataContext = this;    this.Unloaded += delegate    {        _kinectSensor.SkeletonStream.Disable();        _sre.RecognizeAsyncCancel();        _sre.RecognizeAsyncStop();        _sre.Dispose();    };    this.Loaded += delegate    {        _kinectSensor = KinectSensor.KinectSensors[0];        _kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters()        {            Correction = 0.5f,            JitterRadius = 0.05f,            MaxDeviationRadius = 0.04f,            Smoothing = 0.5f        });        _kinectSensor.SkeletonFrameReady += nui_SkeletonFrameReady;        _kinectSensor.Start();        StartSpeechRecognition();    };}

在上面的代碼中,我們添加了一些TransformSmoothParameters參數來使得骨骼追蹤更加平滑。nui_SkeletonFrameReady方法如下。方式使用骨骼追蹤數據來獲取我們感興趣的右手的關節(jié)點位置。這部分代碼和之前文章中的類似。大致流程是:遍歷當前處在追蹤狀態(tài)下的骨骼信息。然后找到右手關節(jié)點的矢量信息,然后使用SkeletonToDepthImage來獲取相對于屏幕尺寸的X,Y坐標信息。

void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e){    using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())    {        if (skeletonFrame == null)            return;        var skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];        skeletonFrame.CopySkeletonDataTo(skeletons);        foreach (Skeleton skeletonData in skeletons)        {            if (skeletonData.TrackingState == SkeletonTrackingState.Tracked)            {                Microsoft.Kinect.SkeletonPoint rightHandVec = skeletonData.Joints[JointType.HandRight].Position;                var depthPoint = _kinectSensor.MapSkeletonPointToDepth(rightHandVec                    , DepthImageFormat.Resolution640x480Fps30);                HandTop = depthPoint.Y * this.MainStage.ActualHeight / 480;                HandLeft = depthPoint.X * this.MainStage.ActualWidth / 640;            }        }    }}

上面是多有設計到手部追蹤的代碼。一旦我們設置好HandTop和HandLeft屬性后,UI界面上的十字光標位置就會自動更新。

接下來我們需要實現語音識別部分的邏輯。SpeechRecognitionEngine中的StartSpeechRecognition方法必須找到正確的語音識別庫來進行語音識別。下面的代碼展示了如何設置語音識別庫預計如何將KinectAudioSource傳遞給語音識別引起。我們還添加了SpeechRecognized,SpeechHypothesized以及SpeechRejected事件對應的方法。SetInputToAudioStream中的參數和前篇文章中的含義一樣,這里不多解釋了。注意到SpeechRecognitionEngine和KinectAudioSource都是Disposable類型,因此在整個應用程序的周期內,我們要保證這兩個對象都處于打開狀態(tài)。

private void StartSpeechRecognition(){    _source = CreateAudioSource();    Func<RecognizerInfo, bool> matchingFunc = r =>    {        string value;        r.AdditionalInfo.TryGetValue("Kinect", out value);        return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase)            && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);    };    RecognizerInfo ri = SpeechRecognitionEngine.InstalledRecognizers().Where(matchingFunc).FirstOrDefault();    _sre = new SpeechRecognitionEngine(ri.Id);    CreateGrammars(ri);    _sre.SpeechRecognized += sre_SpeechRecognized;    _sre.SpeechHypothesized += sre_SpeechHypothesized;    _sre.SpeechRecognitionRejected += sre_SpeechRecognitionRejected;    Stream s = _source.Start();    _sre.SetInputToAudioStream(s,                                new SpeechAudioFormatInfo(                                    EncodingFormat.Pcm, 16000, 16, 1,                                    32000, 2, null));    _sre.RecognizeAsync(RecognizeMode.Multiple);}

要完成程序邏輯部分,我們還需要處理語音識別時間以及語音邏輯部分,以使得引擎能夠直到如何處理和執(zhí)行我們的語音命令。SpeechHypothesized以及SpeechRejected事件代碼如下,這兩個事件的邏輯很簡單,就是更新UI界面上的label。SpeechRecognized事件有點復雜,他負責處理傳進去的語音指令,并對識別出的指令執(zhí)行相應的操作。另外,該事件還負責創(chuàng)建一些GUI對象(實際就是命令模式),我們必須使用Dispatcher對象來發(fā)揮InterpretCommand到主UI線程中來。

void sre_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e){    HypothesizedText += " Rejected";    Confidence = Math.Round(e.Result.Confidence, 2).ToString();}void sre_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e){    HypothesizedText = e.Result.Text;}void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e){    Dispatcher.BeginInvoke(new Action<SpeechRecognizedEventArgs>(InterpretCommand), e);}

現在到了程序核心的地方。創(chuàng)建語法邏輯并對其進行解析。本例中的程序識別普通的以“put”或者“create”開頭的命令。前面是什么我們不關心,緊接著應該是一個顏色,然后是一種形狀,最后一個詞應該是“there”。下面的代碼顯示了創(chuàng)建的語法。

private void CreateGrammars(RecognizerInfo ri){    var colors = new Choices();    colors.Add("cyan");    colors.Add("yellow");    colors.Add("magenta");    colors.Add("blue");    colors.Add("green");    colors.Add("red");    var create = new Choices();    create.Add("create");    create.Add("put");    var shapes = new Choices();    shapes.Add("circle");    shapes.Add("triangle");    shapes.Add("square");    shapes.Add("diamond");    var gb = new GrammarBuilder();    gb.Culture = ri.Culture;    gb.Append(create);    gb.AppendWildcard();    gb.Append(colors);    gb.Append(shapes);    gb.Append("there");    var g = new Grammar(gb);    _sre.LoadGrammar(g);    var q = new GrammarBuilder{ Culture = ri.Culture };    q.Append("quit application");    var quit = new Grammar(q);    _sre.LoadGrammar(quit);}

上面的代碼中,我們首先創(chuàng)建一個Choices對象,這個對象會在命令解析中用到。在程序中我們需要顏色和形狀對象。另外,第一個單詞是“put”或者“create”,因此我們也創(chuàng)建Choices對象。然后使用GrammarBuilder類將這些對象組合到一起。首先是”put”或者“create”然后是一個占位符,因為我們不關心內容,然后是一個顏色Choices對象,然后是一個形狀Choices對象,最后是一個“there”單詞。

我們將這些語法規(guī)則加載進語音識別引擎。同時我們也需要有一個命令來停止語音識別引擎。因此我們創(chuàng)建了第二個語法對象,這個對象只有一個”Quit”命令。然后也將這個語法規(guī)則加載到引擎中。

一旦識別引擎確定了要識別的語法,真正的識別工作就開始了。被識別的句子必須被解譯,出別出來想要的指令后,我們必須決定如何進行下一步處理。下面的代碼展示了如何處理識別出的命令,以及如何根據特定的指令來講圖形元素繪制到UI界面上去。

private void InterpretCommand(SpeechRecognizedEventArgs e){    var result = e.Result;    Confidence = Math.Round(result.Confidence, 2).ToString();    if (result.Confidence < 95 && result.Words[0].Text == "quit" && result.Words[1].Text == "application")    {        this.Close();    }    if (result.Words[0].Text == "put" || result.Words[0].Text == "create")    {        var colorString = result.Words[2].Text;        Color color;        switch (colorString)        {            case "cyan": color = Colors.Cyan;                break;            case "yellow": color = Colors.Yellow;                break;            case "magenta": color = Colors.Magenta;                break;            case "blue": color = Colors.Blue;                break;            case "green": color = Colors.Green;                break;            case "red": color = Colors.Red;                break;            default:                return;        }        var shapeString = result.Words[3].Text;        Shape shape;        switch (shapeString)        {            case "circle":                shape = new Ellipse();                shape.Width = 150;                shape.Height = 150;                break;            case "square":                shape = new Rectangle();                shape.Width = 150;                shape.Height = 150;                break;            case "triangle":                var poly = new Polygon();                poly.Points.Add(new Point(0, 0));                poly.Points.Add(new Point(150, 0));                poly.Points.Add(new Point(75, -150));                shape = poly;                break;            case "diamond":                var poly2 = new Polygon();                poly2.Points.Add(new Point(0, 0));                poly2.Points.Add(new Point(75, 150));                poly2.Points.Add(new Point(150, 0));                poly2.Points.Add(new Point(75, -150));                shape = poly2;                break;            default:                return;        }        shape.SetValue(Canvas.LeftProperty, HandLeft);        shape.SetValue(Canvas.TopProperty, HandTop);        shape.Fill = new SolidColorBrush(color);        MainStage.Children.Add(shape);    }}

方法中,我們首先檢查語句識別出的單詞是否是”Quit”如果是的,緊接著判斷第二個單詞是不是”application”如果兩個條件都滿足了,就不進行繪制圖形,直接返回。如果有一個條件不滿足,就繼續(xù)執(zhí)行下一步。

InterpretCommand方法然后判斷第一個單詞是否是“create”或者“put”,如果不是這兩個單詞開頭就什么也不執(zhí)行。如果是的,就判斷第三個單詞,并根據識別出來的顏色創(chuàng)建對象。如果第三個單詞沒有正確識別,應用程序也停止處理。否則,程序判斷第四個單詞,根據接收到的命令創(chuàng)建對應的形狀。到這一步,基本的邏輯已經完成,最后第五個單詞用來確定整個命令是否正確。命令處理完了之后,將當前受的X,Y坐標賦給創(chuàng)建好的對象的位置。

運行程序后,按照語法設定的規(guī)則就可以通過語音以及骨骼追蹤協(xié)作來創(chuàng)建對象了。

pic3w

有一點遺憾的是,Kinect的語音識別目前不支持中文,即使在5月份發(fā)布的SDK1.5版本增加的識別語言種類中也沒有中文,也有可能是因為目前Xbox和kinect沒有在中國大陸銷售的原因吧。所以大家只有用英語進行測試了。

3. 結語

本文接上文,用一個顯示語音來源方向的例子展示了語音識別中的方向識別。用一個簡單的語音識別結合骨骼追蹤來演示了如何根據語音命令來執(zhí)行一系列操作。在語音命令識別中詳細介紹了語音識別語法對象邏輯的建立,以及語音識別引擎相關事件的處理。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯合牽頭組建的NVI技術創(chuàng)新聯盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現場 NVI技術創(chuàng)新聯...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉