课题要用到数字滤波器,我根据信号的抽样频率,本身的频率及要求的频带范围,用巴特沃思法设计了模拟滤波器的系统函数,并转化成了关于Z的数字滤波函数...接下来,我不知道具体要怎么做了.我的想法是对的采集的数据进行FFT变换,把2N个点分离成二个N个点的采样值,一个做为实部,一个做为虚部,用复数的FFT得到变换结果,但是结果依然是2N个数,问题1:实数的FFT变换后,也应该是复数才对,如果实部占一个单元,虚部占一个单元,那2N实数的FFT变换后也应该是4N个数才对啊(应该变成了复数的话,实部虚部得各占一个单元),这是为什么呢?问题二:即使我FFT转换好了,有书上介绍,把FFT转换结果与滤波器系统函数相乘,再经IFFT就得到滤波后的结果,但是我怎么相乘呢?滤波器的系统函数是关于Z的一个函数,Z等于多少呢?我用上面得到的FFT变换结果,如何相乘呢?问题三:有很多书上都讲MATLAB上的数字滤波,我现在在自己用VC编的工程上要用到滤波,最终得产品化.我是否也可以用MATLAB来进行?
请有过数字信号处理实践开发经验的朋友不吝赐教啊.千言万语,只在一个"谢"字了.

解决方案 »

  1.   

    问题1,N个实数FFT,应该增加了N个0(隐含的虚部),结果为2N(实部N,虚部N)  复数的FFT时就不一样了问题2,是不是褶积啊,,不过褶积又会改变数据长度不好取舍,,
          可以把滤波器扩展成相同的数据长度(相应频率充0),对应相乘试试问题3,用Matcom把Matlab的数字滤波函数转化(编译)成C++语言我对数字滤波不太懂,但做的谱好像效果还行,
      

  2.   

    我的想法是对的采集的数据进行FFT变换,把2N个点分离成二个N个点的采样值,一个做为实部,一个做为虚部,用复数的FFT得到变换结果,但是结果依然是2N个数,问题1:实数的FFT变换后,也应该是复数才对,如果实部占一个单元,虚部占一个单元,那2N实数的FFT变换后也应该是4N个数才对啊(应该变成了复数的话,实部虚部得各占一个单元),这是为什么呢? 
    1)把2N个点分离成二个N个点的采样值,一个做为实部,一个做为虚部,用复数的FFT,要知道你这样实际上不仅改变了原来序列的采样间隔。而且把实序列改变成复数序列。
    2)一个N长实序列,做FFT应该得到一个N长的复数序列。(N长的复数序列,就是N个复数,不要想象成2N个实数,如果你一定要这样想象,那首先要明白是实数还是复数)
      

  3.   

    问题二:即使我FFT转换好了,有书上介绍,把FFT转换结果与滤波器系统函数相乘,再经IFFT就得到滤波后的结果,但是我怎么相乘呢?滤波器的系统函数是关于Z的一个函数,Z等于多少呢?我用上面得到的FFT变换结果,如何相乘呢? Z用FFT转换结果(复数序列)代替,(相乘的意思不是四则运算,应该算信号与系统术语:用一个函数作用于一个信号的意思)得到一串新的复数序列。
      

  4.   

    问题三:有很多书上都讲MATLAB上的数字滤波,我现在在自己用VC编的工程上要用到滤波,最终得产品化.我是否也可以用MATLAB来进行? 
    当然可以。
      

  5.   

    rover___说的不错
    问题一:FFT的代码网上有无数,运算时都是用complex运算的,自己看看就明白了
    问题二,相乘在信号处理中就是卷积,编写起来很简单的。
    问题三:你如果调用matlab的话,运行速度会比C++慢很多,但如果你运算要求的实时性不高的话
    ,也可以考虑调用matlab,但最好还是自己实现,这样效率会高很多!
    你这点滤波算法实现起来难度也不大,我建议自己写
      

  6.   

    记得有个算法是同时计算两个序列的FFT,,分别作为实部和虚部,,但中间的转换过程都忘记了,不过现在计算机速度这么快,没必要弄得这么麻烦
    /* time fft */
    /* flag==1 fft; flag==-1 ifft */
    //输入:fr为实部,fi虚部  对于实数序列fi为0   
    //输出:fr为实部,fi虚部
    //振幅谱:temp[j] = sqrtf(fr[j]*fr[j] + fi[j]*fi[j]);
    //相位谱:temp[j] = atanf(-1*fi[j]/fr[j]);     //0 == fr[j]时相位是pi/2
    //2008.5.23 11:30 Devang
    void tfft(float *fr,float *fi,int n,int flag)
    {
    int mp,arg,cntr,p1,p2;
    int i,j,a,b,k;
    float sign,pr,pi,harm,t;
    float *ca,*sa;
    ca = new float [n];
    sa = new float [n];
    if(ca==NULL||sa==NULL)
    return ;
    j=0;
    if(flag!=1)
    {
    sign=1.0;
    }
    else 
    sign=-1.0;
    for(i=0;i<=n-2;++i)
    {
    if(i<j)
    {
    t=fr[i];
    fr[i]=fr[j];
    fr[j]=t;
    t=fi[i];
    fi[i]=fi[j];
    fi[j]=t;
    }
    k=n/2;
    while (k<=j)
    {
    j-=k;
    k/=2;
    }
    j+=k;
    }
    mp=0;
    i=n;
    while(i!=1)
    {
    mp+=1;
    i/=2;
    }
    harm = (float)(2*PI/n);
    for(i=0;i<=n-1;++i)
    {
    sa[i]=(float)(sign*sin(harm*i));
    ca[i]=(float)(cos(harm*i));
    }
    a=2;
    b=1;
    for(cntr=1;cntr<=mp;++cntr)
    {
    p1=n/a;
    p2=0;
    for(k=0;k<=b-1;++k)
    {
    i=k;
    while(i<n)
    {
    arg=i+b;
    if(k==0)
    {
    pr=fr[arg];
    pi=fi[arg];
    }
    else
    {
    pr=fr[arg]*ca[p2]-fi[arg]*sa[p2];
    pi=fr[arg]*sa[p2]+fi[arg]*ca[p2];
    }
    fr[arg]=fr[i]-pr;
    fi[arg]=fi[i]-pi;
    fr[i]+=pr;
    fi[i]+=pi;
    i+=a;
    }
    p2+=p1;
    }
    a*=2;
    b*=2;
    }
    delete [] ca;
    delete [] sa;
    ca = NULL;
    sa = NULL;
    if(flag!=1)
    {
    for(i=0;i<=n-1;++i)
    {
    fr[i]=fr[i]/n;
    fi[i]=fi[i]/n;
    }
    return;
    }
    }