반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

폴크(FOLC)

치수 계산하기 - smooth filtering 본문

카테고리 없음

치수 계산하기 - smooth filtering

folcjin 2025. 6. 21. 20:20
728x90
반응형

Savitzky-Golay 필터는 신호 처리에서 널리 사용되는 데이터 평활화 기법으로, 특히 노이즈를 줄이면서 신호의 주요 특성(예: 피크, 경향선 등)을 보존해야 할 때 효과적입니다.

이동 윈도우 내의 다항 회귀를 통해 중심값을 재계산하여 평활화하는 방법입니다. 보통 단순 이동 평균은 신호를 과도하게 평탄화하여 중요한 피크나 변화를 손실할 수 있는데, 이 필터는 신호의 형상 보존에 강점이 있습니다.

원리
- 주어진 윈도우 크기와 다항 차수를 바탕으로, 해당 구간의 데이터를 최소자승법(Least Squares) 으로 다항식에 맞추고 중심값을 계산합니다.
- 이는 선형 컨볼루션처럼 미리 계산된 계수를 사용하여 구현할 수 있습니다.

파라미터
- window size (odd integer): 적용할 데이터 포인트의 개수
- polynomial order: 다항식 차수 (2~4 정도가 보통 사용됨)

 

예제

#include <iostream>
#include <vector>
#include <numeric>
#include <cmath>

std::vector<double> savitzkyGolaySmooth(const std::vector<double>& data, int windowSize, int polyOrder) {
    int halfWindow = windowSize / 2;
    int size = data.size();
    std::vector<double> result(size, 0.0);

    // Precompute convolution coefficients (assuming polyOrder == 2 for simplicity)
    // For general implementation, you need to use matrix inversion.
    std::vector<double> coeffs(windowSize);
    int m = halfWindow;
    for (int i = -m; i <= m; ++i) {
        coeffs[i + m] = 1.0 - (3.0 * i * i) / (m * (m + 1));  // Quadratic S-G
    }

    // Normalize coefficients
    double coeffSum = std::accumulate(coeffs.begin(), coeffs.end(), 0.0);
    for (auto& c : coeffs) c /= coeffSum;

    // Apply filter
    for (int i = 0; i < size; ++i) {
        double smoothed = 0.0;
        for (int j = -m; j <= m; ++j) {
            int idx = i + j;
            if (idx < 0) idx = 0;
            if (idx >= size) idx = size - 1;
            smoothed += data[idx] * coeffs[j + m];
        }
        result[i] = smoothed;
    }

    return result;
}

int main() {
    std::vector<double> rawData = {10, 12, 15, 14, 13, 15, 18, 20, 19, 17};
    int windowSize = 5;  // Must be odd
    int polyOrder = 2;

    std::vector<double> smoothed = savitzkyGolaySmooth(rawData, windowSize, polyOrder);

    for (double v : smoothed) {
        std::cout << v << " ";
    }
    std::cout << std::endl;

    return 0;
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --