赞
踩
第六章:利用Kinect语音识别控制51单片机
WPF部分:
(1) 新建 Visual C# --> WPF工程(如下图),记得右键点击“引用”,添加相应驱动版本的Microsoft.Kinect.dll 和Microsoft.Speech动态库。App.xaml 文件及 App.xaml.cs文件无需改动。
(2)下面是MainWindow.xaml.cs文件的内容。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using System.IO;
using System.IO.Ports; //跟串口相关,不能只是引用system.IO
using System.Threading; //跟串口相关,线程的引入
namespace VoiceControlLED
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
KinectSensor myKinect;
///
/// 音控相关
///
RecognizerInfo kinectRecognizerInfo;
SpeechRecognitionEngine recognizer;
KinectAudioSource kinectSource;
Stream audioStream;
///
/// 串口相关
///
///
delegate void HandleInterfaceUpdateDelagate(string text);//委托;此为重点
///
/// 实例化串口
///
SerialPort serialPort1 = new SerialPort();
///
/// 串口初始化函数
///
private void SerialPort1_Init()
{
serialPort1.PortName = "COM1"; //串口号(参考串口调试助手)
serialPort1.BaudRate = 9600; //波特率
serialPort1.Parity = Parity.None; //校验位
serialPort1.DataBits = 8; //数据位
serialPort1.StopBits = StopBits.One; //停止位
if (!serialPort1.IsOpen)
{
serialPort1.Open();
}
else
MessageBox.Show("Port is open!");
}
///
/// 发送字节数据函数
///
///
///
private int send_command(string Command)
{
try
{
serialPort1.Write(Command);
return (1);
}
catch (Exception)
{
// comm error
return (0);
}
}
private RecognizerInfo findKinectRecognizerInfo()
{
var recognizers = SpeechRecognitionEngine.InstalledRecognizers();
foreach (RecognizerInfo recInfo in recognizers)
{
// look at each recognizer info value to find the one that works for Kinect
if (recInfo.AdditionalInfo.ContainsKey("Kinect"))
{
string details = recInfo.AdditionalInfo["Kinect"];
if (details == "True" && recInfo.Culture.Name == "en-US")
{
// If we get here we have found the info we want to use
return recInfo;
}
}
}
return null;
}
private void createSpeechEngine()
{
kinectRecognizerInfo = findKinectRecognizerInfo();
if (kinectRecognizerInfo == null)
{
MessageBox.Show("Kinect recognizer not found", "Kinect Speech Demo");
Application.Current.Shutdown();
return;
}
try
{
recognizer = new SpeechRecognitionEngine(kinectRecognizerInfo);
}
catch
{
MessageBox.Show("Speech recognition engine could not be loaded", "Kinect Speech Demo");
Application.Current.Shutdown();
}
}
private void buildCommands()
{
Choices commands = new Choices();
commands.Add("One");
commands.Add("Two");
commands.Add("Three");
commands.Add("Four");
commands.Add("Five");
commands.Add("Six");
commands.Add("Seven");
commands.Add("Eight");
GrammarBuilder grammarBuilder = new GrammarBuilder();
grammarBuilder.Culture = kinectRecognizerInfo.Culture;
grammarBuilder.Append(commands);
Grammar grammar = new Grammar(grammarBuilder);
recognizer.LoadGrammar(grammar);
}
private void setupAudio()
{
try
{
myKinect = KinectSensor.KinectSensors[0];
myKinect.Start();
kinectSource = myKinect.AudioSource;
kinectSource.BeamAngleMode = BeamAngleMode.Automatic;
audioStream = kinectSource.Start();
recognizer.SetInputToAudioStream(audioStream, new SpeechAudioFormatInfo(
EncodingFormat.Pcm, 16000, 16, 1,
32000, 2, null));
recognizer.RecognizeAsync(RecognizeMode.Multiple);
}
catch
{
MessageBox.Show("Audio stream could not be connected", "Kinect Speech Demo");
Application.Current.Shutdown();
}
}
private void SetupSpeechRecognition()
{
createSpeechEngine();
buildCommands();
setupAudio();
recognizer.SpeechRecognized +=
new EventHandler(recognizer_SpeechRecognized);
}
void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Confidence > 0.90f) //判断声音识别可信度
{
wordTextBlock.Text = e.Result.Text;
}
wordTextBlock.Text = e.Result.Text;
if (wordTextBlock.Text == "One")
send_command("1"); //发送(字节数据)字符1
if (wordTextBlock.Text == "Two")
send_command("2");
if (wordTextBlock.Text == "Three")
send_command("3");
if (wordTextBlock.Text == "Four")
send_command("4");
directionTextBlock.Text = kinectSource.BeamAngle.ToString() + " degrees";
directionSlider.Value = kinectSource.BeamAngle;
}
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SetupSpeechRecognition();
SerialPort1_Init();
}
}
}
(3)下面是MainWindow.xaml.cs的内容。
1 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Color Recognizer" SizeToContent="WidthAndHeight" Loaded="Window_Loaded">
5
6
7
8
9
10
51单片机部分:
我选用的是STC89C52RC型号的单片机,带有串口通信的51单片机应该都可以,但可能设置上有些不同。
下面是C语言代码(可参考郭天祥著的51单片机C语言编程)。
1 #include
2 #define uchar unsigned char
3 #define uint unsigned int
4
5 unsigned char flag,a;//此处不能用宏定义
6
7 sbit LED1 = P0^0; //按键位定义
8 sbit LED2 = P0^1;
9 sbit LED3 = P0^2;
10 sbit LED4 = P0^3;
11
12 void main()
13 {
14
15 TMOD=0x20;//设置定时器1为工作方式2
16 TH1=0xfd; //设置波特率为9600
17 TL1=0xfd; //设置波特率为9600
18 TR1=1; //定时器T1运行控制位,当GATE为0而TR1为1时,允许T1计数
19 REN=1;
20
21 SM0=0; //方式1,是十位异步收发器(8位数据)
22 SM1=1; // 波特率可变
23
24 EA=1; //开总中断
25 ES=1; //串行中断允许标志位,ES=1,允许串行中断
26 while(1)
27 {
28
29 if(flag==1)
30 {
31 ES=0;
32 flag=0;
33
34 switch(a)
35 {
36 case '1': LED1 = 0; break;
37
38 case '2': LED2 = 0; break;
39
40 case '3': LED3 = 0; break;
41
42 case '4': LED4 = 0; break;
43
44 }
45
46 SBUF=a;
47 while(!TI);
48 TI = 0; //发送中断标志位,中断产生自动置1
49 ES = 1;
50 }
51 }
52 }
53
54 void ser() interrupt 4 //串口中断标志号为4
55 {
56 RI=0; //接收中断标志位,中断产生自动置1
57
58 a =SBUF;
59
60 flag=1;
61 }
运行结果:
发音:One 单片机P0^0会亮。(注意要用sbit LED1 = P0^0进行位声明)
发音:Two 单片机P0^1会亮。
发音:Three 单片机P0^2会亮。
发音:Four 单片机P0^3会亮。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。