2015-12-05 19:16:43 yangzhaomuma 阅读数 5663
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6114 人正在学习 去看看 杨波

Android语音识别,简单的理解就是把语音转化为文字。

在日常中,语音识别,车载导航、语音输入等,虽然不一定准确,但用途广泛。

这里就介绍下谷歌原生的语音识别与百度的语音识别

谷歌语音识别

谷歌语音识别做法很简单

1、首先检测本地是否有语音识别工具,比如谷歌语音搜索,如果没有就结束;

2、用intent意图表示语音识别;

3、发送这个intent,并等待返回;

4、显示返回的内容;

具体的代码如下:

package com.example.speak_csdn;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;

public class MainActivity extends Activity {

	final int RESPONCERESULT=99;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Button btnButton=(Button)findViewById(R.id.mybtn);
		btnButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				speak();
			}
		});
	}

	public void speak()
	{
            try{  
             //通过Intent传递语音识别的模式,开启语音  
             Intent intent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
             //语言模式和自由模式的语音识别  
             intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);  
             //提示语音开始  
             intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "开始语音");  
             
             //开始语音识别  
             startActivityForResult(intent, RESPONCERESULT);  
             }catch (Exception e) {  
                 // TODO: handle exception  
                 e.printStackTrace();  
                 Toast.makeText(getApplicationContext(), "找不到语音设备", 1).show();  
             }  
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		
		//回调获取从谷歌得到的数据   
        if(requestCode==RESPONCERESULT && resultCode==RESULT_OK){  
            //取得语音的字符  
            ArrayList<String> results=data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);  
            //谷歌可能有许多语音类似的返回,越往上优先级越高,这里列出所有的返回并拼接成字符串   
            String resultString="";  
            for(int i=0;i<results.size();i++){  
                resultString+=results.get(i);  
            }  
            Toast.makeText(this, resultString, 1).show();  
        }  
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	

}

代码完成了,注意要加上网络访问权限,因为这个是在线语音识读,代码关键的语句在以下几句:

 //通过Intent传递语音识别的模式,开启语音  
             Intent intent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
             //语言模式和自由模式的语音识别  
             intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);  
             //提示语音开始  
             intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "开始语音");  
             
             //开始语音识别  
             startActivityForResult(intent, RESPONCERESULT);  


对应这个的布局语句很简单,只有一个button按钮。给这个按钮绑定事件,点击运行...


这和我们预料的不同啊,网络没有问题,测试了WIFI和GPRS都是同样的结果。最终这只能归结为谷歌后台服务无法连接,你或者可以通过翻墙来看到效果。

悲伤。

那现在我们看看中国本地的语音识别,百度语音。

百度语音识别

百度语音识别,应用的是百度提供的SDK来实现。这个在百度的开放平台上可以看到很详细的说明。
应用它的步骤如下:
1、下载jar包;
2、添加权限;
3、在代码中,用给定的API来做语音识别;
4、显示返回内容;

jar包、so文件下载

以下是从百度开放平台上下载的jar包以及so文件,用于后续的开发使用

权限添加

AndroidManifest.xml中添加需要的权限,如下:
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 蓝牙录音 -->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <!-- 某些手机启动SCO音频连接需要此权限 -->
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <!-- 蓝牙录音检测耳机状态 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />

代码中使用API

这个就是使用API的过程,如下代码:
package com.example.baiduspeak_csdn;

import java.util.ArrayList;

import com.baidu.voicerecognition.android.ui.BaiduASRDigitalDialog;
import com.baidu.voicerecognition.android.ui.DialogRecognitionListener;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.app.Activity;

public class MainActivity extends Activity {

	//百度自定义对话框
	 private BaiduASRDigitalDialog mDialog = null;
	 //对话框监听
	 private DialogRecognitionListener mRecognitionListener;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Button btnButton=(Button)findViewById(R.id.mybtn);
		btnButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				speak_Baidu();
			}
		});
		
		mRecognitionListener = new DialogRecognitionListener() {

            @Override
            public void onResults(Bundle results) {
                ArrayList<String> rs = results != null ? results.getStringArrayList(RESULTS_RECOGNITION) : null;
                if (rs != null && rs.size() > 0) {
                	Toast.makeText(MainActivity.this, rs.get(0), 1).show();
                }

            }
        };
	}
    //百度语音识别
	public void speak_Baidu()
	{
		if (mDialog != null) {
            mDialog.dismiss();
        }
        Bundle params = new Bundle();
        //设置注册百度开放平台得到的值 API_KEY,SECRET_KEY
        params.putString(BaiduASRDigitalDialog.PARAM_API_KEY, Constants.API_KEY);
        params.putString(BaiduASRDigitalDialog.PARAM_SECRET_KEY, Constants.SECRET_KEY);
        //设置对话框模式
        params.putInt(BaiduASRDigitalDialog.PARAM_DIALOG_THEME, Config.DIALOG_THEME);
        //根据设置新建对话框
        mDialog = new BaiduASRDigitalDialog(this, params);
        //设置对话框的监听
        mDialog.setDialogRecognitionListener(mRecognitionListener);
        //对话框设置
	    mDialog.getParams().putInt(BaiduASRDigitalDialog.PARAM_PROP, Config.CURRENT_PROP);
	    mDialog.getParams().putString(BaiduASRDigitalDialog.PARAM_LANGUAGE, Config.getCurrentLanguage());
	    mDialog.getParams().putBoolean(BaiduASRDigitalDialog.PARAM_START_TONE_ENABLE, Config.PLAY_START_SOUND);
	    mDialog.getParams().putBoolean(BaiduASRDigitalDialog.PARAM_END_TONE_ENABLE, Config.PLAY_END_SOUND);
	    mDialog.getParams().putBoolean(BaiduASRDigitalDialog.PARAM_TIPS_TONE_ENABLE, Config.DIALOG_TIPS_SOUND);
	    mDialog.show();
	}
	 @Override
	    protected void onDestroy() {
	        if (mDialog != null) {
	            mDialog.dismiss();
	        }
	        super.onDestroy();
	    }

}
代码也只是简单的定义一个按钮,按钮绑定一个事件。
事件发起时,我们设定了挺多参数,重要的有平台分配的APP_KEY,SECRET_KEY,PROP,语言的选择等。
根据这些,百度对我们发出的声音,在服务端,得到匹配的内容并返回前端。
效果如下:


这个效果我们是能看到的。简单的用法就是这样的。类似谷歌语音,一个请求即可。

源码

源码包括以上的谷歌和百度语音识别,可供下载:

2016-10-29 08:27:58 u011520752 阅读数 794
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6114 人正在学习 去看看 杨波

语音识别

语音识别的意思是将人说话的内容和意思转换为计算机可读的输入。语音识别的目的就是让机器听懂人类口述的语言,包括了两方面的含义:第一是逐字逐句听懂而不是转化成书面的语言文字;第二是对口述语言中所包含的命令或请求加以领会,做出正确回应,而不仅仅只是拘泥于所有词汇的正确转换。

语音识别系统的分类

  • 从说话者与识别系统的相关性考虑:

    • 特定人语音识别系统
    • 非特定人语音系统
    • 多人的识别系统
  • 从说话的方式考虑:

    • 孤立词语音识别系统
    • 连接词语音识别系统
    • 连续语音识别系统
  • 从识别系统的词汇量大小考虑:

    • 小词汇量语音识别系统
    • 中等词汇量的语音识别系统
    • 大词汇量语音识别系统

语音识别
语音识别的方法

目前具有代表性的语音识别方法主要有动态时间规整技术(DTW)、隐马尔可夫模型(HMM)、矢量量化(VQ)、人工神经网络(ANN)、支持向量机(SVM)等方法。

  1. 动态时间规整算法
    动态时间规整算法(Dynamic TIme Warping,DTW)是在非特定人语音识别中一种简单有效的方法,该算法基于动态规划的思想,解决了发音长短不一的模板匹配问题,是语音识别技术中出现较早、较常用的一种算法。在应用DTW算法进行语音识别时,就是将已经预处理和分帧过的语音测试信号和参考语音模板进行比较以获取他们之间的相似度,按照某种距离测度得出两模板间的相似程度并选择最佳路径。

  2. 隐马尔可夫模型
    隐马尔可夫模型(HMM)是语音信号处理中的一种统计模型,是由Markov链演变来的,所以它是基于参数模型的统计识别方法。由于其模式库是通过反复训练形成的与训练输出信号吻合概率最大的最佳模型参数而不是预先储存好的模式样本,且其识别过程中运用待识别语音序列与HMM参数之间的似然概率达到最大值所对应的最佳状态序列作为识别输出,因此是较理想的语音识别模型

  3. 矢量量化
    矢量量化(Vector QuanTIzaTIon)是一种重要的信号压缩方法。与HMM相比,矢量量化主要适用于小词汇量、孤立词的语音识别中。其过程是将若干个语音信号波形或特征参数的标量数据组成一个矢量在多维空间进行整体量化。把矢量空间分成若干个小区域,每个小区域寻找一个代表矢量,量化时落入小区域的矢量就用这个代表矢量代替。矢量量化器的设计就是从大量信号样本中训练出好的码书,从实际效果出发寻找到好的失真测度定义公式,设计出最佳的矢量量化系统,用最少的搜索和计算失真的运算量实现最大可能的平均信噪比。
    多种降低复杂度的方法,包括无记忆的矢量量化、有记忆的矢量量化和模糊矢量量化方法。

  4. 人工神经网络
    人工神经网络(ANN)是一个自适应非线性动力学系统,模拟了人类神经活动的原理,具有自适应性、并行性、鲁棒性、容错性和学习特性,其强大的分类能力和输入—输出映射能力在语音识别中都很有吸引力。其方法是模拟人脑思维机制的工程模型,它与HMM正好相反,其分类决策能力和对不确定信息的描述能力得到举世公认,但它对动态时间信号的描述能力尚不尽如人意,通常MLP分类器只能解决静态模式分类问题,并不涉及时间序列的处理。尽管学者们提出了许多含反馈的结构,但它们仍不足以刻画诸如语音信号这种时间序列的动态特性。由于ANN不能很好地描述语音信号的时间动态特性,所以常把ANN与传统识别方法结合,分别利用各自优点来进行语音识别而克服HMM和ANN各自的缺点。

  5. 支持向量机
    支持向量机(Support vector machine)是应用统计学理论的一种新的学习机模型,采用结构风险最小化原理(Structural Risk Minimization,SRM),有效克服了传统经验风险最小化方法的缺点。兼顾训练误差和泛化能力,在解决小样本、非线性及高维模式识别方面有许多优越的性能,已经被广泛地应用到模式识别领域。

语音识别技术发展现状

语音识别系统的性能受到许多因素的影响,包括不同说话人的发音方式、说话方式、环境噪音、传输信道衰落等等。

具体要解决的问题有四点:
①增强系统的鲁棒性,也就是说如果条件状况变得与训练时很不相同,系统的性能下降不能是突变的。
②增加系统的适应能力,系统要能稳定连续的适应条件的变化,因为说话人存在着年龄、性别、口音、语速、语音强度、发音习惯等方面的差异。
③寻求更好的语言模型,系统应该在语言模型中得到尽可能多的约束,从而解决由于词汇量增长所带来的影响。
④进行动力学建模,语音识别系统提前假定片段和单词是相互独立的,但实际上词汇和音素的线索要求对反映了发声器官运动模型特点的整合。

语音识别

2018-11-27 23:31:21 entoon 阅读数 7354
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6114 人正在学习 去看看 杨波

matlab程序设计实例——语音识别
经典的语音识别流程如下
语音输入——去噪滤波——特征提取——形成模板库——输入测试语音——匹配模板库——得出结论。

在语音处理时最常用的是DTW进行模式匹配,运用MFCC作为识别特征。

这种思路可以做很多的语音识别设计。

例如单一的词语或者语句识别,做说话人的识别,做说话的语气情感识别等

除此之外还可以利用HMM进行语音识别,思路相似,这是一种基于统计的模型,也有着很不错的运用。

一些主要的程序代码如下(matlab)
%设置模板
ncoeff=12; %mfcc系数的个数
fMatrix1 = cell(1,5);
fMatrix2 = cell(1,5);
fMatrix3 = cell(1,5);
fMatrix4 = cell(1,5);
fMatrix5 = cell(1,5);
fMatrix6 = cell(1,5);
fMatrix7 = cell(1,5);

for i = 1:5
q = [‘SpeechData\1’ num2str(i) ‘.wav’];
[speechIn1,FS1] = audioread(q);
z=speechIn1(:,1);
speechIn1 = my_vad(z);

fMatrix1(1,i) = {mfccf(ncoeff,speechIn1,FS1)}; 

end

for j = 1:5
q = [‘SpeechData\2’ num2str(j) ‘.wav’];
[speechIn2,FS2] = audioread(q);
z=speechIn2(:,1);
speechIn2 = my_vad(z);
fMatrix2(1,j) = {mfccf(ncoeff,speechIn2,FS2)};
end

for k = 1:5
q = [‘SpeechData\3’ num2str(k) ‘.wav’];
[speechIn3,FS3] = audioread(q);
z=speechIn3(:,1);
speechIn3 = my_vad(z);
fMatrix3(1,k) = {mfccf(ncoeff,speechIn3,FS3)};
end

for k = 1:5
q = [‘SpeechData\4’ num2str(k) ‘.wav’];
[speechIn4,FS4] = audioread(q);
z=speechIn4(:,1);
speechIn4 = my_vad(z);
fMatrix4(1,k) = {mfccf(ncoeff,speechIn4,FS4)};
end
for k = 1:5
q = [‘SpeechData\5’ num2str(k) ‘.wav’];
[speechIn5,FS5] = audioread(q);
z=speechIn5(:,1);
speechIn5 = my_vad(z);
fMatrix5(1,k) = {mfccf(ncoeff,speechIn5,FS5)};
end
for k = 1:5
q = [‘SpeechData\6’ num2str(k) ‘.wav’];
[speechIn6,FS6] = audioread(q);
z=speechIn6(:,1);
speechIn6 = my_vad(z);
fMatrix6(1,k) = {mfccf(ncoeff,speechIn6,FS6)};
end
for k = 1:5
q = [‘SpeechData\7’ num2str(k) ‘.wav’];
[speechIn7,FS7] = audioread(q);
z=speechIn7(:,1);
speechIn7 = my_vad(z);
fMatrix7(1,k) = {mfccf(ncoeff,speechIn7,FS7)};
end

%将数据保存为mat文件
fields = {‘One’,‘Two’,‘Three’,‘Four’,‘Five’};
s1 = cell2struct(fMatrix1, fields, 2); %fields项作为行
save Vectors1.mat -struct s1;
s2 = cell2struct(fMatrix2, fields, 2);
save Vectors2.mat -struct s2;
s3 = cell2struct(fMatrix3, fields, 2);
save Vectors3.mat -struct s3;
s4 = cell2struct(fMatrix4, fields, 2);
save Vectors4.mat -struct s4;
s5 = cell2struct(fMatrix5, fields, 2);
save Vectors5.mat -struct s5;
s6 = cell2struct(fMatrix6, fields, 2);
save Vectors6.mat -struct s6;
s7 = cell2struct(fMatrix7, fields, 2);
save Vectors7.mat -struct s7;

%%%%%匹配模板%%%
ncoeff = 12; %MFCC参数阶数
N = 5; %10个数字
fs=100000; %采样频率
duration2 = 5; %录音时长
k = 7; %训练样本的人数

speech = audiorecorder(fs,16,1);
disp(‘Press any key to start 5 seconds of speech recording…’);
pause
disp(‘Recording speech…’);
recordblocking(speech,duration2) % duration*fs 为采样点数
speechIn=getaudiodata(speech);
disp(‘Finished recording.’);
disp(‘System is trying to recognize what you have spoken…’);
z=speechIn(:,1);
speechIn= my_vad(z); %端点检测
rMatrix1 = mfccf(ncoeff,speechIn,fs); %采用MFCC系数作为特征矢量
rMatrix = CMN(rMatrix1); %归一化处理

Sco = DTWScores(rMatrix,N); %计算DTW值
[SortedScores,EIndex] = sort(Sco,2); %按行递增排序,并返回对应的原始次序
Nbr = EIndex(:,1:1) %得到每个模板匹配的2个最低值对应的次序

[Modal,Freq] = mode(Nbr(😃); %返回出现频率最高的数Modal及其出现频率Freq

Word = char(‘hello’,‘matlab代码’,‘工作室’,‘欢迎’,‘你’);
if mean(abs(speechIn)) < 0.01
fprintf(‘No microphone connected or you have not said anything.\n’);
elseif (Freq <2) %频率太低不确定
fprintf(‘The word you have said could not be properly recognised.\n’);
else
fprintf(‘You have just said %s.\n’,Word(Modal,:));
end

%%%%来自私人定制程序文案工作室%%%%
https://weidian.com/?userid=1808020072&wfr=wx&sfr=app&source=shop&from=singlemessage

2019-12-15 17:30:26 duozhishidai 阅读数 279
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6114 人正在学习 去看看 杨波

语音识别是完成语音到文字的转换。自然语言理解是完成文字到语义的转换。语音合成是用语音方式输出用户想要的信息,用语音实现人与计算机之间的交互,主要包括语音识别、自然语言理解和语音合成。

相对于机器翻译,语音识别是更加困难的问题。机器翻译系统的输入通常是印刷文本,计算机能清楚地区分单词和单词串。而语音识别系统的输入是语音,其复杂度要大得多,特别是口语有很多的不确定性。人与人交流时,往往是根据上下文提供的信息猜测对方所说的是哪一个单词,还可以根据对方使用的音调、面部表情和手势等来得到很多信息。特别是说话者会经常更正所说过的话,而且会使用不同的词来重复某些信息。显然,要使计算机像人一样识别语音是很困难的。

语音识别过程包括从一段连续声波中采样,将每个采样值量化,得到声波的压缩数字化表示。采样值位于重叠的帧中,对于每一帧,抽取出一个描述频谱内容的特征向量。然后,根据语音信号的特征识别语音所代表的单词,语音识别过程主要分为五步,如下:

1.语音信号采集

语音信号采集是语音信号处理的前提。语音通常通过话筒输入计算机。话筒将声波转换为电压信号,然后通过A/D装置(如声卡)进行采样,从而将连续的电压信号转换为计算机能够处理的数字信号。

目前多媒体计算机已经非常普及,声卡、音箱、话筒等已是个人计算机的基本设备。其中声卡是计算机对语音信进行加工的重要部件,它具有对信号滤波、放大、A/D和D/A转换等功能。而且,现代操作系统都附带录音软件,通过它可以驱动声卡采集语音信号并保存为语音文件。

对于现场环境不好,或者空间受到限制,特别是对于许多专用设备,目前广泛采用基于单片机、DSP芯片的语音信号采集与处理系统。

2.语音信号预处理

语音信号号在采集后首先要进行滤波、A/D变换,预加重(Preemphasis)和端点检测等预处理,然后才能进入识别、合成、增强等实际应用。

滤波的目的有两个:一是抑制输入信号中频率超出//2的所有分量(/:为采样频率),以防止混叠干扰;二是抑制50Hz的电源工频干扰。因此,滤波器应该是一个带通滤波器。

A/D变换是将语音模拟信号转换为数字信号。A/D变换中要对信号进行量化,量化后的信号值与原信号值之间的差值为量化误差,又称为量化噪声。

预加重处理的目的是提升高频部分,使信号的频谱变得平坦,保持在低频到高频的整个频带中,能用同样的信噪比求频谱,便于频谱分析。

端点检测是从包含语音的一段信号中确定出语音的起点和终点。有效的端点检测不仅能减少处理时间,而且能排除无声段的噪声干扰。目前主要有两类方法:时域特征方法和频域特征方法。时域特征方法是利用语音音量和过零率进行端点检测,计算量小,但对气音会造成误判,不同的音量计算也会造成检测结果不同。频域特征方法是用声音的频谱的变异和熵的检测进行语音检测,计算量较大。

3.语音信号的特征参数提取

人说话的频率在10kHz以下。根据香农采样定理,为了使语音信号的采样数据中包含所需单词的信息,计算机的采样频率应是需要记录的语音信号中包含的最高语音频率的两倍以上。一般将信号分割成若干块,信号的每个块称为帧,为了保证可能落在帧边缘的重要信息不会丢失,应该使帧有重叠。例如,当使用20kH*的采样麵率时,标准的一帧为10ms,包含200个采样值。

话筒等语音输入设备可以采集到声波波形,如囫10.4所示。虽然这些声音的波形包含了所需单词的信息,但用肉眼观察这些波形却得不到多少信息因此,需要从采样数据中抽取那些能够帮助辨别单词的特征信息。在语音识别中,常用线性预测编码技术抽取语音特征。

线性预测编码的基本思想是:语音信号采样点之间存在相关性,可用过去的若干采样点的线性组合预测当前和将来的采样点值。线性預测系数埽以通过使预测信号和实际信号之间的均方误差最小来唯一确定。

语音线性预测系数作为语音信号的一种特征参数,已经广泛应用于语音处理各个领域。

4.向置量化

向量量化(VectorQuantization,VQ)技术是20世纪W年代后期发展起来的一种数据压缩和编码技术。经过向量量化的特征向量也可以作为后面隐马尔可夫模型中的输入观察符号。

在标量量化中整个动态范围被分成若干个小区间,每个小区间有一个代表值,对于一个输入的标量信号,量化时落入小区间的值就用这个代表值>[戈替。因为这时的信号量是一维的标量,所以称为标量量化。

向量量化的概念是用线性空间的观点[,把标量改为一维的向量,对向量进行量化。和标量量化一样,向量量化是把向量空间分成若干个小区域,每个小区域寻找一个代表向量,量化时落入小区域的向量就用这个代表向量代替。

向量量化的基本原理是将若干个标量数据组成一个向量(或者是从一帧语音数据中提取的特征向量)在多维空间给予整体量化,从而可以在信息量损失较小的情况下压缩数据量。

语音识别

当提取声音特征集合以后,就可以识别这些特征所代表的单词。本节重点关注单个单词的识别。识别系统的输入是从语音信号中提取出的特征参数,如LPC预测编码参数,当然,单词对应于字母序列。语音识别所采用的方法一般有模板匹配法、随机模型法和概率语法分析法三种。这三种方法都是建立在最大似然决策贝叶斯(Bayes)判决的基础上的。

(1)模板(template)匹配法

在训练阶段,用户将词汇表中的每一个词依次说一遍,并且将其特征向量作为模板存入模板库。在识别阶段,将输入语音的特征向量序列,依次与模板库中的每个模板进行相似度比较,将相似度最高者作为识别结果输出。

(2)随机模型法

随机模型法是目前语音识别研究的主流。其突出的代表是隐马尔可夫模型。语音信号在足够短的时间段上的信号特征近似于稳定,而总的过程可看成是依次相对稳定的某一特性过渡到另一特性。隐马尔可夫模型则用概率统计的方法来描述这样一种时变的过程。

(3)概率语法分析法

这种方法是用于大长度范围的连续语音识别。语音学家通过研究不同的语音语谱图及其变化发现,虽然不同的人说同一些语音时,相应的语谱及其变化有种种差异,但是总有一些共同的特点足以使他们区别于其他语音,也即语音学家提出的“区别性特征”。另一方面,人类的语言要受词法、语法、语义等约束,人在识别语音的过程中充分应用了这些约束以及对话环境的有关信息。于是,将语音识别专家提出的“区别性特征”与来自构词、句法、语义等语用约束相互结合,就可以构成一个“自底向上”或“自顶向下”的交互作用的知识系统,不同层次的知识可以用若干规则来描述。

除了上面的三种语音识别方法外,还有许多其他的语音识别方法。例如,基于人工神经网络的语音识别方法,是目前的一个研究热点。目前用于语音识别研究的神经网络有BP神经网络、Kohcmen特征映射神经网络等,特别是深度学习用于语音识别取得了长足的进步。
  人工智能、大数据、云计算和物联网的未来发展值得重视,均为前沿产业,多智时代专注于人工智能和大数据的入门和科谱,在此为你推荐几篇优质好文:
1.一套完整的语音识别系统,主要的工作流程是什么?
2.人工智能快速发展的今天,语音识别现在发展到什么阶段了?
3.语音的识别过程主要分哪几步,常用的识别方法是什么?
多智时代-人工智能大数据学习入门网站|人工智能、大数据、物联网云计算的学习交流网站

多智时代-人工智能大数据学习入门网站|人工智能、大数据、云计算、物联网的学习服务的好平台

2020-04-02 12:27:25 Morris_ 阅读数 23
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6114 人正在学习 去看看 杨波

iOS10语音识别框架Speech,项目中用到语音识别功能,这里简单的进行了一下封装,大概实现了系统语音识别的功能。还没测试,应该会有很多坑。

系统的语音识别+外部语音输入,实现语音转文字功能。

  • MMSpeechRecognizer

这个类对系统的语音识别功能进行简单的封装,达到能够识别我们对着设备说话,语音转文字的功能。

MMSpeechRecognizer.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol MMSpeechRecognizerDelegate;

typedef NS_ENUM(NSInteger, MMSpeechRecognizerAuthorizationStatus) {
    MMSpeechRecognizerAuthorizationStatusNotDetermined,
    MMSpeechRecognizerAuthorizationStatusDenied,
    MMSpeechRecognizerAuthorizationStatusRestricted,
    MMSpeechRecognizerAuthorizationStatusAuthorized,
} API_AVAILABLE(ios(10.0));

typedef NS_ENUM(NSInteger, MMSpeechRecognizerActiveStatus) {
    MMSpeechRecognizerActiveStatusStoped,
    MMSpeechRecognizerActiveStatusPreparing,
    MMSpeechRecognizerActiveStatusStared,
    MMSpeechRecognizerActiveStatusError,
} API_AVAILABLE(ios(10.0));

API_AVAILABLE(ios(10.0), macos(10.15))
/// The speech recognizer of iOS. Add 'Privacy - Microphone Usage Description' and 'Privacy - Speech Recognition Usage Description' to your project  before used.
@interface MMSpeechRecognizer : NSObject

- (instancetype)init NS_UNAVAILABLE;
- (nullable instancetype)initWithLocale:(NSLocale *)locale; // returns nil if the locale is not supported.

@property (nonatomic, strong, readonly) NSLocale *locale;// Current locale

// recognizer authorization status. Get authorizationStatus and recognizer can work when authorized.
+ (MMSpeechRecognizerAuthorizationStatus)authorizationStatus;
// Request the authorize if you first used recognizer in your project. It's will show a alert if you add 'Privacy - Microphone Usage Description' and 'Privacy - Speech Recognition Usage Description' to your project.
+ (void)requestAuthorization:(void(^)(MMSpeechRecognizerAuthorizationStatus status))callBack;

// start to recognizing
- (void)start;

// stop recognizing
- (void)stop;

// The status of recognizer when it works.
@property (nonatomic, readonly) MMSpeechRecognizerActiveStatus activeStatus;

@property (nonatomic, weak) id <MMSpeechRecognizerDelegate> delegate;

@end


// The delegate of MMSpeechRecognizer
@protocol MMSpeechRecognizerDelegate <NSObject>

@optional
// Called when recognizer status changed
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer activeStatusChanged:(MMSpeechRecognizerActiveStatus)status;

// Called when recognizer error
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer stopedWithError:(NSError *)error;

// Called when received voice and recognized, will call back many a time.
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer didRecognizedVoice:(NSString *)voiceString;

// Called when recognition of all requested utterances is finished.
// If error is not nil, the recognizer recognized failed.
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer didFinishSuccessfullyWithError:(NSError *)error;

@end

NS_ASSUME_NONNULL_END

MMSpeechRecognizer.m

#import "MMSpeechRecognizer.h"
#import <Speech/Speech.h>
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>

@interface MMSpeechRecognizer ()<SFSpeechRecognizerDelegate,SFSpeechRecognitionTaskDelegate>

@property (strong, nonatomic) SFSpeechRecognizer *sysRecognizer;
@property (nonatomic, strong, readwrite) NSLocale *locale;
@property (strong, nonatomic) AVAudioEngine *audioEngine;

@property (strong, nonatomic) SFSpeechRecognitionTask *recognitionTask;
@property (strong, nonatomic) SFSpeechAudioBufferRecognitionRequest *recognitionRequest;

@property (nonatomic, readwrite) MMSpeechRecognizerActiveStatus activeStatus;

@end

@implementation MMSpeechRecognizer

- (void)dealloc {
    [self removeMonitor];
}

- (instancetype)initWithLocale:(NSLocale *)locale
{
    SFSpeechRecognizer *sysRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];
    if (!sysRecognizer) {
        return nil;
    }
    
    if (self = [super init]) {
        
        self.locale = locale;
        self.sysRecognizer = sysRecognizer;
        self.sysRecognizer.delegate = self;
        self.activeStatus = MMSpeechRecognizerActiveStatusStoped;
        
        [self addMonitor];
    }
    return self;
}


#pragma mark - private
- (void)addMonitor {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForegroundNotification:) name:UIApplicationWillEnterForegroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackgroundNotification:) name: UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)removeMonitor {
    [NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)stopAudioEngine {
    if (self.audioEngine.isRunning) {
        [self.audioEngine stop];
        [self.recognitionRequest endAudio];
        [self.audioEngine.inputNode removeTapOnBus:0];
    }
}
- (void)startAudioEngine {
    NSError *error = nil;
    if (!self.audioEngine.isRunning) {
        self.audioEngine = [[AVAudioEngine alloc] init];
        AVAudioInputNode *inputNode = self.audioEngine.inputNode;
        /**
         @warning : "Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)"
         @discussion: It's will crash when phone call etc...Use inputFormatForBus:
         @see https://stackoverflow.com/questions/41805381/avaudioengine-inputnode-installtap-crash-when-restarting-recording
         */
        //AVAudioFormat *nativeAudioFormat = [inputNode outputFormatForBus:0];
        AVAudioFormat *nativeAudioFormat = [inputNode inputFormatForBus:0];
        __weak typeof(self)weakSelf = self;
        [inputNode installTapOnBus:0 bufferSize:1024 format:nativeAudioFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
            [weakSelf.recognitionRequest appendAudioPCMBuffer:buffer];
        }];
        [self.audioEngine prepare];
        [self.audioEngine startAndReturnError:&error];
        if (error) {
            [self stop];
            [self onError:[NSError errorWithDomain:@"startAudioEngine error" code:0 userInfo:nil]];
        }
        else {
            [self activeStatusChanged:MMSpeechRecognizerActiveStatusStared];
        }
    }
    else {
        [self stop];
        [NSError errorWithDomain:@"The audio engine is runing" code:0 userInfo:nil];
    }
}

- (void)stopRecognitionTask {
    if (self.recognitionTask) {
        [self.recognitionTask cancel];
        // if this the calback speechRecognitionTaskWasCancelled: not return when stop.
        //self.recognitionTask = nil;
    }
    if (self.recognitionRequest) {
        [self.recognitionRequest endAudio];
        //self.recognitionRequest = nil;
    }
}

- (void)activeStatusChanged:(MMSpeechRecognizerActiveStatus)status {
    self.activeStatus = status;
    if ([self.delegate respondsToSelector:@selector(MMSpeechRecognizer:activeStatusChanged:)]) {
        [self.delegate MMSpeechRecognizer:self activeStatusChanged:status];
    }
}

- (void)onError:(NSError *)error {
    if ([self.delegate respondsToSelector:@selector(MMSpeechRecognizer:stopedWithError:)]) {
        [self.delegate MMSpeechRecognizer:self stopedWithError:error];
    }
}

- (void)appWillEnterForegroundNotification:(UIApplication *)app {
    if (self.activeStatus != MMSpeechRecognizerActiveStatusStoped) {
        [self startAudioEngine];
    }
}
- (void)appDidEnterBackgroundNotification:(UIApplication *)app {
    if (self.audioEngine.isRunning) {
        [self stopAudioEngine];
    }
}

#pragma mark - public
+ (MMSpeechRecognizerAuthorizationStatus)authorizationStatus {
    return (MMSpeechRecognizerAuthorizationStatus)[SFSpeechRecognizer authorizationStatus];
}
+ (void)requestAuthorization:(void(^)(MMSpeechRecognizerAuthorizationStatus status))callBack {
    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
        if (callBack) {
            dispatch_async(dispatch_get_main_queue(), ^{
                callBack((MMSpeechRecognizerAuthorizationStatus)(status));
            });
        }
    }];
}
- (void)start {
    if ([SFSpeechRecognizer authorizationStatus] != AVAuthorizationStatusAuthorized) {
        [self stop];
        [self onError:[NSError errorWithDomain:@"authorization error" code:0 userInfo:nil]];
        return;
    }
    
    if (self.activeStatus != MMSpeechRecognizerActiveStatusStoped) {
        [self stop];
    }
    
    [self activeStatusChanged:MMSpeechRecognizerActiveStatusPreparing];
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *categoryError = nil;
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeMeasurement options:AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth error:&categoryError];
    
    if (!categoryError) {
        NSError *activeError = nil;
        [audioSession setActive:YES error:&activeError];
        
        if (!activeError) {
            
            self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc]init];
            self.recognitionTask = [self.sysRecognizer recognitionTaskWithRequest:self.recognitionRequest delegate:self];
            
            [self startAudioEngine];
        }
        else {
            [self stop];
            [self onError:[NSError errorWithDomain:@"audioSession setActive error" code:0 userInfo:nil]];
        }
    }
    else {
        [self stop];
        [self onError:[NSError errorWithDomain:@"audioSession setCategory error" code:0 userInfo:nil]];
    }
}

- (void)stop {
    if (self.activeStatus != MMSpeechRecognizerActiveStatusStoped) {
        [self stopAudioEngine];
        [self stopRecognitionTask];
        [self activeStatusChanged:MMSpeechRecognizerActiveStatusStoped];
    }
}


#pragma mark - delegate
#pragma mark - SFSpeechRecognizerDelegate
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available {
    if (!available) {
        [self stop];
    }
}

#pragma mark - SFSpeechRecognitionTaskDelegate
// Called when the task first detects speech in the source audio
- (void)speechRecognitionDidDetectSpeech:(SFSpeechRecognitionTask *)task
{
    NSLog(@"%s",__FUNCTION__);
}
// Called for all recognitions, including non-final hypothesis
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription
{
    NSLog(@"%s \n %@",__FUNCTION__,transcription.formattedString);
    if ([self.delegate respondsToSelector:@selector(MMSpeechRecognizer:didRecognizedVoice:)]) {
        [self.delegate MMSpeechRecognizer:self didRecognizedVoice:transcription.formattedString];
    }
}

// Called only for final recognitions of utterances. No more about the utterance will be reported
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult
{
    NSLog(@"%s \n %@",__FUNCTION__,recognitionResult.bestTranscription.formattedString);
}
// Called when the task is no longer accepting new audio but may be finishing final processing
- (void)speechRecognitionTaskFinishedReadingAudio:(SFSpeechRecognitionTask *)task
{
    NSLog(@"%s",__FUNCTION__);
}
// Called when the task has been cancelled, either by client app, the user, or the system
- (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task
{
    NSLog(@"%s \n %@ \n",__FUNCTION__,self.recognitionRequest.contextualStrings);
}

// Called when recognition of all requested utterances is finished.
// If successfully is false, the error property of the task will contain error information
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishSuccessfully:(BOOL)successfully
{
    NSLog(@"%s \n",__FUNCTION__);
    NSLog(@"successfully:%d \n task.error:%@",successfully,task.error);
    if ([self.delegate respondsToSelector:@selector(MMSpeechRecognizer:didFinishSuccessfullyWithError:)]) {
        [self.delegate MMSpeechRecognizer:self didFinishSuccessfullyWithError:task.error];
    }
    
    [self stop];
}

@end

ViewController.m

#import "ViewController.h"
#import "MMSpeechRecognizer.h"

@interface ViewController ()<MMSpeechRecognizerDelegate>

@property (nonatomic, strong) UIButton *siriBtn;
@property (nonatomic, strong) UITextView *audioTextView;

@property (nonatomic, strong) MMSpeechRecognizer *recognizer;

@end

@implementation ViewController

- (MMSpeechRecognizer *)recognizer {
    if (!_recognizer) {
        _recognizer = [[MMSpeechRecognizer alloc] initWithLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh-CN"]];
        _recognizer.delegate = self;
    }
    return _recognizer;
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    // Show alert if the speech recognizer authorization is not promoted.
    [MMSpeechRecognizer requestAuthorization:^(MMSpeechRecognizerAuthorizationStatus status) {
        if (status != MMSpeechRecognizerAuthorizationStatusAuthorized) {
            
        }
    }];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.audioTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)*0.5)];
    self.audioTextView.editable = NO;
    self.audioTextView.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.audioTextView];
    
    self.siriBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    self.siriBtn.bounds = CGRectMake(0, 0, 60, 30);
    self.siriBtn.center = self.view.center;
    [self.siriBtn setTitle:@"star" forState:UIControlStateNormal];
    [self.siriBtn setTitle:@"stop" forState:UIControlStateSelected];
    [self.siriBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [self.siriBtn addTarget:self action:@selector(siriBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.siriBtn];
}

- (void)siriBtnClick:(UIButton *)sender {
    if ([MMSpeechRecognizer authorizationStatus] != MMSpeechRecognizerAuthorizationStatusAuthorized) {
        return;
    }
    
    if (self.recognizer.activeStatus == MMSpeechRecognizerActiveStatusStoped) {
        [self.recognizer start];
        sender.selected = YES;
    }
    else {
        [self.recognizer stop];
        sender.selected = NO;
    }
}

#pragma mark - MMSpeechRecognizerDelegate

- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer activeStatusChanged:(MMSpeechRecognizerActiveStatus)status
{
    NSLog(@"%s \n %ld",__FUNCTION__,(long)status);
    self.siriBtn.selected = (status != MMSpeechRecognizerActiveStatusStoped);
}

- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer stopedWithError:(NSError *)error
{
    NSLog(@"%s \n %@",__FUNCTION__,error);
}

// Called when received voice and recognized, will call back many a time.
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer didRecognizedVoice:(NSString *)voiceString {
    
    self.audioTextView.text = voiceString;
}
// Called when recognition of all requested utterances is finished.
// If error is not nil, the recognizer recognized failed.
- (void)MMSpeechRecognizer:(MMSpeechRecognizer *)recognizer didFinishSuccessfullyWithError:(NSError *)error
{

}

@end

语音识别功能需要使用Microphone和Speech的功能,需要在info.plist文件中添加相应的权限控制

Privacy - Microphone Usage Description

Privacy - Speech Recognition Usage Description

语音识别技术

阅读数 288

没有更多推荐了,返回首页