이동평균 필터

이동평균은 추세의 변동을 알 수 있도록 구간을 옮겨 가며 구하는 평균을 말한다.




실제로 이동평구현한 결과


< 이동평균 필터 >



< 이동평균 필터(순간변화) >


사용 결과 약간의 딜레이가 생기는거 같은데 FILTERSIZE를 줄이면 딜레이가 줄어들 것 같다. 


작업환경 : Codevision (Version : 2.05.0 Evaluation)

---------------------- mov_average.h -----------------------


#ifndef __AVERAGE_H__

#define __AVERAGE_H__


#define FILTERDATA 10

int avg (int x);


#endif // __AVERAGE_H__


-----------------------------------------------------



---------------------- mov_average.c ----------------------


#include <mega128.h>

#include "my_header.h"


int data[FILTERDATA];


int avg (int x)

{

    unsigned char i;

    int sum = 0, average;

    

    for (i = 0; i < FILTERDATA - 1; i++)

        data[i] = data[i+1];

        

    data[FILTERDATA - 1] = x;

        

    for (i = 0; i < 10; i++)

        sum += data[i]; 

    

    average = sum / FILTERDATA;

    

    return average;

}  


-------------------------------------------------




이동평균필터 재귀식



< 배치식 >


유도 과정



식을 자세히 보면, 새로운 평균값은 이전 평균값에서 가장 오래된 데이터 값을 데이터 개수로 나눈 값을 빼주고 새로운 값을 데이터 개수로 나누 값을 더해준 결과이다. 즉, 오래된 데이터값 대신 새로운 데이터 값을 가중치를 곱해주어 더해준 값이다. 일반적인 평균에서 각 데이터의 가중치는 항상 1/n 으로 일정하다.



실행 결과







주황색이 이동평균필터 재귀식을 사용한 것이고 회색이 그냥 이동평균필터이다. 보면 거의 비슷한 것을 알 수 있다.



개발 환경 : Codevision (Version : 2.05.0 Evaluation)


---------------------- mov_average_recursioin.h -----------------------


#ifndef __MOVE_AVERAGE_FILTER__

#define __MOVE_AVERAGE_FILTER__


#define MOV_FILTERSIZE 4

#define CHANNEL     4



//int MovingAverage(int, unsigned char);

int MovingAverage(int input);

#endif //__MOVE_AVERAGE_FILTER__


-------------------------------------------------------------------



---------------------- mov_average_recursioin.c ----------------------


#include "my_header.h"


int MovingAverage(int input)

{

    static int data[MOV_FILTERSIZE];

    

    static int average = 0;

    unsigned char i;

    

    average = average + (input - data[0])/MOV_FILTERSIZE;

         

        

    for (i = 0; i < MOV_FILTERSIZE - 1; i++)

        data[i] = data[i+1];

        

    data[i] = input;

        

    return average;

}

------------------------------------------------------------------


---------------------- mov_average_recursioin.c (쉬프트 연산자로 하는 방법) ----------------------

int average = 0;


void MovAvgRecursion(int input)

{

    static int data[MOV_FILTERSIZE];

    unsigned char i;    

    int temp;

    

    

    temp = input - data[0];    

    

    if (temp < 0) temp += 3;

    average += temp >> 2;

    

    for (i = 0; i < MOV_FILTERSIZE - 1; i++)

        data[i] = data[i+1];

        

    data[i] = input;

}


----------------------------------------------------------------

Posted by 나무길 :