본문 바로가기
카테고리 없음

C# OpenCV를 활용한 Moving Average(이동 평균) 및 Fast Moving Average 알고리즘 구현

by tasiklee 2025. 2. 17.

1. 이동 평균(Moving Average) 알고리즘이란?

이동 평균(Moving Average)은 데이터의 변동성을 줄이고 추세를 파악하는 데 사용되는 기법입니다. 주로 금융, 영상 처리, 신호 처리 등 다양한 분야에서 활용됩니다. 특히 영상 처리에서는 연속된 이미지의 평균을 구해 노이즈를 줄이거나 부드러운 영상 변화를 만드는 데 사용됩니다.

2. 이동 평균 알고리즘의 주요 활용 분야

이동 평균 필터는 많은 분야에서 자주 활용되는데, 주로 다음과 같은 상황에서 사용됩니다!

📌 1) 이미지 노이즈 제거

카메라 센서에서 발생하는 작은 잡음을 제거하는 데 사용됩니다. 이동 평균을 적용하면 이미지의 변화가 부드러워지면서 랜덤한 노이즈가 감소.

📌 2) 배경 제거 및 객체 추적

이동 평균을 이용하면 배경을 부드럽게 변화시키면서 움직이는 객체를 더욱 명확하게 분리할 수 있습니다. 이는 보안 카메라, 트래킹 시스템 등에 사용 됨.

📌 3) 금융 및 데이터 분석

주식 차트 분석에서 가격의 변동성을 줄이고 전반적인 추세를 파악하는 데 이동 평균이 활용됩니다. 5일 이동 평균, 20일 이동 평균과 같은 지표가 대표적임.

3. OpenCV를 활용한 이동 평균 및 Fast Moving Average 적용 방법

C#에서 OpenCV(EmguCV)를 활용하여 정적인 이미지에 이동 평균 및 Fast Moving Average 필터를 적용 하여 보다 부드러운 영상을 만들어 볼 수 있겠습니다!

4. C# OpenCV(EmguCV) 코드 예제

아래는 EmguCV를 사용하여 이미지에 대해 Moving Average 필터와 많은 연산량으로 인한 tact time을 줄이기 위해 Fast Moving Average 필터를 적용 해 보도록 하겠습니다!

🔹 이동 평균 필터 (일반적인 방식)

using System;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;

class MovingAverageFilter
{
    static void Main()
    {
        // 이미지 불러오기
        Mat image1 = CvInvoke.Imread("image1.jpg", ImreadModes.Color);
        Mat image2 = CvInvoke.Imread("image2.jpg", ImreadModes.Color);
        Mat image3 = CvInvoke.Imread("image3.jpg", ImreadModes.Color);
        
        if (image1.IsEmpty || image2.IsEmpty || image3.IsEmpty)
        {
            Console.WriteLine("이미지를 불러올 수 없습니다.");
            return;
        }

        // 이동 평균 계산 (수동 연산)
        Mat avgImage = new Mat(image1.Size, DepthType.Cv8U, 3);
        byte[] imgData1 = image1.GetRawData();
        byte[] imgData2 = image2.GetRawData();
        byte[] imgData3 = image3.GetRawData();
        byte[] avgData = new byte[imgData1.Length];

        for (int i = 0; i < imgData1.Length; i++)
        {
            avgData[i] = (byte)((imgData1[i] + imgData2[i] + imgData3[i]) / 3);
        }

        avgImage.SetTo(avgData);
        
        // 결과 출력
        CvInvoke.Imshow("Moving Average Image", avgImage);
        CvInvoke.WaitKey(0);
    }
}

🔹 Fast Moving Average (빠른 이동 평균) 코드

Fast Moving Average는 새로운 이미지가 들어올 때 기존 평균에서 일부만 업데이트하는 방식으로 기존보다 연산량을 줄인 방법입니다! 

using System;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;

class FastMovingAverageFilter
{
    static void Main()
    {
        // 이미지 불러오기
        Mat prevAvgImage = CvInvoke.Imread("image1.jpg", ImreadModes.Color);
        Mat newImage = CvInvoke.Imread("image2.jpg", ImreadModes.Color);
        
        if (prevAvgImage.IsEmpty || newImage.IsEmpty)
        {
            Console.WriteLine("이미지를 불러올 수 없습니다.");
            return;
        }

        double alpha = 0.2; // 가중치 설정
        byte[] prevData = prevAvgImage.GetRawData();
        byte[] newData = newImage.GetRawData();
        byte[] fastAvgData = new byte[prevData.Length];

        for (int i = 0; i < prevData.Length; i++)
        {
            fastAvgData[i] = (byte)((1 - alpha) * prevData[i] + alpha * newData[i]);
        }

        prevAvgImage.SetTo(fastAvgData);
        
        // 결과 출력
        CvInvoke.Imshow("Fast Moving Average Image", prevAvgImage);
        CvInvoke.WaitKey(0);
    }
}

5. 이동 평균 알고리즘의 장점과 단점

✅ 장점

  • 간단한 구현: 이동 평균 알고리즘은 쉽게 적용할 수 있으며 계산량이 다소 적다고 볼 수 있습니다.
  • 효과적인 노이즈 제거: 급격한 변화나 작은 노이즈를 줄이는 데 효과적입니다.
  • 다양한 응용 가능: 영상뿐만 아니라 금융, 데이터 분석 등 다양한 분야에 활용되고 있습니다.

❌ 단점

  • 빠른 변화 감지 어려움: 이동 평균 필터는 빠른 움직임을 부드럽게 만들어, 빠른 변화가 필요한 경우에는 다소 적절하지 않을 수 있습니다.
  • 과거 데이터 의존: 과거 프레임이나 데이터의 영향을 계속 유지하기 때문에 최신 변화를 즉각 반영하기 어렵습니다.

7. 결과 및 활용

이 코드를 실행하면 기본 이동 평균과 Fast Moving Average 결과를 비교할 수 있습니다. Fast Moving Average는 연산량이 적고 실시간 적용이 가능하여 실시간 영상 처리 및 트래킹에 적절하다고 볼 수 있습니다!