강좌,팁

[강좌:23] Noisy 신호를 Filtering 하기(1)

조회 수 13377 추천 수 0 2004.07.23 15:37:02
허창원 *.218.140.126

우리나라 기계공업의 중심지 창원시 팔용동으로 진출하기 직전의 강좌가 되겠습니다.
그리고, 정들었던 수출자유지역과 그 부근 마산 봉암동이여, 나 극동테크를 잊지 마시라... ^ ^ (2004.7.23)
----------------------------------------------------------------------------------------------

[강좌:23] Noisy 신호를 Filtering 하기

기준툴: LabWindows/CVI 7
활용수준: 고급 (신호처리 이론이 적용되므로...)

차례
프롤로그
1. IIR Filter의 기본 이론
2. 이번 예제 프로그램의 개요
    2.1 Noisy 신호

    2.2 처리절차

3. 프로그래밍 시작단계
    3.1 통상적인 준비

    3.2 추가되는 모듈

4. 데이터 입출력
    4.1 Data 관련 모듈 소스 파일
    4.2 데이터 초기화
    4.3 데이터 파일 불러오기
    4.4 결과 데이터 저장하기
5. Filtering
    5.1 LPF 모듈 소스

    5.2 필터 계수 구하기

    5.3 한 Sample 단위로 Filtering 하기

    5.4 Block Filtering

6. 실제 Filtering 시 더 고려할 것
    6.1 Amplitude attenuation

    6.2 Phase shift(delay)

에필로그

 

프롤로그
오래 전부터 꼭 강좌로 만들기로 작정하고 있었던 주제가 필터링(Filtering)입니다. 왜냐하면, 저의 대학원 전공의 일부분이며 실제적으로도 필요하기 때문이죠!  하지만, 제가 원래 우수한 학생은 아니어서 배운 것도 잘 모르는 게 많습니다. 너그러이 이해하시길...
예전에 보던 Digital Signal Processing 관련 책을 뒤적여 보면서 겨우 기억을 되살렸습니다만, DSP에서 Filter가 차지하는 비중이 너무 크고, 내용도 아주 세분화되어 있기 때문에 도무지 어디서부터 어디까지를 강좌에 담아야 할지를 결정하기가 무척 어렵더군요.
그래서, 실무적인 내용으로 최대한 간단히 만들었습니다. 이 강좌로 인해 지도교수님의 명성에 먹칠을 하지는 않기를 바랍니다.(창원대학교 전자공학과 신호처리 하판봉 교수님, 이 아둔한 제자, 이 자리를 빌어 인사 올립니다. 꾸벅 헤헤~긁적긁적~)

좀 곁길로 샜습니다. 하여튼, 필터링은 필요한 것이죠!

그럼, 간단히 이론적인 내용을 먼저 살펴볼까요?

1. IIR Filter의 기본 이론
FIR(Finite Impulse Response) filter와 IIR(Infinite Impulse Response) filter는 나름대로 각각 장단점이 있고, 어느 쪽이 절대적으로 유리하다고 판단할 수 없을 것 같습니다. 용어의 직접적인 의미는, Impulse 신호에 대한 time-domain 상의 응답특성이 유한(finite)하냐, 무한(infinite)하냐 하는 것입니다.

특징을 간단히 살펴보면, FIR filter의 경우 transfer function 에 pole(분모의 근에 해당) 부분이 없기 때문에 항상 stable하고, 가장 큰 특징은 아마도 linear phase response 특성이 아닐까 생각합니다. 즉, 필터링을 하면, 주파수 변화에 따른 위상 변화가 선형적(linear)이라는 것이고, 이러한 특성을 꼭 필요로하는 응용분야에 적합한 filter입니다.
반면에, IIR filter의 경우에는 좀더 적은 수의 계수만으로 보다더 sharp한 cutoff 특성을 보여주므로, 처리시간(processing time)이나 계수저장크기(storage) 면에서 보다더 유리하다고 할 수 있죠! 대신에 위상 특성은 비선형적(nonlinear)이기 때문에, 위상정보가 중요한 응용에 사용하기는 좀 부적합하죠!

필터링을 하고자 하는 응용에 따라 적절한 Filter를 구성해야겠지만, 이번 강좌에서는 IIR Filter 방식의 Butterworth 2'nd order Low Pass Filtering을 이용하겠습니다.

아래의 recursive 식 (1.1)이 IIR filter의 time-domain 상의 동작을 묘사하고 있습니다. 여기서 recursive 라는 의미는 한번의 필터링 계산에서 나온 출력값이 다음 계산에서 입력값으로 이용되는 것을 말합니다.

(1.1)

식 (1.2)는 전달함수(transfer function)의 z-domain 표현입니다.

(1.2)

IIR filter를 디자인한다는 것은 식 (1.2)의 분자, 분모 항에 각각 있는 a, b 계수들을 원하는 특성에 맞도록 구하는 것을 말합니다. 분모에 있는 다항식의 근을 pole 이라고 하고, 분자 다항식의 근을 zero라고 합니다. 즉, 분모항이 0이 된다는 것은, H(z)가 infinite한 Gain을 갖는 경우가 되므로 pole이라고 하고, 분자항이 0이 되는 다항식의 근은 H(z)를 0이 되도록 만들므로 zero라고 합니다. 이들 계수값을 적절히 선정하여 불안정한 System이 되지 않도록 해야겠는데, 이번 강좌에서는 LabWindows/CVI의 analysis 함수인 Bw_Coef() 함수를 이용하여 filter 계수를 구할 것입니다.
실제 filtering 과정은 이렇게 구해진 filter 계수를 식 (1.1)에 적용하여, 입력값 x(n)과 이전의 출력값 y(n-k)을 이용하여 진행됩니다.

2. 이번 예제 프로그램의 개요
이번 강좌의 예제에 이용할 Noisy 데이터는 제가 프로젝트를 진행하며 수집해 두었던, noise 가 섞인 데이터입니다. 그때의 Sampling Rate 는 10kHz였고, 측정하고자 했던 신호는 우리나라 AC 전원 주파수에 해당하는 60 Hz 정도였습니다. 이런 경우, 노이즈 제거를 위해 Low Pass Filter(LPF)를 이용하는 것이 좋겠죠?

2.1 Noisy 신호
그림 2.1과 그림 2.2에 이번 예제에 이용될 시험 데이터를 보였습니다.

그림 2.1 NoisySignal_10K_Sampling_1.dat 데이터

 

그림 2.2 NoisySignal_10K_Sampling_2.dat 데이터

주변의 Noise에 어쩔 수 없이 노출되어 있는 환경에서 획득한 신호들입니다.

2.2 처리절차
그림 2.3에 미리보는 실행화면을 보였습니다. 화면 디자인은 거의 무시하고, 설명이 편하도록 만들었습니다. 아시죠? ㅎㅎ

그림 2.3 미리보는 실행화면

실행화면상의 명령행 버튼들을 차례대로 눌러주면서 필터링 과정을 이해하기 쉽도록 하였고, 버튼은 sample by sample, 즉 한 샘플씩 필터링을 하는 형식이고, 버튼은 여러 샘플의 집합인 Block 단위의 필터링을 하기에 적합한 형식입니다. 하지만 Block 단위의 필터링이라도 해당 Block의 데이터 수가 1이라고 보면, sample by sample 처리와 같아집니다.

그리고, 화면 중간에 보이는 수식부분은 구해진 필터계수를 보여주기 위한 것입니다. z(-1)은 z-1로 이해해 주시면 되겠습니다.

그림 2.4 필터계수 출력부분

3. 프로그래밍 시작단계

3.1 통상적인 준비
통상적인 준비 과정은 "[강좌:21] CVI 프로그래밍 시작단계 정의(2)" 강좌 글에 의거하여, 간단히 정리하겠습니다.

프로젝트 파일명: L023_IIRFiltering.prj

화면구성은 그림 2.3을 참고하십시오.

uir 파일 내의 Panel과 각 컨트롤의 속성은 각각 표 3.1과 표 3.2와 같이 설정합니다.

표 3.1 Panel의 속성설정

Panel Constant Name Callback Function Panel Title
메인 패널(메인 화면) PANEL PanelCB L023_IIRFiltering v1.0.001

 

표 3.2 컨트롤의 속성값

컨트롤 종류 Constant Name Callback Function Label 비고
Command Button cmdReset cmdReset Reset  
Command Button cmdOpen cmdOpen

1. 데이터 파일 불러오기

 
Command Button cmdCoef cmdCoef

2. 필터계수 구하기

 
Command Button cmdLPF_1 cmdLPF_1

3-1. LPF_Butt_2( ) Filtering

 
Command Button cmdLPF_2 cmdLPF_2

3-2. IIRFiltering( ) Filtering

 
Command Button cmdSaveAs cmdSaveAs

4. 결과를 파일로 저장하기

 
Graph

GRAPH_NoisySignal

  Noisy Signal - Show Legend: uncheck
Graph

GRAPH_FilteredSignal

  Filtered Signal - Show Legend: uncheck
Numeric

numSampFreq

  Sampling Frequency -Data type:double
-Default Value: 100000
-Format and Precison의 Precision : 0
- Show/Hide의 Show Inc/Dec Arrows: uncheck

Numeric

numCutoffFreq

  Low pass Cutoff Frequency -Data type:double
-Default Value: 60
-Format and Precison의 Precision : 0
- Show/Hide의 Show Inc/Dec Arrows: uncheck

 

그리고, 기본 소스를 생성합니다.

3.2 추가되는 모듈
소스 파일의 기능적 구분을 명확히 하기 위해 "[강좌:21] CVI 프로그래밍 시작단계 정의(3)" 강좌 글에 의거하여, 통합헤더 파일인 L023_IIRFiltering_DEF.h, 일반적인 사용자 정의 함수 파일인 L023_IIRFiltering_common.h와 L023_IIRFiltering_common.c 파일, 데이터의 저장과 파일 입출력을 위한 L023_IIRFiltering_Data.h와 L023_IIRFiltering_Data.c 파일, 그리고, Low Pass Filter를 위한 L023_IIRFiltering_LPF.h와 L023_IIRFiltering_LPF.c 파일이 추가되는데, 그림 3.1에 프로젝트 창 화면을 보였습니다.

그림 3.1 L023_IIRFiltering.prj 프로젝트 구성

이 절에서는 통합헤더파일인 L023_IIRFiltering_DEF.h 와 일반적인 사용자 정의 함수 파일인 L023_IIRFiltering_common.h와 L023_IIRFiltering_common.c 파일을 설명드리고, 나머지는 이후의 절에서 설명하도록 하겠습니다.

먼저, 그림 3.2에 L023_IIRFiltering_DEF.h 파일을 보였습니다.

그림 3.2 L023_IIRFiltering_DEF.h 통합헤더파일

통합헤더파일에 대해서는 더 이상 말씀드릴 필요가 없겠군요. 그림 3.3에 L023_IIRFiltering_common.h 파일에 대한 설명 그림을 보였습니다.

그림 3.3 L023_IIRFiltering_common.h 파일 설명

그림 3.4에는 L023_IIRFiltering_common.c 파일의 일부를 보였습니다. 아직 Data 파일에 대한 내용을 언급하지 않았기 때문에, 데이터 초기화 함수 Reset_L023_IIRFiltering_DATA() 와 그래프 갱신 함수의 파라미터 사용에 대해 금방 이해되지는 않을 겁니다.

그림 3.4 L023_IIRFiltering_common.c 파일

그림 3.5에는 수정된 main() 함수 부분을 보였습니다.

그림 3.5 수정된 main() 함수 부분(L023_IIRFiltering.c 파일)

4. 데이터 입출력

4.1 Data 관련 모듈 소스 파일
Data를 관리하기 위한 소스 모듈이 L023_IIRFiltering_Data.h와 L023_IIRFiltering_Data.c입니다. 우선 그림 4.1에 L023_IIRFiltering_Data.h 파일을 보였습니다.

그림 4.1 L023_IIRFiltering_Data.h 파일

그림에 설명을 붙여 놓았기 때문에 추가 설명이 필요없겠습니다. 예제를 위해 간단하게 Data 관련 변수들을 선언하였습니다. 좀더 큰 규모로 가거나 복잡한 프로젝트를 수행하실 때는 전체를 묶어서 구조체로 하는 게 다루기 좋겠죠? 만약, CVI가 C++을 지원한다면, 함수까지 모두 포함해서 클래스로 선언하면 금상첨화가 되겠는데 말이죠!

그림 4.2에는 L023_IIRFiltering_Data.c 파일의 일부를 보였습니다. 그림에 링크된 소스를 보시면 모두 나타날 것입니다.

그림 4.2 L023_IIRFiltering_Data.c 파일

데이터 파일은 text 형식의 파일이고, 그림 4.3과 같이 시간값과 그 시간의 측정값으로 이루어져 있습니다.

그림 4.3 NoisySignal_10K_Sampling_1.dat 데이터 파일

4.2 데이터 초기화
버튼을 클릭하면, 데이터 메모리를 초기화합니다. 그림 4.4에 콜백함수 부분을 보였습니다. 이 함수는 L023_IIRFiltering.c 파일에 있습니다.

그림 4.4 cmdReset() 콜백함수(L023_IIRFiltering.c 파일)

Reset_L023_IIRFiltering_DATA() 함수를 보시면 아시겠지만, 실제로 data 배열을 초기화하지는 않습니다. 그냥 데이터가 하나도 없다는 식으로 초기화가 이루어지고, 그래프 갱신하는 함수에서는 그 데이터 수만큼 그래프로 그리기 때문에 초기화 된 거로 볼 수 있지요.

4.3 데이터 파일 불러오기
불러올 데이터 파일을 선택하여, L023_IIRFiltering_Data.c 의 함수를 호출하는 콜백함수도 L023_IIRFiltering.c 에 기본틀이 만들어져 있습니다. 실제 파일로부터 불러오는 부분은 L023_IIRFiltering_Data.c 에 정의된 Open_L023_IIRFiltering_TextData() 함수입니다. 그림 4.5에 cmdOpen() 콜백함수를 보였습니다.

그림 4.5 cmdOpen() 콜백함수(L023_IIRFiltering.c 파일)

4.4 결과 데이터 저장하기
처리된 데이터를 파일로 저장하는 콜백함수 cmdSaveAs()를 그림 4.6에 보였습니다.

그림 4.6 cmdSaveAs() 콜백함수(L023_IIRFiltering.c 파일)

 

"[강좌:23] Noisy 신호를 Filtering 하기(2)" 로 계속 이어집니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
74 [계획] CVI 강좌를 좀더 체계화하기 위해... 메모함 허창원 2005-05-19 13923
73 [강좌:28] 나만의 대화상자를 라이브러리(Static,DLL)로 만들기(2) 허창원 2005-03-12 13202
72 [강좌:28] 나만의 대화상자를 라이브러리(Static,DLL)로 만들기(1) file 허창원 2005-03-12 14610
71 [강좌:27] 내 입맛에 맞는 대화 상자 만들기 file 허창원 2005-03-11 13332
70 자동 파일 생성 코드 [1] 허만회 2005-03-03 12158
69 [팁:10] CVI로 DLL 만들기(요약) file [1] 허창원 2005-02-22 17935
68 [강좌:26] 간단한 RS-232 통신예(NI-VISA 함수 이용) 허창원 2005-02-05 73676
67 [강좌:25] 간단한 RS-232 통신예(RS-232용 함수 이용) [2] 허창원 2005-02-05 24029
66 [팁:9] 프로그램 내에서 메뉴 만드는 과정 요약 file 허창원 2005-01-22 11308
65 [팁:8] UIR 파일을 실행파일에 포함하는 방법 file [2] 허창원 2005-01-22 18531
64 [강좌:24] 수치를 String 컨트롤에 출력 file 허창원 2004-12-01 11625
63 [강좌:23] Noisy 신호를 Filtering 하기(2) 허창원 2004-07-23 11758
» [강좌:23] Noisy 신호를 Filtering 하기(1) file 허창원 2004-07-23 13377
61 [강좌:22] 드래그 앤 드롭 이용하기 [1] 허창원 2004-07-06 12055
60 [강좌:21] CVI프로그래밍 시작단계 정의(3) [1] 허창원 2004-07-06 11151
59 [강좌:21] CVI프로그래밍 시작단계 정의(2) 허창원 2004-07-06 11847
58 [강좌:21] CVI프로그래밍 시작단계 정의(1) 허창원 2004-07-06 11893
57 [팁:7] 작업화면 스타일 선택하기 [1] 허창원 2004-07-05 14031
56 [팁:6] 배포판(설치) 프로그램에 데이터 폴더 포함하기 허창원 2004-05-20 12953
55 [팁:5] Parallel Port 이용할 때, CVI Low-level support driver [2] 허창원 2004-05-18 11947