bandpass butterworth filter implementation in C++

前端 未结 4 1589
醉酒成梦
醉酒成梦 2021-02-03 11:59

I am implementing an image analysis algorithm using openCV and c++, but I found out openCV doesnt have any function for Butterworth Bandpass filter officially. in my project I

4条回答
  •  深忆病人
    2021-02-03 12:29

    I finally found it. I just need to implement the following code from matlab source code to c++ . "the_mandrill" were right, I need to add the normalizing constant into the coefficient:

    kern = exp(-j*w*(0:length(b)-1));
    b = real(b*(kern*den(:))/(kern*b(:)));
    

    EDIT: and here is the final edition, which the whole code will return numbers exactly equal to MATLAB :

    double *ComputeNumCoeffs(int FilterOrder,double Lcutoff, double Ucutoff, double *DenC)
    {
        double *TCoeffs;
        double *NumCoeffs;
        std::complex *NormalizedKernel;
        double Numbers[11]={0,1,2,3,4,5,6,7,8,9,10};
        int i;
    
        NumCoeffs = (double *)calloc( 2*FilterOrder+1, sizeof(double) );
        if( NumCoeffs == NULL ) return( NULL );
    
        NormalizedKernel = (std::complex *)calloc( 2*FilterOrder+1, sizeof(std::complex) );
        if( NormalizedKernel == NULL ) return( NULL );
    
        TCoeffs = ComputeHP(FilterOrder);
        if( TCoeffs == NULL ) return( NULL );
    
        for( i = 0; i < FilterOrder; ++i)
        {
            NumCoeffs[2*i] = TCoeffs[i];
            NumCoeffs[2*i+1] = 0.0;
        }
        NumCoeffs[2*FilterOrder] = TCoeffs[FilterOrder];
        double cp[2];
        double Bw, Wn;
        cp[0] = 2*2.0*tan(PI * Lcutoff/ 2.0);
        cp[1] = 2*2.0*tan(PI * Ucutoff / 2.0);
    
        Bw = cp[1] - cp[0];
        //center frequency
        Wn = sqrt(cp[0]*cp[1]);
        Wn = 2*atan2(Wn,4);
        double kern;
        const std::complex result = std::complex(-1,0);
    
        for(int k = 0; k<11; k++)
        {
            NormalizedKernel[k] = std::exp(-sqrt(result)*Wn*Numbers[k]);
        }
        double b=0;
        double den=0;
        for(int d = 0; d<11; d++)
        {
            b+=real(NormalizedKernel[d]*NumCoeffs[d]);
            den+=real(NormalizedKernel[d]*DenC[d]);
        }
        for(int c = 0; c<11; c++)
        {
            NumCoeffs[c]=(NumCoeffs[c]*den)/b;
        }
    
        free(TCoeffs);
        return NumCoeffs;
    }
    

提交回复
热议问题