最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python利用不到一百行代碼實(shí)現(xiàn)一個(gè)小siri

 更新時(shí)間:2017年03月02日 14:22:43   作者:唯心不易  
這篇文章主要介紹了關(guān)于python利用不到一百行代碼實(shí)現(xiàn)了一個(gè)小siri的相關(guān)資料,文中介紹的很詳細(xì),對(duì)大家具有一定的參考借鑒價(jià)值,需要的朋友們下面來(lái)一起看看吧。

前言

如果想要容易理解核心的特征計(jì)算的話建議先去看看我之前的聽(tīng)歌識(shí)曲的文章,傳送門:http://www.fzitv.net/article/97305.htm

本文主要是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的命令詞識(shí)別程序,算法核心一是提取音頻特征,二是用DTW算法進(jìn)行匹配。當(dāng)然,這樣的代碼肯定不能用于商業(yè)化,大家做出來(lái)玩玩娛樂(lè)一下還是不錯(cuò)的。

設(shè)計(jì)思路

就算是個(gè)小東西,我們也要先明確思路再做。音頻識(shí)別,困難不小,其中提取特征的難度在我聽(tīng)歌識(shí)曲那篇文章里能看得出來(lái)。而語(yǔ)音識(shí)別難度更大,因?yàn)橐魳?lè)總是固定的,而人類說(shuō)話常常是變化的。比如說(shuō)一個(gè)“芝麻開(kāi)門”,有的人就會(huì)說(shuō)成“芝麻開(kāi)門”,有的人會(huì)說(shuō)成“芝麻開(kāi)門”。而且在錄音時(shí)說(shuō)話的時(shí)間也不一樣,可能很緊迫的一開(kāi)始錄音就說(shuō)話了,也可能不緊不慢的快要錄音結(jié)束了才把這四個(gè)字說(shuō)出來(lái)。這樣難度就大了。

算法流程:


特征提取

和之前的聽(tīng)歌識(shí)曲一樣,同樣是將一秒鐘分成40塊,對(duì)每一塊進(jìn)行傅里葉變換,然后取模長(zhǎng)。只是這不像之前聽(tīng)歌識(shí)曲中進(jìn)一步進(jìn)行提取峰值,而是直接當(dāng)做特征值。

看不懂我在說(shuō)什么的朋友可以看看下面的源代碼,或者看聽(tīng)歌識(shí)曲那篇文章。

DTW算法

DTW,Dynamic Time Warping,動(dòng)態(tài)時(shí)間歸整。算法解決的問(wèn)題是將不同發(fā)音長(zhǎng)短和位置進(jìn)行最適合的匹配。

算法輸入兩組音頻的特征向量: A:[fp1,fp2,fp3,......,fpM1] B:[fp1,fp2,fp3,fp4,.....fpM2]
A組共有M1個(gè)特征,B組共有M2個(gè)音頻。每個(gè)特征向量中的元素就是之前我們將每秒切成40塊之后FFT求模長(zhǎng)的向量。計(jì)算每對(duì)fp之間的代價(jià)采用的是歐氏距離。

設(shè)D(fpa,fpb)為兩個(gè)特征的距離代價(jià)。

那么我們可以畫出下面這樣的圖

 

我們需要從(1,1)點(diǎn)走到(M1,M2)點(diǎn),這會(huì)有很多種走法,而每種走法就是一種兩個(gè)音頻位置匹配的方式。但我們的目標(biāo)是走的總過(guò)程中代價(jià)最小,這樣可以保證這種對(duì)齊方式是使我們得到最接近的對(duì)齊方式。

我們這樣走:首先兩個(gè)坐標(biāo)軸上的各個(gè)點(diǎn)都是可以直接計(jì)算累加代價(jià)和求出的。然后對(duì)于中間的點(diǎn)來(lái)說(shuō)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)這個(gè)點(diǎn)需要加上兩倍的代價(jià)呢?因?yàn)閯e人走正方形的兩個(gè)直角邊,它走的是正方形的對(duì)角線啊

按照這個(gè)原理選擇,一直算到D(M1,M2),這就是兩個(gè)音頻的距離。

 

 

 

源代碼和注釋

# 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) #計(jì)算兩個(gè)特征之間的歐氏距離

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 #存儲(chǔ)歌曲原始數(shù)組
   f.close()
   self.name = os.path.basename(filepath) # 記錄下文件名
   return True
  except:
   raise IOError, 'File Error'

 def fft(self, frames=40):
  self.fft_blocks = [] #將音頻每秒分成40塊,再對(duì)每塊做傅里葉變換
  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()
  # 播放音樂(lè)方法
  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')#瀏覽器的路徑,之前已經(jīng)被添加到了Path中了
 elif res[0][1].find('play_music') != -1:
  voice.play('C:\data\music\\audio\\audio\\ (9).wav') #播放一段音樂(lè)
 # r = record()
 # r.record(RECORD_SECONDS=3,WAVE_OUTPUT_FILENAME='zhimakaimen_09.wav')

事先可以先用這里的record方法錄制幾段命令詞,嘗試用不同語(yǔ)氣說(shuō),不同節(jié)奏說(shuō),這樣可以提高準(zhǔn)確度。然后設(shè)計(jì)好文件名,根據(jù)匹配到的最接近音頻的文件名就可以知道是哪種命令,進(jìn)而自定義執(zhí)行不同的任務(wù)

這是一段演示視頻:http://www.iqiyi.com/w_19ruisynsd.html

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者使用python能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • python中split()函數(shù)的用法詳解

    python中split()函數(shù)的用法詳解

    Python join() 方法用于將序列中的元素以指定的字符連接生成一個(gè)新的字符串,這篇文章主要介紹了python中split()函數(shù)的用法詳解,需要的朋友可以參考下
    2023-01-01
  • python的正則表達(dá)式re模塊的常用方法

    python的正則表達(dá)式re模塊的常用方法

    Python 的 re 模塊(Regular Expression 正則表達(dá)式)提供各種正則表達(dá)式的匹配操作,在文本解析、復(fù)雜字符串分析和信息提取時(shí)是一個(gè)非常有用的工具,下面我主要總結(jié)了re的常用方法
    2013-03-03
  • selenium執(zhí)行js并繞過(guò)webdriver監(jiān)測(cè)常見(jiàn)方法

    selenium執(zhí)行js并繞過(guò)webdriver監(jiān)測(cè)常見(jiàn)方法

    這篇文章主要為大家介紹了selenium執(zhí)行js并繞過(guò)webdriver監(jiān)測(cè)常見(jiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 在Python 的線程中運(yùn)行協(xié)程的方法

    在Python 的線程中運(yùn)行協(xié)程的方法

    這篇文章主要介紹了在Python 的線程中運(yùn)行協(xié)程的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 解決Cannot?set?up?a?python?SDK?at?Python問(wèn)題

    解決Cannot?set?up?a?python?SDK?at?Python問(wèn)題

    本文主要介紹了解決Cannot?set?up?a?python?SDK?at?Python問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Python中?join()?函數(shù)的使用示例講解

    Python中?join()?函數(shù)的使用示例講解

    Python中有join()和os.path.join()兩個(gè)函數(shù),這篇文章主要介紹了Python中?join()?函數(shù)的使用方法,需要的朋友可以參考下
    2023-04-04
  • pandas行和列的獲取的實(shí)現(xiàn)

    pandas行和列的獲取的實(shí)現(xiàn)

    本文主要介紹了pandas行和列的獲取的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Python selenium 實(shí)例之通過(guò) selenium 查詢禪道是否有任務(wù)或者BUG

    Python selenium 實(shí)例之通過(guò) selenium 查詢禪道是否有任務(wù)或者BUG

    這篇文章主要介紹了Python selenium 實(shí)例之通過(guò) selenium 查詢禪道是否有任務(wù)或者BUG的相關(guān)資料,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • python實(shí)現(xiàn)錄制全屏和選擇區(qū)域錄屏功能

    python實(shí)現(xiàn)錄制全屏和選擇區(qū)域錄屏功能

    這篇文章主要介紹了python實(shí)現(xiàn)錄制全屏和選擇區(qū)域錄屏功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 使用Python實(shí)現(xiàn)火車票查詢系統(tǒng)(帶界面)

    使用Python實(shí)現(xiàn)火車票查詢系統(tǒng)(帶界面)

    周末、假期來(lái)了,七夕也快到了,又到一年中最一票難求的時(shí)候了!本文將用Python制作一個(gè)簡(jiǎn)單的火車票查詢系統(tǒng),感興趣的可以了解一下
    2022-07-07

最新評(píng)論

株洲县| 随州市| 万全县| 青铜峡市| 江永县| 佛冈县| 韶关市| 遵义县| 新蔡县| 巴东县| 二连浩特市| 如皋市| 积石山| 棋牌| 宣威市| 泸州市| 闽侯县| 北川| 博湖县| 昆明市| 嘉兴市| 黄大仙区| 宜宾市| 东阿县| 旬邑县| 黔江区| 双城市| 巴南区| 台湾省| 上饶市| 岳池县| 临西县| 桂平市| 巴楚县| 铁岭市| 洱源县| 常熟市| 耒阳市| 郁南县| 太仆寺旗| 慈利县|