① 二階濾波器用c語言怎麼寫
這個可比你想像的復雜多了,s是個復變數,1/(s+1)極點在-1,要想用C語言寫,必須理解清楚下面幾個問題:
1、輸入必須是個有限序列,比如(x+yi),x和y分別是兩個長度為N的數組
2、要過濾的頻率,必須是個整型值,或者是個整型區間
3、輸出結果同樣是兩個長度為N的數組(p+qi)
4、整個程序需要使用最基本的復數運算,這一點C語言本身不提供,必須手工寫復函數運算庫
5、實現的時候具體演算法還需要編,這里才是你問題的核心。
我可以送你一段FFT的程序,自己琢磨吧,和MATLAB的概念差別很大:
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "complex.h"
extern "C" {
// Discrete Fourier Transform (Basic Version, Without Any Enhancement)
// return - Without Special Meaning, constantly, zero
int DFT (long count, CComplex * input, CComplex * output)
{
assert(count);
assert(input);
assert(output);
CComplex F, X, T, W; int n, i;
long N = abs(count); long Inversing = count < 0? 1: -1;
for(n = 0; n < N ; n++){ // compute from line 0 to N-1
F = CComplex(0.0f, 0.0f); // clear a line
for(i = 0; i < N; i++) {
T = input[i];
W = HarmonicPI2(Inversing * n * i, N);
X = T * W;
F += X; // fininshing a line
}//next i
// save data to outpus
memcpy(output + n, &F, sizeof(F));
}//next n
return 0;
}//end DFT
int fft (long count, CComplex * input, CComplex * output)
{
assert(count);
assert(input);
assert(output);
int N = abs(count); long Inversing = count < 0? -1: 1;
if (N % 2 || N < 5) return DFT(count, input, output);
long N2 = N / 2;
CComplex * iEven = new CComplex[N2]; memset(iEven, 0, sizeof(CComplex) * N2);
CComplex * oEven = new CComplex[N2]; memset(oEven, 0, sizeof(CComplex) * N2);
CComplex * iOdd = new CComplex[N2]; memset(iOdd , 0, sizeof(CComplex) * N2);
CComplex * oOdd = new CComplex[N2]; memset(oOdd , 0, sizeof(CComplex) * N2);
int i = 0; CComplex W;
for(i = 0; i < N2; i++) {
iEven[i] = input[i * 2];
iOdd [i] = input[i * 2 + 1];
}//next i
fft(N2 * Inversing, iEven, oEven);
fft(N2 * Inversing, iOdd, oOdd );
for(i = 0; i < N2; i++) {
W = HarmonicPI2(Inversing * (- i), N);
output[i] = oEven[i] + W * oOdd[i];
output[i + N2] = oEven[i] - W * oOdd[i];
}//next i
return 0;
}//end FFT
void __stdcall FFT(
long N, // Serial Length, N > 0 for DFT, N < 0 for iDFT - inversed Discrete Fourier Transform
double * inputReal, double * inputImaginary, // inputs
double * AmplitudeFrequences, double * PhaseFrequences) // outputs
{
if (N == 0) return;
if (!inputReal && !inputImaginary) return;
short n = abs(N);
CComplex * input = new CComplex[n]; memset(input, 0, sizeof(CComplex) * n);
CComplex * output= new CComplex[n]; memset(output,0, sizeof(CComplex) * n);
double rl = 0.0f, im = 0.0f; int i = 0;
for (i = 0; i < n; i++) {
rl = 0.0f; im = 0.0f;
if (inputReal) rl = inputReal[i];
if (inputImaginary) im = inputImaginary[i];
input[i] = CComplex(rl, im);
}//next i
int f = fft(N, input, output);
double factor = n;
//factor = sqrt(factor);
if (N > 0)
factor = 1.0f;
else
factor = 1.0f / factor;
//end if
for (i = 0; i < n; i++) {
if (AmplitudeFrequences) AmplitudeFrequences[i] = output[i].getReal() * factor;
if (PhaseFrequences) PhaseFrequences[i] = output[i].getImaginary() * factor;
}//next i
delete [] output;
delete [] input;
return ;
}//end FFT
int __cdecl main(int argc, char * argv[])
{
fprintf(stderr, "%s usage:\n", argv[0]);
fprintf(stderr, "Public Declare Sub FFT Lib \"wfft.exe\" \
(ByVal N As Long, ByRef inputReal As Double, ByRef inputImaginary As Double, \
ByRef freqAmplitude As Double, ByRef freqPhase As Double)");
return 0;
}//end main
};//end extern "C"
② 巴特沃斯濾波器c語言實現
說的很對,濾波玩的就是增益(衰減)變化,不同的頻率,不同的增益(衰減)。稱幅頻曲線。
1、巴特奧斯濾波器的截止頻率指-3db通頻帶頻率,也就是在這個頻率以內保證暢通(通帶)。
2、另一個指標叫做阻帶,頻率大於此值能夠保證衰減大於某值
③ 求IIR及FIR數字濾波器的C語言實現。(VC++)
這個問題比較復雜,最近本人也在研究數字濾波,
結合圖片說一下
第一個圖是fir的流程圖,其中Z-1是延遲,是單個采樣時間1/fs
n階的fir濾波器就是選取最近的n+1個樣本,然後使他們各自乘以自己的濾波器系數即圖中的F(n),[一般其他書的表示是h(n)]
然後相加得到輸出的y(n)就是一個輸出點
,其中F(n)的得出需要根據采樣頻率和濾波器的通帶和阻帶來決定
其中為了改善旁瓣的幅值,一般在采樣後給樣本或者h(n)加窗,當然可以用「最佳方法」來做
得出h(n)大致方法是先將矩形窗進行DFT,得出h(n),然後對h(n)進行加窗得出h(k),然後將∑h(k)×x(n)=y(n),假如階數較多可以用傅里葉變換使時域變頻域後再將卷積相加,可以利用FFT來改進實時性,提升速度
上面就是fir濾波器的簡述
第二個圖片上傳不了,直接給鏈接
http://image..com/i?ct=503316480&z=0&tn=imagedetail&word=%D2%BB%BD%D7iir%C2%CB%B2%A8%C6%F7&in=12708&cl=2&cm=1&sc=0&lm=-1&pn=0&rn=1&di=2607528304&ln=1054&fr=
圖中的Z-1是延時,iir濾波器也叫無限沖擊響應濾波器,是有反饋的,
圖中的是一階的,相對fir濾波器來說,iir濾波器可以用較低的階數來獲得較好的濾波特效。但是其相位特性較差。
鑒於實用性,還是建議樓主去圖書館借書看,網路不可能得到確實的方案,
樓主可以去借「數字信號處理」的書,國外的中譯本就有詳細介紹fir和iir以及fft還有其他變換,國內的dsp大都幾乎是dsp用戶手冊的中譯本,對上述問題都是很簡陋地帶過,不予置評。
本人推薦一本書在www.ouravr.com上面的dsp專欄有下載,40多M,叫DSP演算法、應用和設計,本人有這本實體書,寫的較好
④ c語言中值濾波問題
1. 是規定做中值濾波的點不含邊緣的點(取決於中值濾波窗口大小)。 2,對圖像邊緣部分的信息進行鏡像處理。
⑤ 幫幫忙,能不能給我 基於C語言的FIR濾波器設計的程序代碼(包括CMD,C,ASM),謝謝了 真的很急!!!
#include"math.h"
void firwin(n,band,fln,fhn,wn,h)
int n,band,wn;
double fln,fhn,h[];
{int i,n2,mid;
double s,pi,wc1,wc2,beta,delay;
double window();
beta=0.0;
if(wn==7)
{printf("input beta parameter of Kaiser window(2<beta<10)\n");
scanf("%1f",&beta);
}
pi=4.0*atan(1.0);
if((n%2)==0)/*如果n是偶數*/
{n2=n/2+1;/*這行什麼意思*/
mid=1;
}
else
{n2=n/2;
mid=0;
}
delay=n/2.0;
wc1=2.0*pi*fln;
if(band>=3) wc2=2.0*pi*fhn;/*先判斷用戶輸入的數據,如果band參數大於3*/
switch(band)
{case 1:
{for(i=0;i<=n2;i++)
{s=i-delay;
h[i]=(sin(wc1*s)/(pi*s))*window(wn,n+1,i,beta);
h[n-i]=h[i];
}
if(mid==1) h[n/2]=wc1/pi;
break;
}
case 2:
{for(i=0;i<=n2;i++)
{s=i-delay;
h[i]=(sin(pi*s)-sin(wc1*s))/(pi*s);
h[i]=h[i]*window(wn,n+1,i,beta);
h[n-i]=h[i];
}
if(mid==1) h[n/2]=1.0-wc1/pi;
break;
}
case 3:
{for(i=0;i<n2;i++)
{s=i-delay;
h[i]=(sin(wc2*s)-sin(wc1*s))/(pi*s);
h[i]=h[i]*window(wn,n+1,i,beta);
h[n-i]=h[i];
}
if(mid==1)h[n/2]=(wc2-wc1)/pi;
break;
}
case 4:
{for(i=0;i<=n2;i++)
{s=i-delay;
h[i]=(sin(wc1*s)+sin(pi*s)-sin(wc2*s))/(pi*s);
h[i]=h[i]*window(wn,n+1,i,beta);
h[n-i]=h[i];
}
if(mid==1)h[n/2]=(wc1+pi-wc2)/pi;
break;
}
}
}
static double window(type,n,i,beta)
int i,n,type;
double beta;
{int k;
double pi,w;
double kaiser();
pi=4.0*atan(1.0);
w=1.0;
switch(type)
{case 1:
{w=1.0;
break;
}
case 2:
{k=(n-2)/10;
if(i<=k)
w=0.5*(1.0-cos(i*pi/(k+1)));
break;
}
case 3:
{w=1.0-fabs(1.0-2*i/(n-1.0));
break;
}
case 4:
{w=0.5*(1.0-cos(2*i*pi/(n-1)));
break;
}
case 5:
{w=0.54-0.46*cos(2*i*pi/(n-1));
break;
}
case 6:
{w=0.42-0.5*cos(2*i*pi/(n-1))+0.08*cos(4*i*pi/(n-1));
break;
}
case 7:
{w=kaiser(i,n,beta);
break;
}
}
return(w);
}
static double kaiser(i,n,beta)
int i,n;
double beta;
{
double a,w,a2,b1,b2,beta1;
double bessel0();
b1=bessel0(beta);
a=2.0*i/(double)(n-1)-1.0;
a2=a*a;
beta1=beta*sqrt(1.0-a2);
b2=bessel0(beta1);
w=b2/b1;
return(w);
}
static double bessel0(x)
double x;
{int i;
double d,y,d2,sum;
y=x/2.0;
d=1.0;
sum=1.0;
for(i=1;i<=25;i++)
{d=d*y/i;
d2=d*d;
sum=sum+d2;
if(d2<sum*(1.0e-8)) break;
}
return(sum);
}
這是窗函數法的,當然還有其他的比如切比雪夫,零相位濾波什麼的,我也在研究,不是很懂哈
⑥ 給定一個信號s,包括高頻、低頻成份,現在做一個低通濾波器對信號進行濾波,求c語言程序,急急急!
教你實現方法吧:
第一步:你需要採用MATLAB 設計濾波器的脈沖響應序列,如記為h(n) = [ h1,h2,... hN]
第二步:c 語言實現的是 y(n) = h(n) 卷積x(n) 其中h(n)和x(n)都是向量
詳細代碼很簡單,自己來吧。
⑦ 只是用簡單的C語言,能實現高斯濾波嗎
可以的。
int*** SmoothImage(int ***XImage ,int width, int height, int channel)
{
double sigma = 1.85; //(n/2 -1)*0.3 +0.8 { n = 9 ,no. of elements}
double conv[3][3];
double hg = 0;
//Convolution kernel
for(i=0; i<3;i++)
{
for(j=0;j<3;j++)
{
int u=i-1; //subtract from centre element index in 3*3 (1,1)
int v=j-1;
conv[i][j] =exp ( - ((u*u) + (v*v)) / (2*sigma*sigma) );
hg += conv[i][j];
}
}
for(int i=0; i<3;i++)
{
for(int j=0;j<3;j++)
{
conv[i][j] = conv[i][j] / hg;
}
}
int*** sXImage = 0;
sXImage = CreateImageMatrix( sXImage , width , height , channel );// allocating a 3d array
//Assigning weights
for(int i =0; i < height ; i++)
{
for(int j =0; j < width ; j++)
{
for(int k =0; k < 3 ; k++)
{
double val = 0;
double valw =0;
if(j-1 > 0 && i-1 > 0)
{
val += conv[0][0] * XImage[i-1][j-1][k];
valw += conv[0][0];
}
if(i-1 > 0 )
{
val += conv[0][1] * XImage[i-1][j][k];
valw += conv[0][1];
}
if(i-1 > 0 && j+1 < width)
{
val += conv[0][2] * XImage[i-1][j+1][k];
valw += conv[0][2];
}
if(j-1 > 0 )
{
val += conv[1][0] * XImage[i][j-1][k];
valw += conv[1][0];
}
val += conv[1][1] * XImage[i][j][k];
valw += conv[1][1];
if(j+1 < width)
{
val += conv[1][2] * XImage[i][j+1][k];
valw += conv[1][2];
}
if(j-1 > 0 && i+1 < height)
{
val += conv[2][0] * XImage[i+1][j-1][k];
valw += conv[2][0];
}
if(i+1 < height)
{
val += conv[2][1] * XImage[i+1][j][k];
valw += conv[2][1];
}
if(j+1 < width && i+1 < height)
{
val += conv[2][2] * XImage[i+1][j+1][k];
valw += conv[2][2];
}
sXImage[i][j][k] = val / valw;
}
}
}
return( sXImage);
}
⑧ 求:一個關於FIR帶通濾波器的C語言設計程序 代碼
short h[], short y[])
{
int i, j, sum; for (j = 0; j < 100; j++) {
sum = 0;
for (i = 0; i < 32; i++)
sum += x[i+j] * h[i];
y[j] = sum >> 15;
}
}
2
void fir(short x[], short h[], short y[])
{
int i, j, sum0, sum1;
short x0,x1,h0,h1; for (j = 0; j < 100; j+=2) {
sum0 = 0;
sum1 = 0;
x0 = x[j];
for (i = 0; i < 32; i+=2){
x1 = x[j+i+1];
h0 = h[i];
sum0 += x0 * h0;
sum1 += x1 * h0;
x0 = x[j+i+2];
h1 = h[i+1];
sum0 += x1 * h1;
sum1 += x0 * h1;
}
y[j] = sum0 >> 15;
y[j+1] = sum1 >> 15;
}
}
3
void fir(short x[], short h[], short y[])
{
int i, j, sum0, sum1;
short x0,x1,x2,x3,x4,x5,x6,x7,h0,h1,h2,h3,h4,h5,h6,h7; for (j = 0; j < 100; j+=2) {
sum0 = 0;
sum1 = 0;
x0 = x[j];
for (i = 0; i < 32; i+=8){
x1 = x[j+i+1];
h0 = h[i];
sum0 += x0 * h0;
sum1 += x1 * h0;
x2 = x[j+i+2];
h1 = h[i+1];
sum0 += x1 * h1;
sum1 += x2 * h1;
x3 = x[j+i+3];
h2 = h[i+2];
sum0 += x2 * h2;
sum1 += x3 * h2;
x4 = x[j+i+4];
h3 = h[i+3];
sum0 += x3 * h3;
sum1 += x4 * h3;
x5 = x[j+i+5];
h4 = h[i+4];
sum0 += x4 * h4;
sum1 += x5 * h4;
x6 = x[j+i+6];
h5 = h[i+5];
sum0 += x5 * h5;
sum1 += x6 * h5;
x7 = x[j+i+7];
h6 = h[i+6];
sum0 += x6 * h6;
sum1 += x7 * h6;
x0 = x[j+i+8];
h7 = h[i+7];
sum0 += x7 * h7;
sum1 += x0 * h7;
}
y[j] = sum0 >> 15;
y[j+1] = sum1 >> 15;
}
}