2016-03-02 09:08:50 qqh19910525 阅读数 3178
  • C++语音识别开篇

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

    6100 人正在学习 去看看 杨波

         语音识别技术所涉及的领域包括:信号处理模式识别、概率论和信息论、发声机理和听觉机理、人工智能等等。中国物联网校企联盟形象得把语音识别[1] 比做为“机器的听觉系统”。语音识别技术就是让机器通过识别和理解过程把语音信号转变为相应的文本或命令的高技术。 语音识别技术主要包括特征提取技术、模式匹配准则及模型训练技术三个方面。语音识别技术车联网也得到了充分的引用,例如在翼卡车联网中,只需按一键通客服人员口述即可设置目的地直接导航,安全、便捷。

发展史

       1952年贝尔研究所Davis等人研究成功了世界上第一个能识别10个英文数字发音的实验系统。

1960年英国的Denes等人研究成功了第一个计算机语音识别系统
大规模的语音识别[2]  研究是在进入了70年代以后,在小词汇量、孤立词的识别方面取得了实质性的进展。
进入80年代以后,研究的重点逐渐转向大词汇量、非特定人连续语音识别。在研究思路上也发生了重大变化,即由传统的基于标准模板匹配的技术思路开始转向基于统计模型 (HMM)的技术思路。此外,再次提出了将神经网络技术引入语音识别问题的技术思路
        进入90年代以后,在语音识别的系统框架方面并没有什么重大突破。但是,在语音识别技术的应用及产品化方面出现了很大的进展。

DARPA(Defense Advanced Research Projects Agency)是在70年代由美国国防部远景研究计划局资助的一项10年计划,其旨在支持语言理解系统的研究开发工作。
到了80年代,美国国防部远景研究计划局又资助了一项为期10年的DARPA战略计划,其中包括噪声下的语音识别和会话(口语)识别系统,识别任务设定为“(1000单词)连续语音数据库管理”。
到了90年代,这一DARPA计划仍在持续进行中。其研究重点已转向识别装置中的自然语言处理部分,识别任务设定为“航空旅行信息检索”。
日本也在1981年的第五代计算机计划中提出了有关语音识别输入-输出自然语言的宏伟目标,虽然没能实现预期目标,但是有关语音识别技术的研究有了大幅度的加强和进展。
1987年起,日本又拟出新的国家项目---高级人机口语接口和自动电话翻译系统

中国发展

中国的语音识别研究起始于1958年,由中国科学院声学所利用电子管电路识别10个元音。直至1973年才由中国科学院声学所开始计算机语音识别。由于当时条件的限制,中国的语音识别研究工作一直处于缓慢发展的阶段。
进入80年代以后,随着计算机应用技术在中国逐渐普及和应用以及数字信号技术的进一步发展,国内许多单位具备了研究语音技术的基本条件。与此同时,国际上语音识别技术在经过了多年的沉寂之后重又成为研究的热点,发展迅速。就在这种形式下,国内许多单位纷纷投入到这项研究工作中去。

1986年3月中国高科技发展计划(863计划)启动,语音识别作为智能计算机系统研究的一个重要组成部分而被专门列为研究课题。在863计划的支持下,中国开始了有组织的语音

识别模式

这一时期的语音识别方法基本上是采用传统的模式识别策略。其中以苏联的Velichko和Zagoruyko、日本的迫江和千叶,以及当时在美国的板仓等人的研究工作最具有代表性。
· 苏联的研究为模式识别应用于语音识别这一领域奠定了基础;
· 日本的研究则展示了如何利用动态规划技术在待识语音模式与标准语音模式之间进行非线性时间匹配的方法;
·板仓的研究提出了如何将线性预测分析技术(LPC)加以扩展,使之用于语音信号的特征抽取的方法。

数据库

在语音识别的研究发展过程中,相关研究人员根据不同语言的发音特点,设计和制作了以汉语(包括不同方言)、英语等各类语言的语音数据库,这些语音数据库可以为国内外有关的科研单位和大学进行汉语连续语音识别算法研究、系统设计、及产业化工作提供充分、科学的训练语音样本。例如:MIT Media lab Speech Dataset(麻省理工学院媒体实验室语音数据集)、Pitch and Voicing Estimates for Aurora 2(Aurora2语音库的基因周期和声调估计)、Congressional speech data(国会语音数据)、Mandarin Speech Frame Data(普通话语音帧数据)、用于测试盲源分离算法的语音数据等。
识别技术

数据库

在语音识别的研究发展过程中,相关研究人员根据不同语言的发音特点,设计和制作了以汉语(包括不同方言)、英语等各类语言的语音数据库,这些语音数据库可以为国内外有关的科研单位和大学进行汉语连续语音识别算法研究、系统设计、及产业化工作提供充分、科学的训练语音样本。例如:MIT Media lab Speech Dataset(麻省理工学院媒体实验室语音数据集)、Pitch and Voicing Estimates for Aurora 2(Aurora2语音库的基因周期和声调估计)、Congressional speech data(国会语音数据)、Mandarin Speech Frame Data(普通话语音帧数据)、用于测试盲源分离算法的语音数据等。

技术发展

目前在大词汇语音识别方面处于领先地位的IBM语音研究小组,就是在70年代开始了它的大词汇语音识别研究工作的。AT&T的贝尔研究所也开始了一系列有关非特定人语音识别的实验。这一研究历经10年,其成果是确立了如何制作用于非特定人语音识别的标准模板的方法。
这一时期所取得的重大进展有:
隐式马尔科夫模型(HMM)技术的成熟和不断完善成为语音识别的主流方法。
⑵以知识为基础的语音识别的研究日益受到重视。在进行连续语音识别的时候,除了识别声学信息外,更多地利用各种语言知识,诸如构词、句法、语义、对话背景方面等的知识来帮助进一步对语音作出识别和理解。同时在语音识别研究领域,还产生了基于统计概率的语言模型。
人工神经网络在语音识别中的应用研究的兴起。在这些研究中,大部分采用基于反向传播算法(BP算法)的多层感知网络。人工神经网络具有区分复杂的分类边界的能力,显然它十分有助于模式划分。特别是在电话语音识别方面,由于其有着广泛的应用前景,成了当前语音识别应用的一个热点。

另外,面向个人用途的连续语音听写机技术也日趋完善。这方面,最具代表性的是IBM的ViaVoice和Dragon公司的Dragon Dictate系统。这些系统具有说话人自适应能力,新用户不需要对全部词汇进行训练,便可在使用中不断提高识别率。

· 在孤立字大词汇量语音识别方面,最具代表性的要数92年清华大学电子工程系与中国电子器件公司合作研制成功的THED-919特定人语音识别与理解实时系统。 在连续语音识别方面,91年12月四川大学计算机中心在微机上实现了一个主题受限的特定人连续英语——汉语语音翻译演示系统。

分类应用编辑

根据识别的对象不同,语音识别任务大体可分为3类,即孤立词识别(isolated word recognition),关键词识别(或称关键词检出,keyword spotting)和连续语音识别。其中,孤立词识别 的任务是识别事先已知的孤立的词,如“开机”、“关机”等;连续语音识别的任务则是识别任意的连续语音,如一个句子或一段话;连续语音流中的关键词检测针对的是连续语音,但它并不识别全部文字,而只是检测已知的若干关键词在何处出现,如在一段话中检测“计算机”、“世界”这两个词。
根据针对的发音人,可以把语音识别技术分为特定人语音识别和非特定人语音识别,前者只能识别一个或几个人的语音,而后者则可以被任何人使用。显然,非特定人语音识别系统更符合实际需要,但它要比针对特定人的识别困难得多。
另外,根据语音设备和通道,可以分为桌面(PC)语音识别、电话语音识别和嵌入式设备(手机、PDA等)语音识别。不同的采集通道会使人的发音的声学特性发生变形,因此需要构造各自的识别系统。
语音识别的应用领域非常广泛,常见的应用系统有:语音输入系统,相对于键盘输入方法,它更符合人的日常习惯,也更自然、更高效;语音控制系统,即用语音来控制设备的运行,相对于手动控制来说更加快捷、方便,可以用在诸如工业控制、语音拨号系统、智能家电、声控智能玩具等许多领域;智能对话查询系统,根据客户的语音进行操作,为用户提供自然、友好的数据库检索服务,例如家庭服务、宾馆服务、旅行社服务系统、订票系统、医疗服务、银行服务、股票查询服务等等。

识别方法编辑

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

主要问题编辑

语音识别主要有以下五个问题:
⒈对自然语言的识别和理解。首先必须将连续的讲话分解为词、音素等单位,其次要建立一个理解语义的规则。
⒉语音信息量大。语音模式不仅对不同的说话人不同,对同一说话人也是不同的,例如,一个说话人在随意说话和认真说话时的语音信息是不同的。一个人的说话方式随着时间变化。
⒊语音的模糊性。说话者在讲话时,不同的词可能听起来是相似的。这在英语和汉语中常见。
⒋单个字母或词、字的语音特性受上下文的影响,以致改变了重音、音调、音量和发音速度等。
⒌环境噪声和干扰对语音识别有严重影响,致使识别率低。

前端处理

前端处理是指在特征提取之前,先对原始语音进行处理,部分消除噪声和不同说话人带来的影响,使处理后的信号更能反映语音的本质特征。最常用的前端处理有端点检测和语音增强。端点检测是指在语音信号中将语音和非语音信号时段区分开来,准确地确定出语音信号的起始点。经过端点检测后,后续处理就可以只对语音信号进行,这对提高模型的精确度和识别正确率有重要作用。语音增强的主要任务就是消除环境噪声对语音的影响。目前通用的方法是采用维纳滤波,该方法在噪声较大的情况下效果好于其它滤波器。

声学特征

声学特征的提取与选择是语音识别的一个重要环节。声学特征的提取既是一个信息大幅度压缩的过程,也是一个信号解卷过程,目的是使模式划分器能更好地划分。由于语音信号的时变特性,特征提取必须在一小段语音信号上进行,也即进行短时分析。这一段被认为是平稳的分析区间称之为帧,帧与帧之间的偏移通常取帧长的1/2或1/3。通常要对信号进行预加重以提升高频,对信号加窗以避免短时语音段边缘的影响。

声学特征编辑

LPC

线性预测分析从人的发声机理入手,通过对声道的短管级联模型的研究,认为系统的传递函数符合全极点数字滤波器的形式,从而n 时刻的信号可以用前若干时刻的信号的线性组合来估计。通过使实际语音的采样值和线性预测采样值之间达到均方差最小LMS,即可得到线性预测系数LPC。对 LPC的计算方法有自相关法(德宾Durbin法)、协方差法、格型法等等。计算上的快速有效保证了这一声学特征的广泛使用。与LPC这种预测参数模型类似的声学特征还有线谱对LSP、反射系数等等。

CEP

利用同态处理方法,对语音信号求离散傅立叶变换DFT后取对数,再求反变换iDFT就可得到倒谱系数。对LPC倒谱(LPCCEP),在获得滤波器的线性预测系数后,可以用一个递推公式计算得出。实验表明,使用倒谱可以提高特征参数的稳定性。

Mel

不同于LPC等通过对人的发声机理的研究而得到的声学特征,Mel倒谱系数MFCC和感知线性预测 PLP是受人的听觉系统研究成果推动而导出的声学特征。对人的听觉机理的研究发现,当两个频率相近的音调同时发出时,人只能听到一个音调。临界带宽指的就是这样一种令人的主观感觉发生突变的带宽边界,当两个音调的频率差小于临界带宽时,人就会把两个音调听成一个,这称之为屏蔽效应。Mel刻度是对这一临界带宽的度量方法之一。

MFCC

首先用FFT将时域信号转化成频域,之后对其对数能量谱用依照Mel刻度分布的三角滤波器组进行卷积,最后对各个滤波器的输出构成的向量进行离散余弦变换DCT,取前N个系数。PLP仍用德宾法去计算LPC参数,但在计算自相关参数时用的也是对听觉激励的对数能量谱进行DCT的方法。

声学模型编辑

语音识别系统的模型通常由声学模型和语言模型两部分组成,分别对应于语音到音节概率的计算和音节到字概率的计算。本节和下一节分别介绍声学模型和语言模型方面的技术。
HMM声学建模:马尔可夫模型的概念是一个离散时域有限状态自动机,隐马尔可夫模型HMM是指这一马尔可夫模型的内部状态外界不可见,外界只能看到各个时刻的输出值。对语音识别系统,输出值通常就是从各个帧计算而得的声学特征。用HMM刻画语音信号需作出两个假设,一是内部状态的转移只与上一状态有关,另一是输出值只与当前状态(或当前的状态转移)有关,这两个假设大大降低了模型的复杂度。HMM的打分、解码和训练相应的算法是前向算法、Viterbi算法和前向后向算法。
语音识别中使用HMM通常是用从左向右单向、带自环、带跨越的拓扑结构来对识别基元建模,一个音素就是一个三至五状态的HMM,一个词就是构成词的多个音素的HMM串行起来构成的HMM,而连续语音识别的整个模型就是词和静音组合起来的HMM。
上下文相关建模:协同发音,指的是一个音受前后相邻音的影响而发生变化,从发声机理上看就是人的发声器官在一个音转向另一个音时其特性只能渐变,从而使得后一个音的频谱与其他条件下的频谱产生差异。上下文相关建模方法在建模时考虑了这一影响,从而使模型能更准确地描述语音,只考虑前一音的影响的称为Bi- Phone,考虑前一音和后一音的影响的称为Tri-Phone。
英语的上下文相关建模通常以音素为基元,由于有些音素对其后音素的影响是相似的,因而可以通过音素解码状态的聚类进行模型参数的共享。聚类的结果称为senone。决策树用来实现高效的triphone对senone的对应,通过回答一系列前后音所属类别(元/辅音、清/浊音等等)的问题,最终确定其HMM状态应使用哪个senone。分类回归树CART模型用以进行词到音素的发音标注。

语言模型编辑

语言模型主要分为规则模型和统计模型两种。统计语言模型是用概率统计的方法来揭示语言单位内在的统计规律,其中N-Gram简单有效,被广泛使用。
N-Gram:该模型基于这样一种假设,第n个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram和三元的Tri-Gram。
语言模型的性能通常用交叉熵和复杂度(Perplexity)来衡量。交叉熵的意义是用该模型对文本识别的难度,或者从压缩的角度来看,每个词平均要用几个位来编码。复杂度的意义是用该模型表示这一文本平均的分支数,其倒数可视为每个词的平均概率。平滑是指对没观察到的N元组合赋予一个概率值,以保证词序列总能通过语言模型得到一个概率值。通常使用的平滑技术有图灵估计、删除插值平滑、Katz平滑和Kneser-Ney平滑。

搜索编辑

连续语音识别中的搜索,就是寻找一个词模型序列以描述输入语音信号,从而得到词解码序列。搜索所依据的是对公式中的声学模型打分和语言模型打分。在实际使用中,往往要依据经验给语言模型加上一个高权重,并设置一个长词惩罚分数。
Viterbi:基于动态规划的Viterbi算法在每个时间点上的各个状态,计算解码状态序列对观察序列的后验概率,保留概率最大的路径,并在每个节点记录下相应的状态信息以便最后反向获取词解码序列。Viterbi算法在不丧失最优解的条件下,同时解决了连续语音识别中HMM模型状态序列与声学观察序列的非线性时间对准、词边界检测和词的识别,从而使这一算法成为语音识别搜索的基本策略。
由于语音识别对当前时间点之后的情况无法预测,基于目标函数的启发式剪枝难以应用。由于Viterbi算法的时齐特性,同一时刻的各条路径对应于同样的观察序列,因而具有可比性,束Beam搜索在每一时刻只保留概率最大的前若干条路径,大幅度的剪枝提高了搜索的效率。这一时齐Viterbi- Beam算法是当前语音识别搜索中最有效的算法。N-best搜索和多遍搜索:为在搜索中利用各种知识源,通常要进行多遍搜索,第一遍使用代价低的知识源,产生一个候选列表或词候选网格,在此基础上进行使用代价高的知识源的第二遍搜索得到最佳路径。此前介绍的知识源有声学模型、语言模型和音标词典,这些可以用于第一遍搜索。为实现更高级的语音识别或口语理解,往往要利用一些代价更高的知识源,如4阶或5阶的N-Gram、4阶或更高的上下文相关模型、词间相关模型、分段模型或语法分析,进行重新打分。最新的实时大词表连续语音识别系统许多都使用这种多遍搜索策略。
N-best搜索产生一个候选列表,在每个节点要保留N条最好的路径,会使计算复杂度增加到N倍。简化的做法是只保留每个节点的若干词候选,但可能丢失次优候选。一个折衷办法是只考虑两个词长的路径,保留k条。词候选网格以一种更紧凑的方式给出多候选,对N-best搜索算法作相应改动后可以得到生成候选网格的算法。
前向后向搜索算法是一个应用多遍搜索的例子。当应用简单知识源进行了前向的Viterbi搜索后,搜索过程中得到的前向概率恰恰可以用在后向搜索的目标函数的计算中,因而可以使用启发式的A算法进行后向搜索,经济地搜索出N条候选。

系统实现编辑

语音识别系统选择识别基元的要求是,有准确的定义,能得到足够数据进行训练,具有一般性。英语通常采用上下文相关的音素建模,汉语的协同发音不如英语严重,可以采用音节建模。系统所需的训练数据大小与模型复杂度有关。模型设计得过于复杂以至于超出了所提供的训练数据的能力,会使得性能急剧下降。
听写机:大词汇量、非特定人、连续语音识别系统通常称为听写机。其架构就是建立在前述声学模型和语言模型基础上的HMM拓扑结构。训练时对每个基元用前向后向算法获得模型参数,识别时,将基元串接成词,词间加上静音模型并引入语言模型作为词间转移概率,形成循环结构,用Viterbi算法进行解码。针对汉语易于分割的特点,先进行分割再对每一段进行解码,是用以提高效率的一个简化方法。
对话系统:用于实现人机口语对话的系统称为对话系统。受目前技术所限,对话系统往往是面向一个狭窄领域、词汇量有限的系统,其题材有旅游查询、订票、数据库检索等等。其前端是一个语音识别器,识别产生的N-best候选或词候选网格,由语法分析器进行分析获取语义信息,再由对话管理器确定应答信息,由语音合成器输出。由于目前的系统往往词汇量有限,也可以用提取关键词的方法来获取语义信息。(科大讯飞就是用的这种)

适应强健编辑

语音识别系统的性能受许多因素的影响,包括不同的说话人、说话方式、环境噪音、传输信道等等。提高系统鲁棒性,是要提高系统克服这些因素影响的能力,使系统在不同的应用环境、条件下性能稳定;自适应的目的,是根据不同的影响来源,自动地、有针对性地对系统进行调整,在使用中逐步提高性能。以下对影响系统性能的不同因素分别介绍解决办法。
解决办法按针对语音特征的方法(以下称特征方法)和模型调整的方法(以下称模型方法)分为两类。前者需要寻找更好的、高鲁棒性的特征参数,或是在现有的特征参数基础上,加入一些特定的处理方法。后者是利用少量的自适应语料来修正或变换原有的说话人无关(SI)模型,从而使其成为说话人自适应(SA)模型。
说话人自适应的特征方法有说话人规一化和说话人子空间法,模型方法有贝叶斯方法、变换法和模型合并法。
语音系统中的噪声,包括环境噪声和录音过程加入的电子噪声。提高系统鲁棒性的特征方法包括语音增强和寻找对噪声干扰不敏感的特征,模型方法有并行模型组合PMC方法和在训练中人为加入噪声。信道畸变包括录音时话筒的距离、使用不同灵敏度的话筒、不同增益的前置放大和不同的滤波器设计等等。特征方法有从倒谱矢量中减去其长时平均值和RASTA滤波,模型方法有倒谱平移。

识别引擎编辑

微软在office和vista中都应用了自己开发的语音识别引擎,微软语音识别引擎的使用是完全免费的,所以产生了许多基于微软语音识别引擎开发的语音识别应用软件,例如《语音游戏大师》《语音控制专家》《芝麻开门》《警卫语音识别系统》等等软件。其中《警卫语音识别系统是唯一可以控制单片机类的硬件设施!!
2009年微软发布windows 7操作系统,语音识别软件得到了更好的推广!

最新进展编辑

近几年来,特别是2009年以来,借助机器学习领域深度学习研究的发展,以及大数据语料的积累,语音识别技术得到突飞猛进的发展。
1、技术新发展
1)将机器学习领域深度学习研究引入到语音识别声学模型训练,使用带RBM预训练的多层神经网络,极大提高了声学模型的准确率。在此方面,微软公司的研究人员率先取得了突破性进展,他们使用深层神经网络模型(DNN)后,语音识别错误率降低了30%,是近20年来语音识别技术方面最快的进步。
2)目前大多主流的语音识别解码器已经采用基于有限状态机(WFST)的解码网络,该解码网络可以把语言模型、词典和声学共享音字集统一集成为一个大的解码网络,大大提高了解码的速度,为语音识别的实时应用提供了基础。
3)随着互联网的快速发展,以及手机等移动终端的普及应用,目前可以从多个渠道获取大量文本或语音方面的语料,这为语音识别中的语言模型和声学模型的训练提供了丰富的资源,使得构建通用大规模语言模型和声学模型成为可能。在语音识别中,训练数据的匹配和丰富性是推动系统性能提升的最重要因素之一,但是语料的标注和分析需要长期的积累和沉淀,随着大数据时代的来临,大规模语料资源的积累将提到战略高度。
2、技术新应用
近期,语音识别在移动终端上的应用最为火热,语音对话机器人、语音助手、互动工具等层出不穷,许多互联网公司纷纷投入人力、物力和财力展开此方面的研究和应用,目的是通过语音交互的新颖和便利模式迅速占领客户群。
目前,国外的应用一直以苹果的siri为龙头。
而国内方面,科大讯飞、云知声、盛大、捷通华声、搜狗语音助手、紫冬口译、百度语音等系统都采用了最新的语音识别技术,市面上其他相关的产品也直接或间接嵌入了类似的技术。








2019-10-06 18:22:55 qq_40808154 阅读数 692
  • C++语音识别开篇

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

    6100 人正在学习 去看看 杨波

之前在网上看到一个题目使用语音控制你的浏览器,感觉挺有意思的,就想着实现一个简单的语音识别程序,这里我选择的是百度语音识别,还有好多不错的如科大讯飞等都可以使用。

语音识别过程分为三个部分:

1)录音

2)获取参数access token,有效期为一个月(开发文档)

3)上传录音文件

1.首先你需要一个注册一个百度账号,进行登录,可以直接使用注册过的百度网盘账号进行登录,登录的网址在此处https://login.bce.baidu.com/,选择语音识别,点击创建应用,为你的应用起一个名字:

 创建完成后,如下图所示,AppID,API Key,Secret Key这三个参数需要用到

 

 然后看百度相关的技术开发文档,必要的参数一定带全。

2.由于需要进行录音,这里使用到pyaudio库,需要先进行安装,但是直接使用pip install pyaudio进行安装会出现错误,推荐使用下面的命令进行安装:
sudo apt-get install portaudio19-dev python-all-dev python3-all-dev

pip install pyaudio

安装成功后,接下来开始第1部分录音,代码中都有详细的注释,直接上代码:

import pyaudio
import wave
import requests
import json
import base64
import os


#1.录音
#用Pyaudio录制音频(该库可以进行录音,播放,生成wav文件)
def audio_record(rec_time,filename):
    """
    :param rec_time: 音频录制时间
    :param filename: 输出音频文件名
    """
    CHUNK=1024#定义数据流块
    FORMAT=pyaudio.paInt16#16bit编码格式
    CHANNELS=1#单声道
    RATE=16000#16000采样频率
    #创建一个音频对象
    p=pyaudio.PyAudio()
    #创建音频数据流
    stream=p.open(format=FORMAT,#音频流wav格式
                  channels=CHANNELS,#单声道
                  rate=RATE,#采样率16000
                  input=True,#输入
                  frames_per_buffer=CHUNK)
    print('start recording...')
    frames=list()#空列表用于保存录制的音频流
    #录制音频数据
    for i in range(0,int(RATE/CHUNK*rec_time)):
        data=stream.read(CHUNK)
        frames.append(data)
    #录制完成
    print(frames)
    #停止数据流
    stream.stop_stream()
    stream.close()
    #关闭pyaudio
    p.terminate()
    print('recording done...')
    #保存音频文件
    with wave.open(filename,'wb') as f:
        f.setnchannels(CHANNELS)#设置音频声道数
        f.setsampwidth(p.get_sample_size(FORMAT))#以字节为单位返回样本宽度
        f.setframerate(RATE)#设置取样频率

第2部分,获取参数token

#2 使用appKey secretKey 访问 https://openapi.baidu.com 换取 token
def Get_token():
    #baidu_server='https://openapi.baidu.com/oauth/2.0/token'
    grant_type = 'client_credentials'
    # API KEY
    client_id = 'PrKnhUppGEsqrG8mVG2qIq8O'
    # SECRERT KEY
    client_secret = 'Al4cRfrlRGaMCCkz3kLsd4MXOoQP28iD'

    # 拼接url
    url = 'https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={}&client_secret={}'.format(
            client_id, client_secret)
    # 发送Post请求 获取acess_token
    req = requests.post(url)
    data_dict = json.loads(req.text)  # 将json字符串转换为python字典
    print(req.text)
    print(data_dict['access_token'])

    return data_dict['access_token']


此段代码,可以单独运行下,打印token看是否能获取到,token指为如下所示:

返回的数据:scope中含有audio_voice_assistant_get 表示有语音识别能力, 注意语音服务的调用地址是https://openapi.baidu.com/oauth/2.0/token

第3部分,上传录音(有两种方式:第一种是Json方式,第二种方式是Raw方式,详细见开发文档)

#3.上传录音文件
def BaiduYuYin(file_url,token):
    try:
        RATE='16000'
        FORMAT='wav'
        CUID='wate_play'
        DEV_PID='1536' #普通话:支持简单的英文识别

        file_url=file_url
        token = token

        #以字节格式读取文件之后进行编码
        with open(file_url,'rb') as f:
            speech=base64.b64encode(f.read()).decode('utf-8')
        size = os.path.getsize(file_url)#语音文件的字节数
        headers={'Content-Type':'application/json'}#json格式post上传本地文件
        url='https://vop.baidu.com/server_api'
        data={
            "format":FORMAT,#格式
            "rate":RATE,#取样频率,固定值16000
            "dev_pid":DEV_PID,#语音识别类型
            "speech":speech,#本地语音文件的二进制数据,需要进行base64编码
            "cuid":CUID,#用户唯一标识,用来区分用户 建议填写能区分用户的机器MAC地址或IMEI码,长度为60字符以内。
            "len":size,#语音文件的字节数
            "channel":1,#声道数,仅支持单声道,固定值为1
            "token":token,
        }
        req=requests.post(url,json.dumps(data),headers)
        data_dict=json.loads(req.text)
        print(data_dict['result'][0])
        return data_dict['result'][0][::-1]
    except:
        return '识别不清楚'

最后写一个调度函数run(),运行程序

#4.调度
def run(rec_time,file_name):
    #1.录音
    audio_record(rec_time,file_name)

    #2.获取token
    access_token=Get_token()

    #3.上传录音
    BaiduYuYin(file_name,access_token)


if __name__ == '__main__':
    #录音时间为5秒,文件名为'record1.wav'
    run(5,'record1.wav')

若想要你的电脑可以录音,需要提前打开麦克风,运行此程序后在五秒内说出一段话(可能需要大点声),控制台会打印出来,测试过之后发现准确率还可以,

2019-08-01 11:32:20 weixin_40796925 阅读数 1504
  • C++语音识别开篇

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

    6100 人正在学习 去看看 杨波


最近自己想接触下语音识别,经过一番了解和摸索,实现了对语音识别API的简单调用,正好写文章记录下。目前搜到的帖子里,有现成的调用百度语音API来对音频文件进行识别的;也有通过谷歌语音服务来实现了实时语音识别的。由于我这谷歌语音一直调用不成功,就将二者结合,简单实现了通过百度语音API来进行实时语音识别。

语音识别

语音识别技术就是让机器通过识别和理解过程把语音信号转变为相应的文本或命令的技术,微信中将语音消息转文字,以及“Hi Siri”启用Siri时对其进行发号施令,都是语音识别的现实应用。

语音识别API

百度语音识别通过REST API的方式给开发者提供一个通用的HTTP接口。任意操作系统、任意编程语言,只要可以对百度语音服务器发起http请求,均可使用此接口来实现语音识别。调用API的流程在百度语音官方文档中有说明。

在这里插入图片描述

语音识别步骤

  1. 先注册百度云的账号,控制台中创建百度语音的应用,获取API Key和Secret Key
  2. 通过API Key 和 Secret Key获取token
  3. 将token和本地音频数据上传到API链接
  4. 根据API返回结果获取解析后的文字结果

注意上述过程中我们是使用的本地音频数据,那么我们如何将自己的语音转为相应的数据呢?只要调用麦克风记录我们的语音信息存为wav格式的文件即可。而实时语音识别,即一直保持检测麦克风,只要有声音就生成wav文件向API发送请求;当识别不到语音信息时,自动停止。

代码中我参考了调用谷歌语音的 speech_recognition 模块,因为它调用麦克风的命令特别简单,而且会根据检测麦克风结果自动结束录音。

需要通过pip install SpeechRecognition 下载 speech_recognition 模块来实现上述录音工作。

效果展示

语音识别结果如下图:
在这里插入图片描述

代码下载

语音识别代码下载

百度网盘下载:
链接:https://pan.baidu.com/s/1l8JrYKn1pR5CZPCCme17OA
提取码:rc2e

GitHub代码下载:
https://github.com/pengfexue2/yuyin.git

以上算是对语音识别的初步实现,希望后续能挖掘些更有意思的应用,欢迎继续关注哈~
最后也希望推下自己记录学习 Python、前端以及微信小程序开发的公众号 TEDxPY
在这里插入图片描述

2019-09-12 10:11:33 qq_34556369 阅读数 118
  • C++语音识别开篇

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

    6100 人正在学习 去看看 杨波

语音识别技术概述与调研

语音识别已经成为人工智能应用的一个重点,通过语音控制设备简单方便,在各个领域兴起了研究应用的热潮。数据、算法及芯片是语音识别技术的3个关键,大量优质的数据、精准快速的算法和高性能语音识别芯片是提升语音识别的核心。语音是人工智能产品的主要入口,乃兵家必争之地也。相关算法研究日新月异,CNN RNN CLRNN HMM LACE等模型都尤其优势,将多种算法综合运用修改更佳。

一、应用场景

目前语音识别在智能家居、智能车载、智能客服机器人方面有广泛的应用,未来将会深入到学习、生活、工作的各个环节。国内外许多大公司都在倾力研究此技术,并不断推出实际产品。比如科大讯飞的翻译器译呗,可实现汉语与各种语言之间的互译,效果不错。
百度借助自己的人工智能生态平台,推出了智能行车助手CoDriver。科大讯飞与奇瑞等汽车制造商合作,推出了飞鱼汽车助理,推进车联网进程。搜狗与四维图新合作推出了飞歌导航。云知声、思必驰在导航、平视显示器等车载应用方面推出了多款智能语控车载产品。出门问问则基于自己的问问魔镜进入到智能车载市场。
在语音识别的商业化落地中,需要内容、算法等各个方面的协同支撑,但是良好的用户体验是商业应用的第一要素,而识别算法是提升用户体验的核心因素。下文将从语音识别的算法发展路径、算法发展现状及前沿算法研究三个方面来探讨语音识别技术。

二、算法

对于语音识别系统而言,第一步要检测是否有语音输入,即,语音激活检测(VAD)。在低功耗设计中,相比于语音识别的其它部分,VAD采用always on的工作机制。当VAD检测到有语音输入之后,VAD便会唤醒后续的识别系统。主要包括特征提取、识别建模及模型训练、解码得到结果几个步骤。
首先,我们知道声音实际上是一种波。常见的mp3、wmv等格式都是压缩格式,必须转成非压缩的纯波形文件来处理,比如Windows PCM文件,也就是俗称的wav文件。wav文件里存储的除了一个文件头以外,就是声音波形的一个个点了。下图是一个波形的示例。
在这里插入图片描述
在开始语音识别之前,有时需要把首尾端的静音切除,降低对后续步骤造成的干扰。这个静音切除的操作一般称为VAD,需要用到信号处理的一些技术。要对声音进行分析,需要对声音分帧,也就是把声音切开成一小段一小段,每小段称为一帧。分帧操作一般不是简单的切开,而是使用移动窗函数来实现,这里不详述。帧与帧之间一般是有交叠的,就像下图这样:
在这里插入图片描述
图中,每帧的长度为25毫秒,每两帧之间有25-10=15毫秒的交叠。我们称为以帧长25ms、帧移10ms分帧。图中,每帧的长度为25毫秒,每两帧之间有25-10=15毫秒的交叠。我们称为以帧长25ms、帧移10ms分帧。
分帧后,语音就变成了很多小段。但波形在时域上几乎没有描述能力,因此必须将波形作变换。常见的一种变换方法是提取MFCC特征,根据人耳的生理特性,把每一帧波形变成一个多维向量,可以简单地理解为这个向量包含了这帧语音的内容信息。这个过程叫做声学特征提取。实际应用中,这一步有很多细节,声学特征也不止有MFCC这一种,具体这里不讲。
至此,声音就成了一个12行(假设声学特征是12维)、N列的一个矩阵,称之为观察序列,这里N为总帧数。观察序列如下图所示,图中,每一帧都用一个12维的向量表示,色块的颜色深浅表示向量值的大小。
在这里插入图片描述
接下来就要介绍怎样把这个矩阵变成文本了。首先要介绍两个概念:

  1. 音素:单词的发音由音素构成。对英语,一种常用的音素集是卡内基梅隆大学的一套由39个音素构成的音素集,参见The CMU Pronouncing Dictionary。汉语一般直接用全部声母和韵母作为音素集,另外汉语识别还分有调无调,不详述。
  2. 状态:这里理解成比音素更细致的语音单位就行啦。通常把一个音素划分成3个状态。
    语音识别是怎么工作的呢?实际上一点都不神秘,无非是:
    第一步,把帧识别成状态(难点);第二步,把状态组合成音素;第三步,把音素组合成单词。
    如下图所示:
    在这里插入图片描述
    图中,每个小竖条代表一帧,若干帧语音对应一个状态,每三个状态组合成一个音素,若干个音素组合成一个单词。也就是说,只要知道每帧语音对应哪个状态了,语音识别的结果也就出来了。图中,每个小竖条代表一帧,若干帧语音对应一个状态,每三个状态组合成一个音素,若干个音素组合成一个单词。也就是说,只要知道每帧语音对应哪个状态了,语音识别的结果也就出来了。
    那每帧音素对应哪个状态呢?有个容易想到的办法,看某帧对应哪个状态的概率最大,那这帧就属于哪个状态。比如下面的示意图,这帧对应S3状态的概率最大,因此就让这帧属于S3状态。
    在这里插入图片描述
    那这些用到的概率从哪里读取呢?有个叫“声学模型”的东西,里面存了一大堆参数,通过这些参数,就可以知道帧和状态对应的概率。获取这一大堆参数的方法叫做“训练”,需要使用巨大数量的语音数据,训练的方法比较繁琐,这里不讲。
    但这样做有一个问题:每一帧都会得到一个状态号,最后整个语音就会得到一堆乱七八糟的状态号,相邻两帧间的状态号基本都不相同。假设语音有1000帧,每帧对应1个状态,每3个状态组合成一个音素,那么大概会组合成300个音素,但这段语音其实根本没有这么多音素。如果真这么做,得到的状态号可能根本无法组合成音素。实际上,相邻帧的状态应该大多数都是相同的才合理,因为每帧很短。
    解决这个问题的常用方法就是使用隐马尔可夫模型(Hidden Markov Model,HMM)。这东西听起来好像很高深的样子,实际上用起来很简单:
    第一步,构建一个状态网络。
    第二步,从状态网络中寻找与声音最匹配的路径。
    这样就把结果限制在预先设定的网络中,避免了刚才说到的问题,当然也带来一个局限,比如你设定的网络里只包含了“今天晴天”和“今天下雨”两个句子的状态路径,那么不管说些什么,识别出的结果必然是这两个句子中的一句。
    那如果想识别任意文本呢?把这个网络搭得足够大,包含任意文本的路径就可以了。但这个网络越大,想要达到比较好的识别准确率就越难。所以要根据实际任务的需求,合理选择网络大小和结构。
    搭建状态网络,是由单词级网络展开成音素网络,再展开成状态网络。语音识别过程其实就是在状态网络中搜索一条最佳路径,语音对应这条路径的概率最大,这称之为“解码”。路径搜索的算法是一种动态规划剪枝的算法,称之为Viterbi算法,用于寻找全局最优路径。
    在这里插入图片描述
    这里所说的累积概率,由三部分构成,分别是:
    观察概率:每帧和每个状态对应的概率
    转移概率:每个状态转移到自身或转移到下个状态的概率
    语言概率:根据语言统计规律得到的概率
    其中,前两种概率从声学模型中获取,最后一种概率从语言模型中获取。语言模型是使用大量的文本训练出来的,可以利用某门语言本身的统计规律来帮助提升识别正确率。语言模型很重要,如果不使用语言模型,当状态网络较大时,识别出的结果基本是一团乱麻。

三 、调研

百度语音识别技术

注册百度AI开放平台,点击左侧栏语音技术,在控制栏创建应用:百度AI平台
在这里插入图片描述

创建应用后记录如图三个字段信息。
在这里插入图片描述

1语音存储及识别

相关文件:16k.pcm (百度ai平台下载)
百度API提供两种类型的语音识别功能,故语音存储可有两种存储方式:

  1. 直接文件存储方式(数据库表存储文件名、类型、地址等信息)。
  2. 二进制存储方式。

数据库配置及创建测试表

spring.datasource.url=jdbc:mysql://localhost:3306/ass_test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=UTC
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

创建fileinfo表

CREATE TABLE `fileinfo` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`filename` varchar(50) NOT NULL COMMENT '文件名',
`filepath` varchar(50) NOT NULL COMMENT '文件路径',
`filetype` varchar(50) NOT NULL COMMENT '文件类型',
`filedata` MEDIUMBLOB  COMMENT '文件DATA',
`creattime` datetime COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Html demo.html:

<html>
	<head>
	<script type='text/javascript'>
	function spack(){
		var wrapSpk = document.getElementById('wrapSpk');
		var spkAudio=document.getElementById('spkAudio');
		var spkText=document.getElementById('spkText').value;
		wrapSpk.removeChild(spkAudio);
		var spk1='<audio id="spkAudio" autoplay="autoplay">';
		var spk2='<source src="http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=6&text='+spkText+'" type="audio/mpeg">';
		var spk3='<embed height="0" width="0" src="">';
		var spk4='</audio>';
		wrapSpk.innerHTML = spk1+spk2+spk3+spk4;
		var spkAudio=document.getElementById('spkAudio');
		spkAudio.play();
	}
	function voiceToWord(){
	window.location.href="http://localhost:8080/voice/voiceToWord";}
	
	if (document.createElement("input").webkitSpeech == undefined) {  
		alert("很遗憾,你的浏览器不支持语音识别。");
		}
	else{
		alert("尝试使用语言识别来输入内容吧");
		}
	</script>
	</head>
	<body>
		<!--<input name="s" type="text" x-webkit-speech x-webkit-grammar="builtin:translate" />
		<input x-webkit-speech lang="zh-CN" />
		<input x-webkit-speech x-webkit-grammar="bUIltin:search" />
	<form action="http://www.google.com/search" >
		<input type="search" name="q" lang="zh-CN" x-webkit-speech x-webkit-grammar="builtin:search" onwebkitspeechchange="startSearch(event)"/>
	</form>
	-->
	<div>
		汉字转语音播放:<input type="text" id="spkText">
		<input type="button" id="spkBtn" onclick="spack()" value="播放">
	</div>
	<div id="wrapSpk">
		<audio id="spkAudio" autoplay="autoplay">
			<source src="http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=6&text=" type="audio/mpeg">
			<embed height="0" width="0" src="">
		</audio>
	</div>
	<div id="wrapSpk">
		<form action="http://localhost:8080/voice/receiveToHost" method="post" id="iconForm" enctype="multipart/form-data">
                        <table">
                     
                            <tr>
                                <td>语音文件:</td>
                                <td><input id="pcmFile" name="pcmFile" type="file" /></td>
                                <td><input type="submit" value="上传到本地"/></td>
                            </tr>
                        </table>
                     
         </form>
	</div>
		<div id="wrapSpk1">
		<form action="http://localhost:8080/voice/receiveToBase" method="post" id="iconForm1" enctype="multipart/form-data">
                        <table">
                            <tr>
                                <td>语音文件:</td>
                                <td><input id="pcmFile1" name="pcmFile1" type="file" /></td>
                                <td><input type="submit" value="上传到数据库"/></td>
                            </tr>
                        </table>
                     
         </form>
	</div>
		<div id="wrapSpk2">
		<form action="http://localhost:8080/voice/voiceToWordD" method="post" id="iconForm2" enctype="multipart/form-data">
                        <table">
                            <tr>
                                <td>语音文件:</td>
                                <td><input id="pcmFile2" name="pcmFile2" type="file" /></td>
                                <td><input type="submit" value="直接识别"/></td>
                            </tr>
                        </table>
                     
         </form>
	</div>
	<div id="wrapSpk">
			文件识别:<input type="button" id = "shibie" value="语音转文字" onclick="voiceToWord()"/>
	</div>
	</body>
</html>

百度链接客户端:

在此之前,需要导入百度api的jar包。
Mave配置:

 <dependency>
    <groupId>com.baidu.aip</groupId>
    <artifactId>java-sdk</artifactId>
    <version>4.1.1</version>
	</dependency>
	
	<!-- jdbcTemplate -->
	<dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-jdbc</artifactId>
	</dependency>
 
	<!-- MySQL连接 -->
	<dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    	<scope>runtime</scope>
	</dependency>

客户端AipSpeechClient.java 代码示例:

public class AipSpeechClient {
	//设置APPID/AK/SK
    private static final String APP_ID = "";
    private static final String API_KEY = "";
    private static final String SECRET_KEY = "";
    
    public static AipSpeech AIPSPEECH=null;

    private static AipSpeechClient aipSpeechClient;
    
    private AipSpeechClient(){
    }
    
    public static AipSpeechClient getInstance(){
    	if(aipSpeechClient==null){
    		AIPSPEECH=new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
        	AIPSPEECH.setConnectionTimeoutInMillis(2000);
        	AIPSPEECH.setSocketTimeoutInMillis(60000);
    		aipSpeechClient = new AipSpeechClient();
    	}
		return aipSpeechClient;
    }
}

或者创建配置类AppConfig.java,代码如下:

@Configuration
public class AppConfig {

	//设置APPID/AK/SK
    private static final String APP_ID = "";
    private static final String API_KEY = "";
    private static final String SECRET_KEY = "";
    
    @Bean
    public AipSpeech aipSpeech() {
    	return new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
    }
}

Controller层用@Autowired注入。

Controller类VoiceReceiveController.java:

/**
 * 语音识别controller
 * 
 * @author zhangjx
 * @version 1.0
 * @since 2019-9-4
 */
@RestController
@RequestMapping("/voice")
public class VoiceReceiveController {

	public static final String path = "E:\\testFile\\";

//	public AipSpeech client = AipSpeechClient.getInstance().AIPSPEECH;

	public static final String filePath = "E:\\testFile\\16k.pcm";

	@Autowired
	public AipSpeech aipSpeech;

	@Autowired
	public JdbcTemplate jdbcTemplate;

	/**
	 * 测试demo,直接存入本地,业务环境需要创建表来存储文件名、文件类型及文件路径 此方法亦可存储其他类型文件
	 * 
	 * @param pcmFile
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@PostMapping(value = "/receiveToHost")
	public String uploadToHost(MultipartFile pcmFile, HttpServletRequest request) throws IOException {
		
		long startTime = System.currentTimeMillis(); //获取开始时间

		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

		MultipartFile file = multipartRequest.getFile("pcmFile");

		savePic(file.getInputStream(), file.getOriginalFilename());

		String sql = "insert into fileinfo (filename,filepath,filetype,filedata,creattime) values(?,?,?,?,?);";

		jdbcTemplate.update(sql, file.getOriginalFilename(), path, file.getOriginalFilename().split("\\.")[1], null,
				new Date());
		long endTime = System.currentTimeMillis(); //获取结束时间
		return "success!"+"程序运行时间:" + (endTime - startTime) + "ms";

	}

	/**
	 * 测试demo,直接存入数据库,业务环境需要创建表来存储文件名、文件类型及文件路径 此方法也可以存储其他类型文件,文件大小不宜过大。
	 * 
	 * @param pcmFile
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@PostMapping(value = "/receiveToBase")
	public String uploadToDatabase(MultipartFile pcmFile, HttpServletRequest request) throws IOException {
		
		long startTime = System.currentTimeMillis(); //获取开始时间

		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

		MultipartFile file = multipartRequest.getFile("pcmFile1");

		String sql = "insert into fileinfo (filename,filepath,filetype,filedata,creattime) values(?,?,?,?,?);";

		jdbcTemplate.update(sql, file.getOriginalFilename(), "DATABASE", file.getOriginalFilename().split("\\.")[1],
				file.getInputStream(), new Date());

		long endTime = System.currentTimeMillis(); //获取结束时间
		
		return "success!"+"程序运行时间:" + (endTime - startTime) + "ms";

	}

	
	/**
	 * 测试demo,读取本地文件及二进制数据并识别。
	 * 
	 * @param pcmFile
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@GetMapping(value = "/voiceToWord")
	public String voiceToWorld() throws IOException {
		long startTime = System.currentTimeMillis(); //获取开始时间
		// 文件读取方式,aipSpeech.asr()方法为多态方法,实际上都是调用的二进制方法,可自行查看api
		JSONObject asrRes = aipSpeech.asr(filePath, "pcm", 16000, null);

		long endTime = System.currentTimeMillis(); //获取结束时间
		
		return asrRes.get("result").toString()+"程序运行时间:" + (endTime - startTime) + "ms";

	}

	/**
	 * 测试demo,上传文件直接识别。
	 * 
	 * @param pcmFile
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@PostMapping(value = "/voiceToWordD")
	public String voiceToWorldDirect(MultipartFile pcmFile, HttpServletRequest request) throws IOException {
		
		long startTime = System.currentTimeMillis(); //获取开始时间
		
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

		MultipartFile file = multipartRequest.getFile("pcmFile2");
		
		JSONObject asrRes = aipSpeech.asr(file.getBytes(), "pcm", 16000, null);
		
		long endTime = System.currentTimeMillis(); //获取结束时间

		return asrRes.get("result").toString()+"程序运行时间:" + (endTime - startTime) + "ms";

	}
	/**
	 * 测试demo,文件流
	 * 
	 * @param inputStream
	 * @param fileName
	 * 
	 */
	private void savePic(InputStream inputStream, String fileName) {

		OutputStream os = null;
		try {
			byte[] bs = new byte[1024];
			int len;
			File tempFile = new File(path);
			if (!tempFile.exists()) {
				tempFile.mkdirs();
			}
			os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
			while ((len = inputStream.read(bs)) != -1) {
				os.write(bs, 0, len);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

测试方法:

启动springboot。
浏览器打开html。
在这里插入图片描述
依次进行测试并查看数据库及配置的存储位置。
文件上传响应结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
文件存入数据库响应结果:
在这里插入图片描述
在这里插入图片描述
直接识别结果:
在这里插入图片描述
文件识别结果:
在这里插入图片描述
注意事项:
1、 上传需要完整的录音文件,录音文件时长不超过60s。
2、 系统默认为普通话模式,本次调用为非极速模式语音输入法。
3、 原始 PCM 的录音参数必须符合 16k 采样率、16bit 位深、单声道,支持的格式有:pcm(不压缩)、wav(不压缩,pcm编码)、amr(压缩格式)。
4、 上传文件亦适用其他类型文件上传,数据库存储方式不适合大文件存储,系统设置为16M限制。
5、 本次测试基于springboot进行,demo中的AppID、API Key、Secret Key需自行申请。
6、 错误码
在这里插入图片描述
7、 接口函数说明
在这里插入图片描述

2、资费标准

语音识别极速版价格

语音识别极速版采用分段阶梯定价方式,调用单价按照自然月累积调用量所落阶梯区间而变化。月初,上月累积的调用量清零,重新开始累积本月调用量。 每账号前50000次调用免费,免费额度用尽后开始计费,价格如下:

月调用量(万次) 语音识别极速版(元/次)
0<调用次数<=600 0.0042
600<调用次数<=3000 0.0036
3000<调用次数<=6000 0.0029
6000<调用次数<=15000 0.0019
15000<调用次数 0.0014

语音识别价格

语音识别包含输入法、搜索、粤语、英语、四川话、远场模型。可按天/月购买QPS。价格如下:

QPS购买方式 单价(元)
1QPS/天 80
1QPS/月 1400
1QPS/年 12000

说明:若原有QPS默认配额为2,则购买10QPS/月后,该月QPS提升至12。不限调用量。

免费额度

接口服务 免费调用量额度 QPS限额 计费模式
语音识别 不限制 默认2-10QPS(可通过企业认证提升) 可购买提升QPS
语音识别极速版 每账号共50000次 默认5QPS;开通付费后提升至50QPS 按调用量阶梯计费
注:成功调用与失败调用均算作一次调用,消耗免费额度。
个人创建的应用控制台,企业认证QPS值为10.
在这里插入图片描述

其他语音识别平台资费

科大讯飞

调用方法类似于百度api。
计费标准:
在这里插入图片描述
优点:
1、 支持语种多。
2、 支持长时间录音识别(5小时内)。
3、 转换精度高。
缺点:
1、 付费。

腾讯

企业认证10QPS,个人认证2QPS。
优点:
1、 免费。
2、 提供多版本语音识别技术,如语音识别-echo版,语音识别-流式版(AI Lab),语音识别-流式版(WeChat AI),流式版可做到边录编译。
缺点:
1、 echo版单次请求上限15s,只支持普通话。
2、 AI Lab及WeChat AI只支持普通话。

阿里

1. 语音数据处理费用

• 实时语音识别服务,按照处理的语音时长计费,可以自助开通后付费或购买预付费资源包。
• 一句话语音识别服务,按照调用次数计费,可以自助开通后付费或购买预付费资源包。
• 录音文件识别服务,按照录音时长计费,可以自助开通后付费或购买预付费资源包。
• 语音合成服务,按照调用次数计费,可以自助开通后付费或购买预付费资源包。

2. 附加产品费用

• 超额并发线路费用,商用客户默认提供200路并发,如果客户业务量较大超过200路的,可以自助购买额外并发线路
• 文本自学习定制模型,用于提高客户业务领域的名词句子识别率,可以自助开通

3.计费方式和报价

预付费方式

在这里插入图片描述
注意:预付费资源包的有效期是购买之日起1年以内

后付费方式

按天结算,量大优惠,随调用量增加梯度报价。
在这里插入图片描述

计费细则

试用版:
• 目前试用版不计费,您可免费试用,如有变化,请关注官网通知;
• 一句话识别、实时语音识别、语音合成在2个并发内每个自然日使用量不限;
• 录音文件识别每个自然日识别时长不超过2小时;
商用版:
• 如果您需要超过2个并发或更大量的录音文件识别接口的时长使用,请您开通商用版;
• 开通商用版之后,默认为后付费模式。购买预付费资源包之后,自动变更为预付费模式,并使用资源包内资源进行抵扣,当预付费资源包内资源使用完之后,会再次变更为后付费模式;
• 商用版(包括预付费模式和后付费模式)按每个自然日实际使用量计费,无免费额度,不使用则不产生费用,若使用则每天结算。北京时间每晚24点,系统将自动对您当天用量进行全量计算和计费,具体账单生成会有延迟;
• 计费规则:

  1. 按时长计费的,会累加每次调用的语音时长(按秒向下取整,如本次发送的语音长度22.8秒,则记为22秒)。
  2. 按照次数计费的,返回失败的调用不会计入次数。
  3. 计费总额按照当天24点总体用量最后达到的梯度价格进行全量计费,例如一句话识别当天达到500千次调用量,则当日扣费500*3.0元(300-999千次阶梯价格)=1500.0元。
  4. 语音合成的计费调用次数按照每次请求中传入的字符数(UTF-8编码,以下字符数均以此编码为准。1个汉字、英文字母、全半角标点符号均算1个有效字符)作为统计依据:100个字符以内(含100个字符)记为1次计费调用;每超过100个字符则多记1次计费调用,且1次请求最多传入300个字符。例如,102个字符记为2次计费调用,201个字符记为3次计费调用,依此类推。(2019年6月10日零点前开通预付费或后付费的商用版客户,将于2020年6月9日24点开始自动调整为新规格的计费方式。)

并发数计算

并发数指同一个账号同时在处理的请求数。
一般语音请求的处理都会延续一段时间,例如用户新建一个语音识别请求,持续发送语音数据给服务端,这时并发数就是1;在这个请求处理的同时,这个用户又新建了另一个请求,开始发送语音数据,这时服务端在处理这个账号的2个请求,并发数就变成2。

超额并发线路

在这里插入图片描述
优点:
1、 识别准确率高。
2、 超快的解码速率。
3、 独创的模型优化工具。
4、 广泛的领域覆盖。
缺点:
1、付费。

2012-09-07 13:24:22 maimode 阅读数 112
  • C++语音识别开篇

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

    6100 人正在学习 去看看 杨波

本文介绍使用android.speech包下的api实现一个简单的语音识别例子。

 

speech api参考:http://developer.android.com/intl/zh-CN/reference/android/speech/package-summary.html

 

android开发入门参考:http://maimode.iteye.com/blog/1634268

 

下文给出核心的代码部分:

 

EgSpeechActivity(启动的activity)

 

package com.example.androideg.speech;

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

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

public class EgSpeechActivity extends Activity implements OnClickListener {
	 public final static String EXTRA_MESSAGE = "com.example.androideg.speech.MESSAGE";
	 
	 private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;  
	 private static final String SPEECH_PROMPT = "请讲话";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
		// 检查是否存在recognition activity
		PackageManager pm = getPackageManager();
		List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
				RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
		Button btn = (Button) findViewById(R.id.btn_speek);
		if (activities.size() != 0) {
			//如果存在recognition activity则为按钮绑定点击事件
			btn.setOnClickListener(this);
		} else {
			// 如果不存在则禁用按钮
			btn.setEnabled(false);
			btn.setText("语音识别不可用");
		}

    }

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_speek){
			startVoiceRecognitionActivity();
		}
	}
	
	/**
	 * 启动语音识别activity,接收用户语音输入
	 */
	private void startVoiceRecognitionActivity(){
		//通过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, SPEECH_PROMPT);  
        //开始执行我们的Intent、语音识别  并等待返回结果
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// 确定是语音识别activity返回的结果
		if (requestCode == VOICE_RECOGNITION_REQUEST_CODE){
			// 确定返回结果的状态是成功
			if (resultCode == RESULT_OK){
				// 获取语音识别结果  
	            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);  
	            startDisplayMessageActivity(matches);
			}
		}
		
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	/**
	 * 启动展示activity,显示识别结果
	 * @param message
	 */
	private void startDisplayMessageActivity(ArrayList<String> strList){
		Intent intent = new Intent(this, DisplayMessageActivity.class);
    	intent.putExtra(EXTRA_MESSAGE, strList);
    	startActivity(intent);
	}
}

相应的layout文件activity_main.xml:

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".EgSpeechActivity" >


    <Button
        android:id="@+id/btn_speek"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_speak" />

</LinearLayout>

 

DisplayMessageActivity(用于展示识别结果):

 

 

package com.example.androideg.speech;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class DisplayMessageActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		// 设置布局
		setContentView(R.layout.activity_display_message);
		
		// 从intent中获取数据
		Intent intent = getIntent();
		ArrayList<String> strList = intent.getStringArrayListExtra(EgSpeechActivity.EXTRA_MESSAGE);

		//找到list,然后赋值
		ListView list = (ListView) findViewById(R.id.list);
		list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strList));
    }

}
 

 相应的layout文件activity_display_message.xml:

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >
    </ListView>

 </LinearLayout>

 

经过测试,需要在网络支持的环境下才能识别,支持中文识别。 

 

附件有本示例的eclipse项目文件。

 

运行界面:

 

 

 

 

iOS系统语音识别

阅读数 16

语音识别技术

阅读数 72

Siri 语音识别 Speech

阅读数 599

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