基于多普勒效应的手势识别(python)

前段时间看见了微软公司推出的Soundwave(详见连接点击打开链接)觉得很有意思,搜遍很多地方却只发现了js的实现。于是心血来潮做了一个python版的。


代码如下:

# -*- coding: utf-8 -*-
from pyaudio import PyAudio, paInt16 
import numpy as np 
from datetime import datetime 
import pylab as pl
import wave 
import numpy as np
import scipy.signal as signal
import sounddevice as sd
import threading

# 将data中的数据保存到名为filename的WAV文件中
def save_wave_file(filename, data): 
    wf = wave.open(filename, 'wb') 
    wf.setnchannels(1) 
    wf.setsampwidth(2) 
    wf.setframerate(SAMPLING_RATE) 
    wf.writeframes("".join(data)) 
    wf.close() 


def test():
    NUM_SAMPLES = 50000     # pyAudio内部缓存的块的大小
    P_NUM=300
    data_l=NUM_SAMPLES-P_NUM
    SAMPLING_RATE = 44100    # 取样频率
    COUNT_NUM = 0#20          

    # 开启声音输入
    print"record is  beginning!"
    pa = PyAudio()
    stream = pa.open(format=paInt16, channels=1, rate=SAMPLING_RATE, input=True, 
                    frames_per_buffer=NUM_SAMPLES) 

    save_count = 0 
    save_buffer = [] 

    while True: 
        # 读入NUM_SAMPLES个取样
        string_audio_data = stream.read(NUM_SAMPLES) 
        # 将读入的数据转换为数组
        audio_data = np.fromstring(string_audio_data, dtype=np.short) 
        p_data=audio_data[P_NUM:NUM_SAMPLES]
        ap_data=p_data*signal.hann(data_l,sym=0)
        time=np.arange(0,NUM_SAMPLES-300)*(1.0/SAMPLING_RATE)
    #进行傅里叶变换,将时域信号转到频域
        fft_data=np.fft.rfft(p_data)/data_l
        afft_data=np.fft.rfft(ap_data)/data_l
        freqs=np.linspace(0,SAMPLING_RATE/2,data_l/2+1)
        xfft_data=20*np.log10(np.clip(np.abs(fft_data),1e-20,1e100))
        axfft_data=20*np.log10(np.clip(np.abs(afft_data),1e-20,1e100))
        z=np.argmax(np.abs(fft_data))
        n=(data_l*18000)/SAMPLING_RATE
        n1=(data_l*17600)/SAMPLING_RATE
        n2=(data_l*17950)/SAMPLING_RATE
        n3=(data_l*18050)/SAMPLING_RATE
        n4=(data_l*18400)/SAMPLING_RATE
        print n
        kfft_data=np.abs(fft_data)
        right=sum(kfft_data[n1:n2])#最后判别采用的是获取发出频率附近400hz的数据加和并比较大小
        left=sum(kfft_data[n3:n4])
        x=left-right
        print x
        if(abs(x)>80):
            
            if(left>right):
                print "your hand is moving toward left"
            
            else:
                print "your hand is moving toward right"
         
        else:
            print "No moving is detected"

        # 绘图
        pl.subplot(211)
        pl.plot(time,p_data)
        pl.subplot(212)
        pl.plot(freqs,np.abs(afft_data))
        pl.legend()
        pl.xlabel(u"频率(Hz)")
        pl.show()
        COUNT_NUM =COUNT_NUM +1;
        if COUNT_NUM >=1:
            break
def test1():
    fs = 44100 # Hz
    f = 18000 # Hz
    length = 1 #s
    myarray = np.arange(fs * length)
    myarray = np.sin(2 * np.pi * f / fs * myarray)
    sd.play(myarray, fs)

    
threading.Thread(target=test1).start()
threading.Thread(target= test).start()


你可能感兴趣的:(基于多普勒效应的手势识别(python))