소프트웨어/음성프로그래밍

4. Convolution과 Filter를 ANSI C로 설계

cs만두 2013. 6. 24. 03:20

>> x=[1 100 1 100 2 50 2 10 30 20 1 2];
>> h=[2 3 1 2 3];
>> conv(h,x)

ans =

     2   203   303   305   508   508   359   380   198   294   118   117   137    64     7     6

>> filter(h,1,x)

ans =

     2   203   303   305   508   508   359   380   198   294   118   117

일단 MATLAB으로 테스트한 테스트 데이터는 다음과 같다.

 

 

 1

 

 

 

 

 x

10 

6

 

 

 

 

 h

 

 

 

 

 

 

 

 

 

 

 

 

 10

 

 

 

 

 

 

10 

 

 

 

 

 

 

 10

 

 

 

 

 

 

 10

 

 y

10 

19 

..

.. 

.. 

.. 

.. 

.. 

.. 

.. 

 

 

<----- 

------ 

------

 필

터 

후 

데 

이 

터 

---> 

 

 

 

 

일단 카테고리 3번글에서 테스트한 데이터로 위의 convolution table을 만들어 보았다.

테이블에서 참고할 수 있듯이 convoultion데이터는 13개가 생기고( 0부터  Xn+ Yn-1 ),

필터후의 데이터는 10개가 생긴다.( 0부터 들어온 데이터의 갯수)

 

그래서 convoultion소스를 아래와 같이 구성해 보았다.

#include<stdio.h>
#include<stdlib.h>

void conv(int *h,int *x,int *y,int *filterY,int lengthH,int lengthX){
 /*printf("%d %d %d",h,x,length);*/
 int i=0,j=0;
 int outLength= lengthX+(lengthH-1);
 
 for(i=0; i< lengthX;i++)
  for(j=0; j< lengthH;j++)
   y[i+j]=x[i]*h[j]+y[i+j];

}


 

int main(){
 //int x[]={10,9,8,7,6,5,4,3,2,1};
 //int h[]={1,1,1,1};
 int i=0;
 
 int x[]={1,100,1,100,2,50,2,10,30,20,1,2};
 int h[]={2,3,1,2,3};
 
 int lengthH= sizeof(h) / sizeof(int);
 int lengthX= sizeof(x) / sizeof(int);
 int outLength= lengthX+(lengthH-1);
 int *y;
 int *filterY;
 y=(int *)calloc( outLength,sizeof(int));
 filterY=(int *)calloc( x, sizeof(int));

 conv(h,x,y,filterY,lengthH,lengthX);
 printf("x와 h의 convolution결과 :\n");
 for(i=0;i<outLength; i++)
  printf("%d ",y[i]);

}

 

그 결과

 

 

matlab에서 conv함수를 돌린 결과와 같았다.

이 후 filter함수의 구현은 단순하게 0~들어온 데이터의 index만큼만 새로운 배열에 복사하는 식으로 구현해서.

void filter(int *h,int *x,int *y,int *filterY,int lengthH,int lengthX){
 int i=0;
 conv(h,x,y,filterY,lengthH,lengthX);
 for(i=0;i<lengthX;i++)
  filterY[i]=y[i];
}

다음과같이 wraped 함수로 만들어 주었다.

 

그 결과

 

 

MATLAB에서 filter(h,x)로 돌린 결과와 같은 결과를 얻을 수 있었다.

 

구성한 소스에서는 int로 배열을 구성하였지만, double이나 float으로 구성한다면 매트랩같이 복잡한 값도 계산 할 수 있을 듯 하다.