신호 처리 업무를 하면서 가끔씩은 디지털 필터가 필요한 경우가 있습니다. 저도 최근에 DC 성분을 제거하는 DC 제거 필터가 필요해서 검색을 해보니 아래 주소에서 굉장히 좋은 글을 발견할 수 있었습니다.

DC 제거 필터 관련 읽어볼만한 글

https://www.embedded.com/design/configurable-systems/4007653/DSP-Tricks-DC-Removal

위 링크의 글에서 확인할 수 있는 바와 같이 가장 기본적인 DC 제거 필터의 시간 도메인 수식은 아래와 같습니다.

DC 제거 필터 수식

x[n] - x[n-1] = y[n] – a* y[n-1], a < 0

DC 제거 필터의 zero 가 1 이 됨으로서 DC 에 무한대의 attenuation 을 주게 되고 a 값이 1 에 가까워 질수록 notch 의 기울기가 증가하게 됩니다.

numerator [1 -1], denominator [1 -0.95] 인 경우의 DC 필터에 대해 MATLAB을 사용하여 알아보면~

freqz 명령어를 통해 Frequency response 를 확인할 수 있고 명령어는 아래와 같습니다.

freqz([1 -1], [1 -0.95],512,1000)

zero-pole plot 을 확인하기 위해스는 zplane 명령어를 사용하고 아래와 같이 확인 할 수 있습니다.

zplane([1 -1], [1 -0.95])

Impulse response 에 대해 확인하기 위해서는 impz 함수를 사용하고 아래 예와 같이 사용합니다.

impz([1 -1], [1 -0.95])

디지털 필터 관련 참고 자료들

IIR Filter 관련 읽어볼만한 글

http://www.eas.uccs.edu/~mwickert/ece2610/lecture_notes/ece2610_chap8.pdf

Lecture Notes

http://www.eas.uccs.edu/~mwickert/ece2610/lecture_notes/

DC 필터 이외의 다양한 필터들에 대한 수식들

저주파 통과 필터

y[k] = a*y[k-1]+(1-a)*x[k],  a < 0

고주파 통과 필터

y[k] = -a*y[k-1]+(1-a)*x[k], a < 0

평균 필터

y[k] = [(k-1)/k]*y[k-1]+(1/k)*x[k]

N 이동평균 필터

y[k] = y[k-1] + (x[k]-x[k-N])/N



아래 글에도 답변을 달았지만 MATLAB 에서도 linked list 를 구성 할 수 있습니다.

 

http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=104&docId=194575538&page=1#answer1

 

위 글에서 소개한 바와 같이 MATLAB 에서 linked list 를 구성하고자 하는 경우 classdef 을 사용했는데요~

 

오늘은 간단하게 Filter Class 를 하나 만들어보죠.

 

Filter 함수는 아래 주소에서 소개하듯이 1차원 디지털 필터입니다.

 

http://www.mathworks.co.kr/kr/help/matlab/ref/filter.html

 

MATLAB filter() 함수에 대해서는 아래 포스팅에서도 소개한 바가 있습니다.

2013/09/21 - [programming language/MATLAB] - MATLAB filter() 함수의 고급 사용


2011/03/01 - [programming language/MATLAB] - conv(), filter(), 인수분해 전개

 

filter 함수를 루프 내에서 사용하고자 하는 경우 그 연속성을 위해 filter의 state 를 계속해서 출력했다 저장했다 해야 하는데~

 

이런 경우 Class 의 형태로 만들어서 사용하는 게 편리하다고 생각합니다.

 

제가 사용하고 있는 Filter Class 는 아래 코드의 filter_O.m 파일입니다. 


filter_O.m Class 는 굉장히 간단하게 구성되어 있는데요~

 

filter_O의 생성자에서 필터의 numerator b 값과 denominator a 값을 설정하고~

 

멤버 함수인 filtering() 함수를 사용해서 filtering 을 수행하면 됩니다.

 

Filter 의 state 인 zi 값은 멤버 변수로 만들었고, 멤버 변수 out 이 필터의 출력 값입니다.


아래 코드의 Filtertest.m 파일을 실행해 보시면~ 



아래 그림과 같이 기존 filter 함수와 동일한 결과를 나타내는것을 확인 할 수 있습니다. 



필터 함수는 FIR 또는 IIR 필터링을 수행하는데 이용이 되는 함수이다.

다음과 같이

Z=filter(x,1,y); 하면 x 라는 필터 계수를 가진 필터로 FIR 필터링을 수행하는 것이다.

그런데 filter() 함수를 한번만 이용하는 것이 아니라 루프를 이용하여 필터링을 해야 하는 경우가 있다.

예를 들면 프레임 단위의 시뮬레이션을 하는 경우 등이다.

이럴 때는 filter() 함수의 옵션 몇 가지를 이용하면 가능 하다.

filter() 함수는 다음과 같이 이용할 수 있다.


[y,zf] = filter(b,a,X,zi)


위 표현에서 y 는 필터링 결과 zf 는 필터의 최종 상태, zi 는 초기 상태, b 는 필터의 numerator, a 는 필터의 denumerator, X 는 필터의 입력 이다.

zi 값은 a, b 의 길이중 최대값 -1 의 길이를 갖는다.

 

예를 들어 a=[1 ] 이고 b=[ 1 2 3 4 5] 라고 한다면

a 의 길이는 1 이고 b 의 길이는 5 이므로 zi 의 길이는 5-1 = 4 가 된다.

필터의 초기값으로 0 을 준다면 zi=zeros(4, 1) 이라고 선언을 하면 되는 것이다.

 

그럼 for 루프 안에서 필터링을 연속으로 하는 예를 들어 보자.

X=rand(100) 이라는 100 행 100 열의 매트릭스의 값을 각 열 별로 for 문을 이용하여 필터링을 해 볼 것이다.

 

X=rand(100); % X 의 값

a=[1]; % 필터의 denumerator

b=[1 2 3 4 5]; % 필터의 numerator

zi = zeros(4,1); % 필터의 초기 상태

Y=zeros(100); % 필터링 결과를 저장 할 버퍼

 

이제 for 문을 구성 해 본다.

 

for n=1:100

[Y(:,n) zi]=filter(b,a,X(:,n), zi); % 이 부분에서 필터 초기 상태와 필터 최종상태의 변수를

% 동일하게 놓음으로서 상태가 연속이 되도록 할 수 있는것이다.

end

 

위 결과값 Y(:) 는

Y2=filter(b,a,X(:)) 의 결과인 Y2 값과 동일한 결과이다.



+ Recent posts