python设计函数计算 1**2+2**2+n**2_声源定位系统设计(二)——MUSIC算法以及Python代码实现...

声源定位系统设计(二)——MUSIC算法以及Python代码实现

上一篇:声源定位系统设计(一)——MVDR波束形成算法讲述了声源定位系统的一些基本概念以及MVDR算法的原理。

目录

声源定位系统设计(二)——MUSIC算法以及Python代码实现

一、前言

二、MUSIC算法

三、MVDR算法代码实现

四、MUSIC算法代码实现

一、前言

上篇博客中已经详细介绍了声源定位的一些概念以及MVDR波束形成法的原理,在本篇博客中,我将介绍另一种更为精准的波束形成算法:MUSIC算法以及这两种算法的Python代码实现。

二、MUSIC算法

MUSIC(Multiple Signal Classification)算法的方法类似于MVDR算法,只是在最后计算的时候有些许不同。该算法建立在一下假设基础上:

①、噪声为高斯分布,每个麦克风之间的噪声分布为随机过程,之间相互独立,空间平稳,即每个麦克风噪声方差相等。

②、要求空间信号为高斯平稳随机过程,且与单元麦噪声互不相干,相互独立。

③、目标声源数目小于阵列元数目。

④、阵元间隔不大于来波信号中频率最高波长的1/2。

MUSIC算法是空间谱估计技术的代表之一,它利用特征结构分析。其基本原理是将协方差矩阵进行特征值分解。它通常把空间信号分为两种,一种是信号特征向量对应的信号空间,另一种是噪声向量对应的噪声空间,利用噪声空间和信号空间的正交性原理,构造空间谱函数进行搜索,从而预估出DOA信息。

按照上一篇博客的做法,阵列数据的协方差矩阵为:

其中,RS​和RN分别为信源的协方差矩阵和噪源的协方差矩阵。

通过对阵列协方差矩阵进行特征值分解,将特征值进行升序排列,其中有D个较大的特征值,对应于声源信号,而有M-D个较小的特征值,对应于噪声信号。

设λii​为第i个特征值,v i为其对应的特征向量,则:

设λi = σ²是R的最小特征值,则:

将R = A R SAH + σ 2 I代入上式得:

化简可得:

由于A H A是满秩矩阵,( A H A ) − 1存在,而RS − 1 也存在,则上式同乘以RS−1 ( A H A ) − 1 A H后变成:

于是有A H vi = 0, i = D + 1 , D + 2 , . . . , M

故可以用噪声向量来求信号源的角度。先构造噪声矩阵E n

最后定义空间谱P ( θ )

其中a为上一篇博客中的方向导向向量,通过遍历θ,即可得到一个空间的功率谱,寻找其最值即可寻得DOA方向角。二维的估计也想同,增加一个遍历的维度即可。

三、MVDR算法代码实现

直接上代码了:

我这里用了一个16阵元的麦克风阵列信号采集板。设计两层圆阵。

nmicro = 16

layers = 2

micros_every_layer = nmicro//layers

R = [0.082, 0.103]

theta_micro = np.zeros(nmicro)#所有麦克风阵元的角度

for layer in range(layers):

theta_micro[micros_every_layer*layer:micros_every_layer*(layer+1)] = \

2*np.pi/micros_every_layer*(np.arange(micros_every_layer)+0.5*layer)

#所有麦克风阵元的坐标

pos = np.concatenate((np.stack([R[0] * np.cos(theta_micro[:8]), R[0] * np.sin(theta_micro[:8]), np.zeros(8)],axis = 1), \

np.stack([R[1] * np.cos(theta_micro[8:]), R[1] * np.sin(theta_micro[8:]), np.zeros(8)],axis = 1)), axis=0)

#PyAudio的信号采集参数

CHUNK = 1600

FORMAT = pyaudio.paInt16

CHANNELS = 18

RATE = 16000

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,

channels=CHANNELS,

rate=RATE,

input=True,

frames_per_buffer=CHUNK)

#最后求得的声源位置

xr = 0

yr = 0

#遍历的x和y,假设z为固定深度1m

X_STEP = 20

Y_STEP = 20

x = np.linspace(-0.4, 0.4, X_STEP)

y = np.linspace(-0.4, 0.4, Y_STEP)

z = 1

def beamforming():

global xr, yr, x, y

while True:

data = stream.read(1600)

data = np.frombuffer(data, dtype=np.short)

data = data.reshape(1600,18)[:,:16].T

p = np.zeros((x.shape[0], y.shape[0]))#声强谱矩阵

#傅里叶变换,在频域进行检测

data_n = np.fft.fft(data)/data.shape[1]# [16,1600]

data_n = data_n[:, :data.shape[1]//2]

data_n[:, 1:] *= 2

#宽带处理,对于50个不同的频率都进行计算

#r存储每个频率下对应信号的R矩阵

r = np.zeros((50, nmicro, nmicro), dtype=np.complex)

for fi in range(1,51):

rr = np.dot(data_n[:, fi*10-10:fi*10+10], data_n[:, fi*10-10:fi*10+10].T.conjugate())/nmicro

r[fi-1,...] = np.linalg.inv(rr)

#MVDR搜索过程

for i in range(x.shape[0]):

for j in range(y.shape[0]):

dm = np.sqrt(x[i]**2+y[j]**2+z**2)

delta_dn = pos[:,0]*x[i]/dm + pos[:,1]*y[j]/dm

for fi in range(1,51):

a = np.exp(-1j*2*np.pi*fi*100*delta_dn/340)

p[i,j] = p[i,j] + 1/np.abs(np.dot(np.dot(a.conjugate(), r[fi-1]), a))

xr = np.argmax(p)//Y_STEP

yr = np.argmax(p)%Y_STEP

print(x[xr],y[yr])

#转为强度0-1

p /= np.max(p)

绘制声强图

x1, y1 = np.meshgrid(x,y)

ax = plt.axes(projection='3d')

ax.plot_surface(x1,y1,np.abs(p.T))

plt.pause(0.01)

if __name__='__main__':

while True:

beamforming()

四、MUSIC算法代码实现

阵列与MVDR相同

nmicro=16

layers = 2

micros_every_layer = nmicro//layers

R = [0.082, 0.103]

theta_micro = np.zeros(nmicro)#所有麦克风阵元的角度

for layer in range(layers):

theta_micro[micros_every_layer*layer:micros_every_layer*(layer+1)] = \

2*np.pi/micros_every_layer*(np.arange(micros_every_layer)+0.5*layer)

#所有麦克风阵元的坐标

pos = np.concatenate((np.stack([R[0] * np.cos(theta_micro[:8]), R[0] * np.sin(theta_micro[:8]), np.zeros(8)],axis = 1), \

np.stack([R[1] * np.cos(theta_micro[8:]), R[1] * np.sin(theta_micro[8:]), np.zeros(8)],axis = 1)), axis=0)

#PyAudio的信号采集参数

CHUNK = 1600

FORMAT = pyaudio.paInt16

CHANNELS = 18

RATE = 16000

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,

channels=CHANNELS,

rate=RATE,

input=True,

frames_per_buffer=CHUNK)

#最后求得的声源位置

xr = 0

yr = 0

#遍历的x和y,假设z为固定深度1m

X_STEP = 20

Y_STEP = 20

x = np.linspace(-0.4, 0.4, X_STEP)

y = np.linspace(-0.4, 0.4, Y_STEP)

z = 1

def beamforming():

global xr, yr, ifplot, x, y

while True:

data = stream.read(1600)

data = np.frombuffer(data, dtype=np.short)

data = data.reshape(1600,18)[:,:16].T

data_n = np.fft.fft(data)/data.shape[1]# [16,1600]

data_n = data_n[:, :data_n.shape[1]//2]

data_n[:, 1:] *= 2

r = np.zeros((50, nmicro, nmicro-1), dtype=np.complex)

for fi in range(1,51):

rr = np.dot(data_n[:, fi*10-10:fi*10+10], data_n[:, fi*10-10:fi*10+10].T.conjugate())/nmicro

feavec,_,_ = np.linalg.svd(rr)

r[fi-1,...] = feavec[:, 1:]

p = np.zeros((x.shape[0], y.shape[0]))

for i in range(x.shape[0]):

for j in range(y.shape[0]):

dm = np.sqrt(x[i]**2+y[j]**2+z**2)

delta_dn = pos[:,0]*x[i]/dm + pos[:,1]*y[j]/dm

for fi in range(1,51):

a = np.exp(-1j*2*np.pi*fi*100*delta_dn/340)

p[i,j] = p[i,j] + 1/np.abs(np.dot(np.dot(np.dot(a.conjugate(), r[fi-1]), r[fi-1].T.conjugate()), a))

#n = np.argmin(np

xr = np.argmax(p)//Y_STEP

yr = np.argmax(p)%Y_STEP

print(x[xr],y[yr])

p /= np.max(p)

x1, y1 = np.meshgrid(x,y)

ax = plt.axes(projection='3d')

ax.plot_surface(x1,y1,np.abs(p.T))

plt.pause(0.01)

上一篇:声源定位系统设计(一)——MVDR波束形成算法讲述了声源定位系统的一些基本概念以及MVDR算法的原理。

你可能感兴趣的:(python设计函数计算,1**2+2**2+n**2)