- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章python利用不到一百行代码实现一个小siri由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
如果想要容易理解核心的特征计算的话建议先去看看我之前的听歌识曲的文章,传送门:http://www.zzvips.com/article/103189.html 。
本文主要是实现了一个简单的命令词识别程序,算法核心一是提取音频特征,二是用DTW算法进行匹配。当然,这样的代码肯定不能用于商业化,大家做出来玩玩娱乐一下还是不错的.
设计思路 。
就算是个小东西,我们也要先明确思路再做。音频识别,困难不小,其中提取特征的难度在我听歌识曲那篇文章里能看得出来。而语音识别难度更大,因为音乐总是固定的,而人类说话常常是变化的。比如说一个“芝麻开门”,有的人就会说成“芝麻开门”,有的人会说成“芝麻开门”。而且在录音时说话的时间也不一样,可能很紧迫的一开始录音就说话了,也可能不紧不慢的快要录音结束了才把这四个字说出来。这样难度就大了.
算法流程:
特征提取 。
和之前的听歌识曲一样,同样是将一秒钟分成40块,对每一块进行傅里叶变换,然后取模长。只是这不像之前听歌识曲中进一步进行提取峰值,而是直接当做特征值.
看不懂我在说什么的朋友可以看看下面的源代码,或者看听歌识曲那篇文章.
DTW算法 。
DTW,Dynamic Time Warping,动态时间归整。算法解决的问题是将不同发音长短和位置进行最适合的匹配.
算法输入两组音频的特征向量: A:[fp1,fp2,fp3,......,fpM1] B:[fp1,fp2,fp3,fp4,.....fpM2] A组共有M1个特征,B组共有M2个音频。每个特征向量中的元素就是之前我们将每秒切成40块之后FFT求模长的向量。计算每对fp之间的代价采用的是欧氏距离.
设D(fpa,fpb)为两个特征的距离代价.
那么我们可以画出下面这样的图 。
我们需要从(1,1)点走到(M1,M2)点,这会有很多种走法,而每种走法就是一种两个音频位置匹配的方式。但我们的目标是走的总过程中代价最小,这样可以保证这种对齐方式是使我们得到最接近的对齐方式.
我们这样走:首先两个坐标轴上的各个点都是可以直接计算累加代价和求出的。然后对于中间的点来说D(i,j) = Min{D(i-1,j)+D(fpi,fpj) , D(i,j-1)+D(fpi,fpj) , D(i-1,j-1) + 2 * D(fpi,fpj)} 。
为什么由(i-1,j-1)直接走到(i,j)这个点需要加上两倍的代价呢?因为别人走正方形的两个直角边,它走的是正方形的对角线啊 。
按照这个原理选择,一直算到D(M1,M2),这就是两个音频的距离.
源代码和注释 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# coding=utf8
import
os
import
wave
import
dtw
import
numpy as np
import
pyaudio
def
compute_distance_vec(vec1, vec2):
return
np.linalg.norm(vec1
-
vec2)
#计算两个特征之间的欧氏距离
class
record():
def
record(
self
, CHUNK
=
44100
,
FORMAT
=
pyaudio.paInt16, CHANNELS
=
2
, RATE
=
44100
, RECORD_SECONDS
=
200
,
WAVE_OUTPUT_FILENAME
=
"record.wav"
):
#录歌方法
p
=
pyaudio.PyAudio()
stream
=
p.
open
(
format
=
FORMAT
,
channels
=
CHANNELS,
rate
=
RATE,
input
=
True
,
frames_per_buffer
=
CHUNK)
frames
=
[]
for
i
in
range
(
0
,
int
(RATE
/
CHUNK
*
RECORD_SECONDS)):
data
=
stream.read(CHUNK)
frames.append(data)
stream.stop_stream()
stream.close()
p.terminate()
wf
=
wave.
open
(WAVE_OUTPUT_FILENAME,
'wb'
)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(
FORMAT
))
wf.setframerate(RATE)
wf.writeframes(''.join(frames))
wf.close()
class
voice():
def
loaddata(
self
, filepath):
try
:
f
=
wave.
open
(filepath,
'rb'
)
params
=
f.getparams()
self
.nchannels,
self
.sampwidth,
self
.framerate,
self
.nframes
=
params[:
4
]
str_data
=
f.readframes(
self
.nframes)
self
.wave_data
=
np.fromstring(str_data, dtype
=
np.short)
self
.wave_data.shape
=
-
1
,
self
.sampwidth
self
.wave_data
=
self
.wave_data.T
#存储歌曲原始数组
f.close()
self
.name
=
os.path.basename(filepath)
# 记录下文件名
return
True
except
:
raise
IOError,
'File Error'
def
fft(
self
, frames
=
40
):
self
.fft_blocks
=
[]
#将音频每秒分成40块,再对每块做傅里叶变换
blocks_size
=
self
.framerate
/
frames
for
i
in
xrange
(
0
,
len
(
self
.wave_data[
0
])
-
blocks_size, blocks_size):
self
.fft_blocks.append(np.
abs
(np.fft.fft(
self
.wave_data[
0
][i:i
+
blocks_size])))
@staticmethod
def
play(filepath):
chunk
=
1024
wf
=
wave.
open
(filepath,
'rb'
)
p
=
pyaudio.PyAudio()
# 播放音乐方法
stream
=
p.
open
(
format
=
p.get_format_from_width(wf.getsampwidth()),
channels
=
wf.getnchannels(),
rate
=
wf.getframerate(),
output
=
True
)
while
True
:
data
=
wf.readframes(chunk)
if
data
=
=
"":
break
stream.write(data)
stream.close()
p.terminate()
if
__name__
=
=
'__main__'
:
r
=
record()
r.record(RECORD_SECONDS
=
3
, WAVE_OUTPUT_FILENAME
=
'record.wav'
)
v
=
voice()
v.loaddata(
'record.wav'
)
v.fft()
file_list
=
os.listdir(os.getcwd())
res
=
[]
for
i
in
file_list:
if
i.split(
'.'
)[
1
]
=
=
'wav'
and
i.split(
'.'
)[
0
] !
=
'record'
:
temp
=
voice()
temp.loaddata(i)
temp.fft()
res.append((dtw.dtw(v.fft_blocks, temp.fft_blocks, compute_distance_vec)[
0
],i))
res.sort()
print
res
if
res[
0
][
1
].find(
'open_qq'
) !
=
-
1
:
os.system(
'C:\program\Tencent\QQ\Bin\QQScLauncher.exe'
)
#我的QQ路径
elif
res[
0
][
1
].find(
'zhimakaimen'
) !
=
-
1
:
os.system(
'chrome.exe'
)
#浏览器的路径,之前已经被添加到了Path中了
elif
res[
0
][
1
].find(
'play_music'
) !
=
-
1
:
voice.play(
'C:\data\music\\audio\\audio\\ (9).wav'
)
#播放一段音乐
# r = record()
# r.record(RECORD_SECONDS=3,WAVE_OUTPUT_FILENAME='zhimakaimen_09.wav')
|
事先可以先用这里的record方法录制几段命令词,尝试用不同语气说,不同节奏说,这样可以提高准确度。然后设计好文件名,根据匹配到的最接近音频的文件名就可以知道是哪种命令,进而自定义执行不同的任务 。
这是一段演示视频:http://www.iqiyi.com/w_19ruisynsd.html 。
总结 。
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流.
原文链接:http://www.cnblogs.com/chuxiuhong/p/6124459.html 。
最后此篇关于python利用不到一百行代码实现一个小siri的文章就讲到这里了,如果你想了解更多关于python利用不到一百行代码实现一个小siri的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我已经为应用程序实现了 Siri 快捷方式。一切正常,除了一件事: 当执行 INPreferences.requestSiriAuthorization 请求使用 Siri 的授权时,用户可以允许或拒
我知道有 no API for Siri .看起来也没有迹象表明它会很快发生变化。 但我迫不及待地想利用它出色的自由语音识别功能,所以我在想也许仍在使用它但作为一个“黑匣子”? 例如,this app
这个问题在这里已经有了答案: Does Apple provide an API for SIRI? (4 个回答) 5年前关闭。 我可以像使用 iOS 应用程序一样使用 Siri 功能对 macOS
我需要集成 Siri 才能使用我的应用调用电话。 Siri 在设置的应用程序支持上识别我的应用程序。但是当我试图调用某个联系人说“在 MyApp 上调用 ContactName”时,它只显示按钮“打开
我已经通过 react-native-siri-shortcut npm 在 React Native 项目中成功实现了快捷方式。 我可以在快捷方式应用程序(iOS 中)中看到所有这些快捷方式。 当我
我在 iOS 应用程序上有一个可用的 Siri 支付扩展程序。但是当我问 Siri“你能做什么?”它没有列出我的应用程序。 Siri 确实列出了现金和 Venmo 支付应用程序(我同事手机上的 Ven
我想知道是否可以在移动设备上使用 JS 验证一些 Siri 驱动(或 Android 语音识别软件)的输入。 我有一个“input type=text”对象,但我只需要启用数字(数字)。我正在使用 k
AppleTV 似乎存在错误。我有一个包含所有游戏节点(和 Action )的 SKNode“worldNode”的 SpriteKit 场景。我能够检测到何时按下 Siri Remote 上的菜单按
我正在集成 Sirikit,Bill Payment,目的是: INPayBillIntentHandling(最近在 iOS 10.3+ 中发布,2017 年 3 月 27 日)。 Apple 文档
我想通过终端命令来使用 siri。是否可以?示例: $ siri "Sleep my mac" 最佳答案 您可以使用 siri 在“设置”>“辅助功能”>“语音”中设置萨曼莎的声音 打开终端并输入 $
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
'com.apple.coreaudio.avfaudio', reason: 'required condition is false: _recordingTap == nil 代码崩溃 1.
我的应用程序有一个自定义意图,它向用户建议一个快捷方式,如下所示: let intent = ReadIntent() if let shortcut = INShortcut(int
这个问题在这里已经有了答案: 已关闭10 年前。
有没有一种方法或工具可以检查 Apple 的 Siri 如何解释/读取语音字段的值?我已经能够在终端 (Mac OSX) 中通过 say something 帮助自己一点点,但我对任何其他替代方案感到
我知道这是一个长期的尝试,但是有什么方法可以将数据推送到 iOS 上的 Siri。 我的意思是,我有一个程序,其中包含一些数据,例如我的购物 list 或其他数据。现在我想问 Siri 我需要买什么,
有没有办法从网页(可能使用 Javascript)触发 Siri 来填充输入文本字段? 最佳答案 您可能无法直接触发 Siri,但您可以使用 x-webkit-speech将添加使用语音输入功能的 h
我正在尝试将 Siri 快捷方式集成到我的应用程序中。我正在尝试的概念是通过密码确认获得我的卡的奖励积分。请在下面找到我为此所做的工作。 在功能中启用 Siri 并添加 Siri Intent 定义文
我已启动并运行快捷方式,并且已将自定义响应添加到我的完成处理程序中。在这种情况下... completion ([TriggerSceneIntentResponse successIntentR
在 Apple TV 上的 Siri Remote 上收集触摸时,触摸的位置始终报告为同一位置? let tapRecognizer = UITapGestureRecognizer(target:
我是一名优秀的程序员,十分优秀!