반응형
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 3 본문

카테고리 없음

치수 계산하기 - smooth filtering 3

folcjin 2025. 6. 28. 10:19
728x90
반응형

Wiener Filter
- 노이즈를 억제하면서 신호를 왜곡 없이 보존하는 것이 목표.
- 선형 필터 중 평균 제곱 오차(Mean Square Error, MSE)를 최소화함.

동작 방식
- 입력 (신호 + 잡음)
- 출력 y[n]는 다음 조건을 만족하도록 설계:

- 주파수 영역에서의 형태 (1D 버전):

  • S(f) : 신호 파워 스펙트럼
  • N(f) : 노이즈 파워 스펙트럼

 

간단한 1D Wiener Filter 구현 로직

핵심 공식 (시간영역 근사)

  • μ : 로컬 윈도우 평균
  • σ2 : 로컬 신호 분산
  • ν2 : 노이즈 추정 분산 (전역 평균 또는 사전 정보)

 

예제

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

// 평균 계산 함수
double mean(const std::vector<double>& data) {
    return std::accumulate(data.begin(), data.end(), 0.0) / data.size();
}

// 분산 계산 함수
double variance(const std::vector<double>& data, double data_mean) {
    double var = 0.0;
    for (auto v : data) {
        var += (v - data_mean) * (v - data_mean);
    }
    return var / data.size();
}

// 1D Wiener Filter
std::vector<double> wienerFilter(const std::vector<double>& signal, int windowSize, double noiseVariance = -1.0) {
    int N = signal.size();
    int half = windowSize / 2;
    std::vector<double> output(N);

    // 전체 평균 기반으로 노이즈 분산 추정 (옵션)
    if (noiseVariance < 0) {
        double global_mean = mean(signal);
        noiseVariance = variance(signal, global_mean) * 0.1;  // 약한 노이즈 가정
    }

    for (int i = 0; i < N; ++i) {
        std::vector<double> window;
        for (int j = -half; j <= half; ++j) {
            int idx = std::clamp(i + j, 0, N - 1);
            window.push_back(signal[idx]);
        }

        double local_mean = mean(window);
        double local_var = variance(window, local_mean);

        double gain = (local_var > 0.0) ? std::max(0.0, (local_var - noiseVariance) / local_var) : 0.0;
        output[i] = local_mean + gain * (signal[i] - local_mean);
    }

    return output;
}

int main() {
    std::vector<double> input = {10, 12, 11, 80, 12, 11, 10};  // 스파이크 포함된 노이즈 신호
    int windowSize = 3;
    
    std::vector<double> filtered = wienerFilter(input, windowSize);

    std::cout << "Wiener Filter Output:\n";
    for (double v : filtered) {
        std::cout << v << " ";
    }
    std::cout << std::endl;
    return 0;
}

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