| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- public
- Gradient
- Contour
- stream
- flutter
- Class
- digitalRead
- Gaussian
- memory
- UNO
- parameter
- Binary
- subpixel
- Unity
- sensor
- file access
- Android
- compare
- APP
- Encapusulation
- aduino
- wpf
- SERIAL
- mfc
- atmega328
- Read
- Pointer
- c++
- edge
- Filtering
- Today
- Total
폴크(FOLC)
치수 계산하기 - smooth filtering 3 본문
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;
}