阵列信号处理及matlab实现_球形麦克风阵列设计
問題背景
要設(shè)計(jì)球形麥克風(fēng)陣列(SMA),并保證麥克風(fēng)在球面等距離分布(可以理解為,球面上任一麥克風(fēng)與相鄰麥克風(fēng)的距離相等),需要給出每個(gè)麥克風(fēng)的具體坐標(biāo)位置。
麥克風(fēng)坐標(biāo)計(jì)算
球面上的麥克風(fēng)最終組成一個(gè)規(guī)則的凸包多面體(參見Platonic solid),麥克風(fēng)坐標(biāo)數(shù)值解法其實(shí)是一個(gè)Thomson problem。
此類問題有多種求解思路(可參考cofludy的博客),其中一種是基于力學(xué)原理,大致思路如下:
1)首先建立單位球體,然后將待分布的N個(gè)麥克風(fēng)作為帶電粒子,隨機(jī)分布在該單位球體的表面;
2) 計(jì)算每個(gè)帶電粒子在各個(gè)方向上受到的合力大小,然后計(jì)算出合力在對(duì)應(yīng)帶電粒子上的切線分量;
3) 根據(jù)切線分量計(jì)算對(duì)應(yīng)帶電粒子沿切向運(yùn)動(dòng)飛出該單位球體表面的坐標(biāo),然后對(duì)每一帶電粒子的坐標(biāo)沿徑向進(jìn)行歸一化,使所有帶電粒子再次回到該單位球體的表面;
4) 步驟2)、3)循環(huán)若干次,當(dāng)各帶電粒子所受合力均小于一設(shè)定值時(shí),得到各帶電粒子的球面均勾分布,即為N個(gè)麥克風(fēng)在該球形的陣列分布。
詳細(xì)的算法步驟可參考專利描述:一種3D錄音系統(tǒng)球面麥克風(fēng)陣列分布方法【北京大學(xué)】
幸運(yùn)的是,網(wǎng)上有一段現(xiàn)成的MATLAB代碼,可通過鏈接查看,源代碼如下:
function []=main() N=12; %點(diǎn)數(shù)量 a=rand(N,1)*2*pi;%根據(jù)隨機(jī)求面均勻分布,先生成一個(gè)初始狀態(tài) b=asin(rand(N,1)*2-1); r0=[cos(a).*cos(b),sin(a).*cos(b),sin(b)]; v0=zeros(size(r0)); G=1e-2;%斥力常數(shù),試驗(yàn)這個(gè)值比較不錯(cuò) for ii=1:200%模擬200步,一般已經(jīng)收斂,其實(shí)可以在之下退出[rn,vn]=countnext(r0,v0,G);%更新狀態(tài)r0=rn;v0=vn; end plot3(rn(:,1),rn(:,2),rn(:,3),'.');hold on;%畫結(jié)果 [xx,yy,zz]=sphere(50); h2=surf(xx,yy,zz); %畫一個(gè)單位球做參考 set(h2,'edgecolor','none','facecolor','r','facealpha',0.7); axis equal; axis([-1 1 -1 1 -1 1]); hold off; endfunction [rn vn]=countnext(r,v,G) %更新狀態(tài)的函數(shù) %r存放每點(diǎn)的x,y,z數(shù)據(jù),v存放每點(diǎn)的速度數(shù)據(jù) num=size(r,1); dd=zeros(3,num,num); %各點(diǎn)間的矢量差 for m=1:num-1for n=m+1:numdd(:,m,n)=(r(m,:)-r(n,:))';dd(:,n,m)=-dd(:,m,n);end end L=sqrt(sum(dd.^2,1));%各點(diǎn)間的距離 L(L<1e-2)=1e-2; %距離過小限定 F=sum(dd./repmat(L.^3,[3 1 1]),3)';%計(jì)算合力Fr=r.*repmat(dot(F,r,2),[1 3]); %計(jì)算合力徑向分量 Fv=F-Fr; %切向分量rn=r+v; %更新坐標(biāo) rn=rn./repmat(sqrt(sum(rn.^2,2)),[1 3]); vn=v+G*Fv;%跟新速度 end一開始因?yàn)橛?jì)算機(jī)沒有安裝MATLAB只有Python,代碼看著也不多,也有那么一點(diǎn)點(diǎn)Python使用經(jīng)驗(yàn),想著用Python重寫一遍好了。
結(jié)果,困難程度遠(yuǎn)遠(yuǎn)超出預(yù)期(請(qǐng)?jiān)徫疫@只菜鳥~)。一邊查MATLAB中函數(shù)的用法,一邊查Numpy中函數(shù)的用法,折騰幾天還是沒能完成。不得已,安裝MATLAB后,一步一步確認(rèn)Python代碼的輸出結(jié)果,又折騰幾天最終完成。
Numpy雖然說很多函數(shù)和MATLAB非常相似,但有幾個(gè)地方需要注意:
- MATLAB下標(biāo)索引從1開始,Numpy下標(biāo)索引從0開始;
- MATLAB中多維數(shù)組下標(biāo)依次表示維度 行:列:頁,而Numpy中多維數(shù)組下標(biāo)依次表示維度 頁:行:列;
計(jì)算得到球面麥克風(fēng)點(diǎn)的坐標(biāo)后,可利用Scipy.spatial中的ConvexHull函數(shù)繪制3D凸包,參考以下鏈接,源代碼如下
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.spatial import ConvexHull# 8 points defining the cube corners pts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0],[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1], ])hull = ConvexHull(pts)fig = plt.figure() ax = fig.add_subplot(111, projection="3d")# Plot defining corner points ax.plot(pts.T[0], pts.T[1], pts.T[2], "ko")# 12 = 2 * 6 faces are the simplices (2 simplices per square face) for s in hull.simplices:s = np.append(s, s[0]) # Here we cycle back to the first coordinateax.plot(pts[s, 0], pts[s, 1], pts[s, 2], "r-")# Make axis label for i in ["x", "y", "z"]:eval("ax.set_{:s}label('{:s}')".format(i, i))plt.show()計(jì)算結(jié)果
好了,讓我們一起來看看最終的實(shí)現(xiàn)效果吧~
球面均勻分布4點(diǎn)球面均勻分布36點(diǎn)總結(jié)
以上是生活随笔為你收集整理的阵列信号处理及matlab实现_球形麦克风阵列设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开发常用工具
- 下一篇: matlab 点太多,matlab输出参