평균필터

제목만 보고 이글을 읽지 않으시는 분들이 분명히 많을것 같습니다 ㅋㅋ

무슨 중학생도 아니고 평균을 언급하고 그래?

라는 생각 분명히 하셨지요? ㅋㅋ

저도 그랬거든요 ㅋㅋ

이래서 역시 사람은 겸손하고, 돌다리도 두들겨 보고 가고 이래야 합니다 ㅋㅋ

자 여기서 문제 ~

문) 10Hz 로 샘플링되는 데이터가 계속 들어오고 있다. 1초동안 각 데이터가 들어올때 변화하는 평균값의 추이를 보고자한다. 이를 구현하라.

너무 쉽나요? ㅋㅋ

역시 여러분은 똑똑하군요 ㅋㅋ

이 멍청한 저는 말이지요 ㅋㅋㅋ

이렇게 구현했습니다 ㅋㅋㅋ

데이터의 처음부터 새로들어오는 데이터까지 다 더하고, 데이터 갯수로 나눈다. ㅋ

아 심플하고 직관적이다 ㅋㅋㅋ 역시 멋지다 ㅋㅋㅋ

요로면 망합니다 ㅋㅋㅋ

이전 데이터 까지의 평균을 계산하기 때문에 그 값을 이용한다면 Stack 의 사용량과 연산량을 대폭 줄일수 있겠죠? ㅋㅋ

자 그럼 한번씩 읽어 보시기 바랍니다



오... ㅋㅋ

이렇게 재귀식을 이용해서 계산하니까 어떠세요? ㅋㅋㅋ

처음부터 무식하게 다 더하는 그런 짓을 하지 않아도 될것 같은 느낌이 들지요? ㅋㅋㅋ

이제 이대로 구현해서 어떤 결과를 보여주는지 한번 봐볼까요? ㅋㅋ

이게 정말로 맞는지 궁금하시면, 손으로 직접 같은 결과가 나오는지 계산들 해보세요 ㅋㅋㅋ

이게 Matlab 으로 구현한 함수를 이용해서 계산한 값입니다 ㅋㅋ

5V 전압에 White Noise 가 끼었다고 가정하고 ㅋㅋ

실제 입력 데이터와 출력데이터가 어떻게 나오는지를 살펴보지요 ㅋㅋ

오늘도 어김없이 코드는 제공됩니다 ~ ㅋㅋㅋ

다운받을때 댓글이라도 좀 달아주시고 ㅋㅋ 어떻게 쓰시던 개념치 않겠습니다 ~ ㅋㅋ

그럼 다음에 뵈용 ㅋ~



## 추가 ##

얼마나 계산량의 차이가 나는지를 보고싶어서 ㅋ

1kHz Fs 에 60초간의 데이터를 Average Filtering 취한다고 했을때 수행시간을 알아보겠습니다 ㅋㅋ

1. 재귀식을 이용한 연산 : 1.587초
2. 싸그리 더해서 나누는 연산 : 3.672초

데이터의 수가 많아질수록 이 효과는 극명하게 나타나겠죠? ㅋㅋ
그럼 재미로 300초 데이터로 다시 비교해볼까요?

1. 7.627초
2. 23.895초

ㅋㅋㅋ 극명하게 차이가 나는군요 ㅋㅋ

제공되는 코드는 tic, toc 함수를 사용하여 몇초의 연산이 걸렸는지를 확인할수 있는 걸로 올리겠습니다.

300초 연산으로 잡혀있는것이므로, 컴퓨터가 후달리면 시간을 좀 줄이고 하시길 추천합니당~


 

Posted by J.Bear

댓글을 달아 주세요

  1. 잠퉁이 2013.06.20 04:04  댓글주소  수정/삭제  댓글쓰기

    글 잘 보았습니다. 그런데, 궁금한게 있습니다. 평균필터의 경우, 새로운 데이터가 입력되면 새 평균값을 구하기위해 처음부터 모든 값을 다 더해야 한다고 하셨습니다. 이 부분이 이해가 되지 않는데요, 몇 개의 데이터가 들어왔던, 애초에 평균을 구하기 전에 임의의 저장소에 새 데이터가 들어오기 직전의 총 합이 저장되었을 것으로 생각됩니다.

    가령, {2, 3, 4, 5, 6} 이렇게 5개의 데이터가 차례로 입력되었다면, 평균필터로 평균을 구하기 위해 2, 3, 4, 5, 6의 총합인 20이 임의의 저장소에 저장되어있을 것입니다. 평균은 이 20을 5로 나눈 것이지요. 이 상태에서 다음 데이터인 7이 입력되었다고 가정합니다. 굳이 처음부터 더할 필요가 있을까요? 이미 임의의 저장소에는 7이 입력되기 직전의 총합인 20이 저장돼있을 것이고 단순히 이 20에 7을 더하면 현재까지의 총합 27을 구할 수 있고 이걸 6으로 나누면 현재까지의 평균이 산출될 것입니다.

    저는 매틀랩은 써본 적은 없습니다만, 매틀랩 내에도 데이터를 저장할 수 있는 변수 같은 것을 선언할 수 있지 않을까 생각합니다. 물론, 입력되는 데이터가 많을 수록 연산속도가 점차 느려지는 것은 어쩔 수 없겠지요.

    언젠가는 데이터의 총합이 너무 커서 하나의 변수에 다 저장할 수 없어 변수 내에 있는 값을 다 버리고 처음부터 다시 평균을 구해야 할 때가 오겠지요? 가령, 255까지 저장할 수 있는 unsigned char 타입만 사용할 수 있다고 가정했을 때, 변수에 입력 데이터를 차곡차곡 쌓다보면 255를 넘기게 되어 결국 이 변수를 비우고 처음부터 평균을 다시 구해야 할지도 모릅니다. 그렇다면, 이 부분에서는 다음 입력 데이터가 256이기 전까지는 계속해서 평균을 구할 수 있는 재귀적 평균 필터가 더 유용할 것으로 생각됩니다.

    궁금한 것은 데이터가 입력될 때마다 지금껏 입력된 데이터를 다 더해줘야 한다는 부분인데요, 이 때문에 연산속도의 차이를 보인다고 하셨지요? 앞서 썼지만, 새 데이터가 입력되기 전까지의 값을 임의의 변수에 차곡차곡 쌓아두고 매 평균을 구한다고 한다면 이 때에도 연산속도의 차이가 있을지요? 이전의 총합을 변수에 담아둔다고 가정한다면 오히려 평균필터의 연산속도가 더 빠르진 않을까요? 재귀적 평균이 연산속도 면에서도 우위인 것인지요?

    시뮬레이션을 해볼 수도 없고 글을 읽다보니 문득 이런 의문이 들어 글을 남기게 되었습니다.

    • J.Bear 2013.06.21 16:46 신고  댓글주소  수정/삭제

      잘읽어보았습니다

      말씀하신대로 코드를 짜려면 최소한 2개의 변수가 더필요하겠군요

      cnt, preSum 정도의 변수 말이지요~

      물론 말씀하신대로 연산량으로만보면 둘 사이에 큰 차이가 없을 것으로 사료됩니다. (조만간 시간나면 바로 시뮬레이션 해보겠습니다)

      하지만 명백한것은 매우 소소한 차이지만 메모리의 이점은 확실하군요 ㅋㅋㅋ

      재귀적으로 연산하면 무조건 필요한 입출력만을 가지고 계산할 수 있으니까요 ㅋㅋ

      사실 요즘 MCU 들의 성능이 너무 좋아져서 메모리나 동작클럭에 구애를 받지 않는 경우가 많아졌습니다.
      프로그래머의 선호에 따라 코드를 짜면 크게 문제될것이 없다고 저도 생각합니다 ㅋㅋ

      이 글도 아 이런 방법이 있구나 정도의 리뷰차원에서 가볍게 넘어가는것이 좋을듯 합니다~ ㅋㅋ

      좋은 조언 감사합니다~~~~