Rectangular 필터부터 Savitzky-Golay 필터까지 여섯 가지 1D 스무딩 필터의 수학적 원리, α 블렌딩, 경계 처리, 그리고 인터랙티브 시뮬레이터를 코드 · 다이어그램과 함께 수학적 개념과 구현 방식을 심층 분석합니다.
SonataSmooth.Tune 는 1 차원 수열에 여섯 가지 스무딩 필터를 단일 순회 (single traversal) 로 병렬 적용할 수 있는 .NET Standard 2.0 라이브러리입니다.
입력 배열의 비정상 값을 0.0 으로 치환하여 모든 필터의 안정성을 보장합니다.
Binomial : CalcBinomialCoefficients(W) · Gaussian : ComputeGaussianCoefficients(W, σ) · SG : HouseholderQR (Adaptive 모드 제외 - Adaptive 에서는 매 인덱스마다 비대칭 QR 분해 수행)
원본 (입력) 데이터가 2,000 개 이상이면 행 단위 자동 병렬 처리를 활성화합니다.
단일 순회에서 활성화된 모든 필터의 결과를 동시에 계산합니다.
y[i] = α · filtered + (1 − α) · original - Rect, SG 를 제외한 필터에 적용됩니다.
SonataSmooth 는 1 차원 데이터 스무딩 및 노이즈 제거에 특화되어 있습니다. 단일 차원 데이터셋에 한정되지만, 순차적 수치 신호의 전처리 또는 정제가 필요한 다양한 분야에 폭넓게 적용할 수 있습니다.
| Smoothing Filter | 유형 | 복잡도 / 점 | α 블렌딩 | 강점 |
|---|---|---|---|---|
| Rectangular | 선형 | O(W) | ✗ | 최소 계산 비용 |
| Binomial Avg | 선형 | O(W) | ✓ | 부드러운 가중, 효율적 |
| Binom. Median | 비선형 | O(W log W) | ✓ | 이상치 저항 |
| Gauss. Median | 비선형 | O(W log W) | ✓ | 가우시안 지역성 + 이상치 저항 |
| Gaussian | 선형 | O(W) | ✓ | 형태 보존, 고주파 노이즈 제거 |
| Savitzky-Golay | 선형 | O(W) | ✗ | 피크 높이 · 도함수 구조 보존 |
다양한 신호 패턴에 대해 6 가지 필터가 어떤 성능을 보이는지 한눈에 비교합니다. 각 셀은 해당 조합의 처리 성능 등급을 나타냅니다.
| 신호 패턴 | Rect. | Binom. Avg | Binom. Med | Gauss. Med | Gaussian | S-G |
|---|---|---|---|---|---|---|
| 간헐적 랜덤 노이즈 | 적정 | 양호 | 우수 | ★ 탁월 | 양호 | 우수 |
| 빈번한 랜덤 노이즈 | 미흡 | 적정 | ★ 탁월 | 적정 | 적정 | 적정 |
| 완만한 대형 추세 변화 | 미흡 | 양호 | 양호 | 양호 | 양호 | ★ 탁월 |
| 간헐적 급격한 스파이크 | 미흡 | 적정 | ★ 탁월 | 우수 | 적정 | 적정 |
| 빈번한 / 연속 급격한 스파이크 | 미흡 | 적정 | 적정 | ★ 탁월 | 적정 | 적정 |
| 규칙적인 대진폭 파형 | 미흡 | 적정 | 적정 | 양호 | 적정 | ★ 탁월 |
| 계단 변화 (갑작스런 레벨 전환) | 미흡 | 적정 | ★ 탁월 | 우수 | 적정 | 적정 |
| 복합 주파수 진동 | 미흡 | 양호 | 적정 | 양호 | 양호 | ★ 탁월 |
| 주기적 고주파 노이즈 (일정 톤) | ★ 탁월 | 적정 | 적정 | 양호 | 양호 | 양호 |
| 느린 기저선 표류 + 미세 지터 | 양호 | 양호 | ★ 탁월 | 우수 | 양호 | 우수 |
| 부드러운 곡선 + 완만한 노이즈의 자연 신호 | 적정 | 양호 | 양호 | ★ 탁월 | ★ 탁월 | 우수 |
| 안정된 주기 신호 + 중간 강도 고주파 노이즈 | 적정 | ★ 탁월 | 적정 | 양호 | 양호 | 양호 |
단순하지만 일정한 고주파 노이즈 억제에 효과적입니다. 계산 비용이 가장 낮아 빠른 처리가 필요한 상황에 적합합니다.
균형 잡힌 중간 지대. 특히 중간 강도 노이즈가 포함된 주기 신호에서 강점을 발휘합니다.
다양한 데이터셋과 지표에서 가장 높은 종합 성능을 보여주는 Smoothing Filter. 간헐적 · 빈번한 스파이크, 빈번한 노이즈, 계단 변화 처리에 탁월하여 종합 최강자에 해당하지만, 연속 스파이크에서는 일관성이 다소 낮습니다.
가우시안의 부드러움과 중앙값의 강건함을 결합한 하이브리드 Smoothing Filter. 간헐적 스파이크와 부드러운 곡선 보존에 뛰어나며, 범용성이 높은 대안입니다.
부드러운 곡선과 자연 신호 흐름을 잘 재현하지만, 급격한 변화나 극단적 이상치에는 취약합니다.
파형, 추세, 복합 주파수 보존에 탁월. 과학 데이터 및 부드러운 곡선 분석에 이상적입니다.
종합 결론 : Binomial Median 필터링이 다양한 신호 유형과 평가 지표 전반에 걸쳐 가장 높은 종합 성능을 보여줍니다. Gaussian Median (GWMF) 은 특히 간헐적 스파이크와 노이즈가 섞인 부드러운 곡선 시나리오에서 강력한 범용 대안이며, 나머지 필터들은 각자의 특정 상황에서 고유한 강점을 유지합니다.
| 매개변수 | 타입 | 범위 | 설명 |
|---|---|---|---|
r (radius) | int | ≥ 0 | 커널 반경. 윈도우 크기 W = 2r + 1 |
polyOrder | int | 0 ≤ p < W | SG 다항식 차수 |
boundaryMode | enum | 4 종 | Symmetric · Replicate · ZeroPad · Adaptive |
alpha | double | [0, 1] | 블렌딩 계수. Rect, SG 제외 필터에 적용 |
sigmaFactor | double? | > 0 | σ = W / sigmaFactor. 기본 6.0 |
노이즈가 포함된 신호에 여섯 가지 종류의 필터를 동시 적용한 결과를 미리 확인합니다.
가장 단순한 선형 평활화 Smoothing Filter. 윈도우 내 모든 샘플에 동일한 가중치를 부여하여 산술 평균을 계산합니다.
가중치 벡터:
부엽 (side lobe) 이 높아 Gibbs 현상 (ringing) 을 유발할 수 있습니다. Binomial · Gaussian 등에서 테이퍼링 윈도우가 선호되는 이유입니다.
// SmoothingConductor.cs double invRectDiv = 1.0 / windowSize; // = 1 / W double sum = 0.0; for (int k = -r; k <= r; k++) sum += Sample(i + k); rect[i] = sum * invRectDiv;
파스칼 삼각형의 행 (이항 계수) 을 가중치로 사용하는 가중 이동 평균입니다.
이항 필터는 기본 2 점 평균 필터 [½, ½] 를 (W − 1) 회 반복 컨볼루션한 것과 동치입니다. 따라서 주파수 응답은 코사인의 거듭제곱으로 표현됩니다.
Rectangular 의 sinc 응답과 달리 부엽 (side lobe) 이 전혀 없으며, W 가 커질수록 차단 주파수 이후 급격히 감쇠합니다. CLT (중심극한정리) 에 의해 W → ∞ 일 때 가우시안 응답에 수렴하므로, 이상적인 저역 통과 필터에 자연스럽게 접근합니다.
부엽이 높아 Gibbs 현상 (ringing) 유발. 고주파 성분이 완전히 제거되지 않습니다.
부엽 없음. 부드러운 롤오프. Gaussian 과 유사하되 이산적으로 정확한 계수를 가집니다.
이항 계수를 가중치로 사용하여 가중 중앙값을 구합니다. 평균 (Average) 과 달리 극단 값 (이상치, spike) 에 강건하고 신호의 엣지 · 피크 구조를 보존하는 비선형 필터입니다. Binomial Average 와 동일한 가중치를 사용하되 출력 방법만 다릅니다.
가중치 벡터는 Binomial Average 와 동일합니다:
일반 중앙값 (unweighted median) 은 모든 샘플에 동등한 가중치를 부여합니다. 가중 중앙값은 중앙에 가까운 샘플에 더 높은 가중치를 부여하여, 원본 신호 (중앙 근처) 가 극단값보다 더 큰 영향력을 갖습니다.
Weighted Median 은 비선형 필터이므로 고전적인 전달 함수 H(ω) 가 정의되지 않습니다. 선형 중첩의 원리 (superposition) 가 성립하지 않기 때문입니다. 그러나 유효 주파수 거동 (effective frequency behavior) 은 다음과 같이 특성화할 수 있습니다.
이항 가중 평균과 유사한 저역 통과 효과. 유효 대역폭은 커널 크기 W 와 이항 가중치 분포에 의해 결정됩니다.
선형 필터는 불연속점을 번지게 (blurring) 하지만, 가중 중앙값은 엣지를 보존합니다. 가중치가 부여된 투표 메커니즘이 극단값을 배제하기 때문입니다.
Binomial Average 와 Binomial Weighted Median 은 동일한 가중치를 사용하되, 출력 계산 방식에만 차이가 있습니다. 이는 이상치 (noise spike) 처리 능력을 근본적으로 바꿉니다.
예 : [100, 102, 99, 240, 101], w = [1, 4, 6, 4, 1]
= (100 + 408 + 594 + 960 + 101) / 16 = 135.2 ← 이상치에 끌림
정렬 : 99 (w = 6), 100 (w = 1), 101 (w = 1), 102 (w = 4), 240 (w = 4)
누적 : 6, 7, 8, 12, 16 → T/2 = 8, even → accum == 8 at 101 → TieBreak (101 + 102) / 2 = 101.5 ← 이상치 무시
인덱스 i 를 중심으로 반경 r 값의 윈도우 [i − r, i + r] 에서 W = 2r + 1 개의 샘플과 이항 가중치를 수집합니다. BoundaryMode 에 따라 경계 밖 샘플 처리가 달라집니다.
(값, 가중치) 쌍을 값 기준으로 정렬합니다. 정렬 후 가중치 누적이 의미를 갖습니다. 1D 에서는 배열이 작으므로 (W ≤ 51) Array.Sort 의 IntroSort 가 효율적입니다.
accum > T / 2
정렬된 순서대로 가중치를 누적하며 전체 합 (T) 의 절반을 초과 (strictly greater) 하는 첫 위치를 찾습니다. 이 값이 가중 중앙값입니다. 이항 계수는 정수값이므로 부동소수점 오차가 없습니다.
accum == T / 2이면 두 값 평균
누적합이 정확히 T / 2 와 같으면 (짝수 가중치 합), 현재 값과 다음 값의 산술 평균을 반환합니다. 이항 계수의 합 = 2^(W−1) 이므로, W 가 홀수 (일반적) 이면 합이 2 의 거듭제곱 → 짝수 → TieBreak 가능성 있음.
y[i] = α · WMed + (1 − α) · x[i] - α = 1 이면 완전 Smoothing Filter, α = 0 이면 원본 유지. 0 < α < 1 에서 원본과 Smoothing Filter 결과의 혼합.
// SmoothingConductor.cs - Binomial Weighted Median 핵심 코드 double[] binom = CalcBinomialCoefficients(windowSize); // 1. 윈도우 내 (값, 가중치) 수집 var pairs = new List<(double val, double w)>(); for (int k = -r; k <= r; k++) { double v = Sample(i + k); // BoundaryMode 적용 pairs.Add((v, binom[k + r])); } // 2. 값 기준 정렬 pairs.Sort((a, b) => a.val.CompareTo(b.val)); // 3. 가중 누적합 탐색 double total = pairs.Sum(p => p.w); double half = total / 2.0; bool even = (total % 2) == 0; double accum = 0; for (int j = 0; j < pairs.Count; j++) { accum += pairs[j].w; if (accum > half) { // 4a. 초과 → 즉시 반환 med = pairs[j].val; break; } if (even && accum == half) { // 4b. TieBreak → 두 값 평균 med = (pairs[j].val + pairs[j+1].val) / 2.0; break; } } // 5. α 블렌딩 result[i] = alpha * med + (1 - alpha) * input[i];
이항 계수의 합 T = 2^(W−1) 은 항상 짝수 (W ≥ 2) 입니다. 따라서 가중 누적합이 정확히 T / 2 에 도달할 수 있으며, 이 경우 두 인접 값의 평균을 반환합니다.
| r | W | 이항 계수 | 합 T | T / 2 | TieBreak 가능 |
|---|---|---|---|---|---|
| 1 | 3 | [1, 2, 1] | 4 | 2 | ✓ 예: accum = 1 + 1 = 2 = T / 2 |
| 2 | 5 | [1, 4, 6, 4, 1] | 16 | 8 | ✓ 예: accum = 1 + 4 + ... = 8 |
| 3 | 7 | [1, 6, 15, 20, 15, 6, 1] | 64 | 32 | ✓ |
accum >= half (이상) 을 사용하고 별도 짝수 처리가 없습니다.
가중 중앙값이 이상치 (spike) 에 강건한 이유를 수학적으로 분석합니다.
중앙 가중치가 전체의 50% 미만이면, 중앙에 이상치가 있어도 주변 정상 샘플들이 과반을 차지하여 이상치의 영향을 무시합니다.
| r | 중앙 가중치 | 중앙 비율 | Breakdown Point | 의미 |
|---|---|---|---|---|
| 1 | 2 / 4 | 50.0% | 50.0% | 경계 - 중앙 1 개가 이상치여도 유효 |
| 2 | 6 / 16 | 37.5% | 62.5% | 중앙 + 인접 2 개가 이상치여도 유효 |
| 3 | 20 / 64 | 31.3% | 68.8% | 높은 이상치 내성 |
| 5 | 252 / 1024 | 24.6% | 75.4% | 매우 높은 이상치 내성 |
Adaptive 모드에서는 대칭 축소 (Symmetric Shrinking) 로 left == right 를 보장합니다. 원본 전폭 이항 커널에서 가중치를 추출하여 커널 피크가 항상 위치 i 에 정렬되며 영위상 (zero-phase) 이 유지됩니다.
// Adaptive 분기 - 대칭 축소 + 원본 커널 최고점 정렬 int symR = Math.Min(r, Math.Min(i, n - 1 - i)); int start = i - symR; int W_local = 2 * symR + 1; // left == right == symR → 항상 대칭 // 원본 전폭 커널 binom[] 에서 가중치 추출 double[] localWeights = new double[W_local]; for (int pos = 0; pos < W_local; pos++) localWeights[pos] = binom[(pos - symR) + r]; // 예: i = 1, r = 3 → symR = min(3, min(1, n−2)) = 1 // W_local = 3, binom[(0−1)+3]=binom[2], binom[(1−1)+3]=binom[3], binom[(2−1)+3]=binom[4] // 대칭 축소이므로 커널 피크가 항상 중앙 (위치 i) 에 정렬 → 영위상 filtered = WeightedMedianDoubleWeights(safeInput, start, W_local, localWeights);
Spike 옵션을 변경하여 이상치에 대한 필터의 강건성을 확인하세요. α 값을 조절하여 원본과의 블렌딩 효과를 관찰합니다.
Binomial Median 과 동일한 가중 중앙값 알고리즘에 가우시안 가중치를 사용합니다. sigmaFactor 로 σ 를 정밀 조절하여 커널의 감쇠 강도를 제어할 수 있습니다.
정규화 후 합 = 1 이 됩니다. sigmaFactor 가 클수록 σ 값이 작아져 중앙에 집중하고, 작을수록 σ 값이 커져 넓게 분산됩니다.
Binomial Weighted Median 과 마찬가지로 비선형 필터이므로 선형 전달 함수가 존재하지 않습니다. 그러나 가우시안 가중치에 의한 유효 주파수 거동을 특성화할 수 있습니다.
Gaussian Convolution 과 유사한 저역 통과 효과. σ 가 유효 차단 주파수를 결정합니다. σ ↑ → 대역폭 ↓ → 더 강한 스무딩.
가우시안 가중치로 인해 중앙에 가까운 정상 샘플에 더 높은 투표권을 부여하면서도, 중앙값의 비선형 특성으로 극단값을 배제합니다.
// Binomial Median과의 유일한 차이: 가중치 생성 함수 double[] weights = useGaussianWeights ? ComputeGaussianCoefficients(windowSize, windowSize / sigmaFactor) : CalcBinomialCoefficients(windowSize); // 이후 정렬 + 누적 탐색 로직은 완전히 동일 // 단, 임계값 비교 연산자만 다름: // Binomial : accum > half (strictly greater) // Gaussian : accum >= half (greater or equal)
> vs >=Binomial 의 가중치는 정수값이므로 누적합이 정확히 T / 2 와 일치할 수 있어, accum > half (초과) 와 accum == half (TieBreak) 를 분리합니다.
Gaussian 의 가중치는 실수 값 (exp 결과) 이므로 정확한 T / 2 일치가 사실상 불가능합니다. 따라서 accum >= half (이상) 만 사용하고 별도 짝수 처리 (TieBreak) 가 없습니다.
if (accum > half) → 반환 if (even && accum == half) → 평균
if (accum >= half) → 반환 // TieBreak 없음
sigmaFactor (σF) 는 가우시안 커널의 유효 범위를 결정합니다. 동일한 r 에서 σF 를 바꾸면 가중치 분포 형태가 크게 달라집니다.
| σF | σ (r = 3) | 중앙 가중치 | 가장자리 가중치 | 특성 |
|---|---|---|---|---|
| 3 (넓음) | 2.33 | ~ 0.20 | ~ 0.09 | 모든 샘플 비슷한 비중 → 단순 중앙값에 가까움 |
| 6 (기본) | 1.17 | ~ 0.34 | ~ 0.013 | 중앙 집중 + 먼 샘플 무시 → 균형 |
| 12 (좁음) | 0.58 | ~ 0.68 | ~ 10⁻⁶ | 중앙 거의 단독 → 원본에 가까움 |
Adaptive 모드에서는 대칭 축소 (Symmetric Shrinking) 로 left == right 를 보장하면서 원본 σ 를 유지하고, offset = pos − symRGM (i 로부터의 부호 거리) 을 기반으로 가우시안 가중치를 계산합니다. 커널 최고점이 항상 i 위치에 정렬되며 영위상이 보장됩니다.
// Gaussian Median - Adaptive 분기 (대칭 축소 + 커널 최고점 i 정렬) int symRGM = Math.Min(r, Math.Min(i, n - 1 - i)); int startGM = i - symRGM; int W = 2 * symRGM + 1; // left == right == symRGM → 항상 대칭 // 원본 σ 로 커널을 위치 i 에 정렬 double twoSigSq = 2.0 * sigma * sigma; for (int pos = 0; pos < W; pos++) { int offset = pos - symRGM; // i 로부터의 부호 거리 wts[pos] = Math.Exp(-(offset * offset) / twoSigSq); } // ↑ 원본 σ 사용 : σ_local 재계산 없음
wSum 으로 나눠 정규화한 뒤 Array.Sort 를 수행하여 가중 중앙값 탐색 시 total ≈ 1.0 이 됩니다. 반면 HTML 시뮬레이터 (JavaScript) 는 raw exp() 값을 정규화 없이 weightedMedianGauss 에 전달하고 함수 내부에서 total 을 직접 합산합니다. 가중 중앙값은 가중치의 절대 스케일에 불변 (scale-invariant) 이므로 두 방식의 수치 결과는 완전히 동일합니다.
σ Factor 를 조절하여 가우시안 폭이 중앙값 결과에 미치는 영향을 관찰하세요.
두 필터는 동일한 Weighted Median 알고리즘을 공유하되, 가중치 생성 방식이 다릅니다. 한 가지 차이가 결과물과 사용 시나리오에서 구체적으로 어떤 차이를 만드는지 깊이 분석합니다.
동일한 r 에서 두 필터의 1D 가중치를 시각적으로 비교합니다.
| 항목 | Binomial Weighted Median | Gaussian Weighted Median |
|---|---|---|
| 가중치 생성 | C(W − 1, k) 점화식 O(W) - 정수값 double | exp(−x² / 2σ²) O(W) - 실수값 근사 |
| σ 파라미터 | 없음 - r 값에 의해 분포 자동 결정 | σ = W / sigmaFactor - σF 값으로 분포 형태 조절 |
| 임계값 비교 | accum > half (strictly greater) | accum >= half (greater or equal) |
| TieBreak (짝수 처리) | accum == half → 두 값 평균 | 해당 없음 (실수 가중치, 정확한 일치 불가) |
| 캐싱 | CalcBinomialCoefficients 재사용 가능 | ComputeGaussianCoefficients 매번 계산 |
| Adaptive 경계 | 대칭 축소 + 원본 커널에서 binom[(pos − symR) + r] 추출 (커널 피크 i 정렬, 영위상) | 대칭 축소 + 원본 σ 로 offset 기반 exp() 계산 (커널 피크 i 정렬, 영위상) |
| α 블렌딩 | ✓ | ✓ |
| 수치 정밀도 | 정수값 double - 누적 오차 없음 | exp() 근사 - 미세 누적 오차 가능 |
Weighted Median 이 이상치를 제거하려면 중앙 가중치가 50% 미만이어야 합니다. 50% 이상이면 중앙 샘플 하나가 과반을 차지하여 이상치가 그대로 통과됩니다.
| r | W | Binomial 중앙 % | 노이즈 제거 | Gaussian 중앙 % (σF = 6) | 노이즈 제거 |
|---|---|---|---|---|---|
| 1 | 3 | 50.0% | ✓ 경계 | 78.7% | ✗ Smoothing Filter 무효화 |
| 2 | 5 | 37.5% | ✓ | 47.9% | ✓ |
| 3 | 7 | 31.3% | ✓ | 34.3% | ✓ |
| 5 | 11 | 24.6% | ✓ | 21.8% | ✓ |
| 10 | 21 | 17.6% | ✓ | 11.4% | ✓ |
σ 를 일치시킨 조건에서도 Binomial WM 이 미세하게 우위인 수학적 근거가 네 가지 있습니다.
Binomial B(2r, 0.5) 의 첨도 κ = 3 − 1 / r 은 Gaussian 의 κ = 3 보다 항상 작습니다 (Platykurtic). 이는 가중치가 더 고르게 분산됨을 의미하여 유효 샘플 수 (n_eff) 가 높아지고 추정 분산이 감소합니다.
이항 계수는 정수값 double (1.0, 4.0, 6.0 등) 로 IEEE 754 에서 정확히 표현됩니다. 가중치 누적 연산에서 오차가 없습니다. Gaussian 의 exp() 결과는 무리수 근사이므로 미세한 누적 오차가 발생합니다.
Binomial 분포의 정의역 = [0, W − 1] 로 윈도우와 정확히 일치합니다. Gaussian 은 이론적으로 무한 꼬리를 가지며 윈도우 경계에서 강제 절단 (truncation) 후 재정규화합니다. 이 재정규화는 원래 분포 형태를 미세하게 변형시킵니다.
σ 값을 일치시켜도 꼬리가 얇은 분포 (Platykurtic) 특성을 가진 Binomial 은 중앙 가중치가 항상 Gaussian 보다 낮습니다. 이는 이상치가 중앙에 위치할 때 주변 샘플들이 더 쉽게 주변 샘플들이 이상치를 압도할 수 있음을 의미합니다.
| 상황 | Binomial Median 추천 | Gaussian Median 추천 |
|---|---|---|
| 소형 커널 r = 1 (기본 σF = 6) | ✓ 명백히 우위 | ✗ Smoothing Filter 무효화 - σF 재조율 필수 |
| 소형 커널 r = 2 | ✓ 미세 우위 (중앙 37.5%) | △ 정상 동작 (중앙 47.9%) |
| Salt-Pepper 이상치 제거 | ✓ 모든 r 에서 안정 | r ≥ 2 부터 정상 동작 |
| 배치 처리 (동일 r 반복) | ✓ 캐시 재사용 효과 | 매번 exp() 재계산 |
| 신호 특성에 맞는 정밀 튜닝 | r 값만 조절 - 유연성 낮음 | ✓ σF 로 세밀 조율 |
| 파라미터 없이 빠른 적용 | ✓ r 값만 설정, 즉시 안전 | σF 값 조율 필요 |
| 결론 | Binomial 은 파라미터 없이 안전하고 빠른 기본 선택. Gaussian 은 σF 튜닝으로 정밀 제어가 필요한 전문가 용도. | |
반경을 변경하며 두 필터의 결과 차이를 직접 확인하세요. 이상치 (spike) 포함 신호에서 차이가 뚜렷해집니다.
이산 가우시안 커널과의 컨볼루션을 통한 선형 평활화 필터입니다. 중앙 샘플에 가장 높은 가중치를 부여하며, σ (시그마) 로 감쇠 속도를 제어합니다. Rectangular 보다 부드러운 주파수 응답을 가집니다.
정규화 후 Σĝ = 1 이므로 DC 성분 (상수 신호) 이 완벽히 보존됩니다. Binomial 과 동일한 성질이지만, σ 파라미터로 분포 폭을 자유롭게 조절할 수 있습니다.
연속 도메인에서 가우시안의 푸리에 변환은 다시 가우시안입니다 (자기 유사성). 이 성질은 부엽 (side lobe) 이 없는 이상적인 저역 통과 필터에 가장 근접한 커널임을 뒷받침하며, Rectangular 의 sinc 응답과 대비됩니다.
ComputeGaussianCoefficients) 는 정수 좌표 k 에서 exp(−k² / 2σ²) 를 샘플링한 뒤 정규화합니다. 이 이산 가우시안 커널의 DTFT (이산 시간 푸리에 변환) 는 가우시안에 근사할 뿐 정확히 가우시안 형태를 갖지는 않습니다. 샘플링 간격과 σ 값이 작을수록 근사 오차가 커집니다. 실용 범위 (σ ≥ 0.5 sample) 에서는 무시할 수 있는 수준이며, DSP 교재에서도 일반적으로 이 근사를 자기 유사성과 동치로 기술합니다.
부엽이 높아 Gibbs 현상 (ringing) 유발. 급격한 전이 (step) 에서 링잉 (ringing) 왜곡 현상 발생.
부엽 없음. 부드러운 전이. σ 가 클수록 더 강한 저역 통과. 이산 구현에서도 이상적인 LPF 에 가장 근접.
sigmaFactor (σF) 는 σ = W / σF 로 정의됩니다. 동일한 r 에서 σF 에 따라 커널 형태가 크게 달라집니다.
| σF | σ (r = 5) | 중앙 가중치 | 가장자리 가중치 | 특성 |
|---|---|---|---|---|
| 3 (넓음) | 3.67 | ~ 0.13 | ~ 0.05 | 거의 균일 → Rectangular 에 수렴 |
| 6 (기본) | 1.83 | ~ 0.22 | ~ 0.005 | 표준 Gaussian 스무딩 - 균형적 감쇠 |
| 12 (좁음) | 0.92 | ~ 0.44 | ~ 10⁻⁷ | 중앙 극도 집중 → 원본에 가까움 |
// SmoothingConductor.cs - Gaussian Convolution double sigma = windowSize / sigmaFactor; double[] gCoeffs = ComputeGaussianCoefficients(windowSize, sigma); // ↑ 이미 정규화됨 (합 = 1) // 내부 루프 : 가중 합산 double sum = 0; for (int k = -r; k <= r; k++) sum += gCoeffs[k + r] * Sample(i + k); // α 블렌딩 적용 result[i] = alpha * sum + (1 - alpha) * input[i]; // Adaptive 모드 : 대칭 축소 + 원본 σ 로 커널을 위치 i 에 정렬 if (boundary == Adaptive) { int symRG = Math.Min(r, Math.Min(i, n - 1 - i)); double twoSigSq = 2.0 * sigma * sigma; // offset = pos - symRG (i 로부터의 부호 거리) localGauss[pos] = Math.Exp(-(offset * offset) / twoSigSq); }
σ 계수 를 조절하여 커널 폭이 결과에 미치는 영향을 확인하세요.
윈도우 내 데이터에 m 차 다항식을 최소제곱법으로 피팅하고, 피팅된 다항식의 중앙값을 출력합니다. 피크 높이 · 도함수 구조 · 신호 형태를 보존하는 유일한 필터입니다.
각 행은 윈도우 내 위치, 각 열은 다항식 차수에 해당합니다. 예를 들어 r = 2, m = 2 이면:
QR 분해로 유사역행렬 (pseudo-inverse) 의 0 번째 행을 추출합니다. 해당하는 행이 컨볼루션 계수 h 입니다.
h_k / Σh_j 정규화는 수학적 필수 절차가 아니라 QR 분해 과정의 부동소수점 누적 오차를 방어하기 위한 수치 안정성 코드입니다. 코드에서는 if (Math.Abs(sum) < 1e-14) return h; 조건 없이 항상 정규화를 수행하여 미세 오차를 보정합니다.
SG 계수에는 음수가 나타납니다. 이는 수학적 필연이며, 엣지 보존의 핵심 메커니즘입니다.
양 끝의 음수 계수는 신호의 2 차 도함수 (곡률) 정보를 포함합니다. 이 구조가 피크 높이를 보존하면서도 노이즈를 제거할 수 있게 합니다. 다른 모든 Smoothing Filter (Rectangular, Binomial, Gaussian) 는 양수 계수만 가지므로 피크를 반드시 감쇠시킵니다.
SG 필터는 선형 FIR 필터이므로 정확한 이산 주파수 응답을 가집니다. 컨볼루션 계수 h_k 로부터 직접 구할 수 있습니다.
SG 계수 h_k 는 대칭 (h_{−k} = h_k) 이므로 위상 왜곡이 없는 영위상 (zero-phase) 필터입니다. 이를 실수 형태로 변환하면:
다항식 차수 m 이 높을수록 통과 대역이 넓고 평탄해집니다. m = 0 일 때 Rectangular 과 동일한 응답이며, m ↑ 에 따라 피크 · 추세 보존 능력이 향상됩니다.
양 끝의 음수 계수가 통과 대역 내 응답을 1.0 에 가깝게 유지합니다. 다른 선형 필터 (Rectangular, Binomial, Gaussian) 는 양수 계수만 가지므로 통과 대역 내에서도 감쇠가 발생합니다.
| polyOrder (m) | 피팅 다항식 | 보존 특성 | 스무딩 강도 |
|---|---|---|---|
| 0 | 상수 (y = a₀) | 평균값만 | 최대 - Rectangular 과 동일 |
| 1 | 직선 (y = a₀ + a₁x) | 추세 (기울기) | 강함 |
| 2 (기본) | 포물선 (y = a₀ + a₁x + a₂x²) | 피크 높이 + 곡률 | 보통 - 가장 범용적 |
| 3 | 3 차 다항식 | 변곡점 | 약함 |
| 4+ | 고차 다항식 | 세밀한 구조 | 매우 약함 - 과적합 위험 |
경계에서는 비대칭 윈도우에 맞는 새로운 설계 행렬 A'를 구성하고 QR 분해를 다시 수행합니다. 경계에서도 다항식 피팅의 정확성이 보장됩니다.
// Adaptive SG - 비대칭 계수 생성 var sides = GetAdaptiveSides(i, r, n); var coeffs = ComputeSGCoefficientsAsymmetric(sides.left, sides.right, polyOrder); // ↑ 매번 QR 분해 → O(W · m²) - 가장 연산 부담이 큰 경계 처리 double sum = 0; for (int k = -sides.left; k <= sides.right; k++) sum += coeffs[k + sides.left] * input[i + k]; result[i] = sum; // α 블렌딩 미적용 - 다항 피팅 특성 보존 우선
다항식 차수 (Polynomial Order) 를 변경하여 스무딩 강도와 피크 보존의 상충 관계를 확인하세요.
(left, right, effectivePolyOrder) 3-튜플을 키로 _sgAsymCoeffCache Dictionary 에 저장됩니다. 동일한 (left, right, polyOrder) 조합이 반복되면 QR 분해를 생략하고 캐시를 반환하여 경계 처리 비용을 크게 절감합니다.커널이 데이터 경계를 넘어설 때 존재하지 않는 샘플을 어떻게 처리하는지 결정합니다. 4 가지 모드가 모든 6 가지 필터에 공통 적용됩니다.
경계를 거울처럼 반사하여 연속성을 유지합니다. 1 차 도함수가 자연스럽게 이어져 가장 부드러운 경계 효과를 냅니다.
양 끝 값을 그대로 반복하여 경계를 채웁니다. 경계 평탄화 효과가 발생하며 경계 값이 과다 반영됩니다.
범위 밖을 모두 0으로 처리합니다. 분모 (윈도우 크기) 는 그대로 유지되어 경계 근처에서 에너지 감쇠 (값 저하) 가 발생합니다.
합성 샘플을 전혀 생성하지 않습니다. 비 SG 필터는 대칭 축소 (Symmetric Shrinking) 로 left == right 를 보장하여 영위상 (zero-phase) 을 유지하고, SG 필터는 GetAdaptiveSides 로 윈도우 크기 W 를 보존하는 비대칭 축소를 적용합니다.
// GetValueWithBoundary() - Symmetric / Replicate / ZeroPad 경계 처리 // Symmetric: 경계에서 반사 if (idx < 0) idx = -idx - 1; // -1 → 0, -2 → 1 if (idx >= n) idx = 2 * n - idx - 1; // n → n - 1, n + 1 → n - 2 // Replicate: 경계값 복제 if (idx < 0) idx = 0; if (idx >= n) idx = n - 1; // ZeroPad: 경계 밖 = 0 if (idx < 0 || idx >= n) return 0.0; // GetAdaptiveSides() - SG 전용 윈도우 크기 보존 보정 // (Rect, Binomial, Gaussian 은 자체 인라인 Math.Min 축소 사용) var (left, right) = GetAdaptiveSides(i, r, n); // left = min(r, i) // right = W - 1 - left (maxRight 조정 적용)
왼쪽으로 가용한 샘플 수 계산. 인덱스 i 가 r 보다 작으면 왼쪽이 축소됩니다.
균형 조정 : 왼쪽이 줄어든 만큼 오른쪽이 늘어나 총 윈도우 크기 W 를 유지합니다.
right > (n − 1 − i) 이면 extra = right − maxRight를 계산하고, right = maxRight, left = min(i, left + extra)로 초과분을 왼쪽으로 재분배합니다. 조정으로 W 가 가능한 한 유지됩니다.
left = min(left, i), right = min(right, n − 1 − i)로 최종 경계 제한을 가합니다.
GetAdaptiveSides()를 사용하여 윈도우 크기 W 를 보존 (균형 조정) 합니다. 다항식 피팅에 최소 W 개의 데이터 포인트가 필요하기 때문입니다.Math.Min(r, i) / Math.Min(r, n − 1 − i)로 양쪽을 독립 축소하고 균일 평균을 계산합니다.binom[(pos − left) + r] 로 추출하여 커널 피크를 위치 i 에 정렬합니다.offset = pos − left (i 로부터의 거리) 기반 exp() 계산으로 커널 피크를 위치 i 에 정렬합니다.
반경을 늘려 경계 처리의 영향이 커지는 것을 확인하세요.
스무딩 필터의 윈도우가 데이터 끝을 넘어갈 때, 각 경계 모드가 빈 자리를 어떻게 채우는지 직접 확인해 보세요. 중심 인덱스 (i) 와 반경 (r) 을 조절하면 실시간으로 결과가 바뀝니다. 색상 셀 = 모드가 채운 가상 값.
커널이 데이터 경계를 침범할 때 "합성 샘플 없이" 처리하는 방법은 두 가지입니다. 하나는 범위 밖 샘플을 건너뛰고 남은 가중치를 재정규화 (Skip-and-Renormalize) 하는 것이고, 다른 하나는 윈도우를 대칭으로 축소 (Symmetric Shrinking) 하여 항상 left == right 를 유지하는 것입니다. 두 가지 방식은 수학적으로 근본적인 차이 : 위상 편이 (Phase Shift) 를 만들어냅니다.
데이터 [1, 2, 3, 4, 5], 반경 r = 2, 중심 i = 1 인 경우를 비교합니다. 윈도우 [−1, 0, 1, 2, 3] 에서 인덱스 −1 은 범위 밖입니다.
범위 밖 샘플을 건너뛰고 (skip), 남은 가중치를 합이 1 이 되도록 재정규화합니다.
left == right 가 되도록 양쪽을 대칭 축소합니다. 합성 샘플이 아닌 실제 데이터만 사용합니다.
위상 편이는 필터 출력이 원본 신호 대비 시간 축 (인덱스 방향) 으로 밀리는 현상입니다. 이 개념을 직관적으로 이해해 봅시다.
가중 평균 필터는 본질적으로 "가중 무게 중심"을 구하는 연산입니다. 시소 (seesaw) 위에 각 위치 k 에 가중치 wk 만큼의 추를 올려놓는다고 상상해 보세요.
• 대칭 가중치 : 양쪽에 동일한 무게 → 시소가 정확히 중앙 (i = 0) 에서 균형 → 영위상
• 비대칭 가중치 : 한쪽이 무거움 → 시소가 무거운 쪽으로 기울어짐 → 위상 편이
여기서 k 는 중심 (i) 으로부터의 오프셋 (부호 거리) 이고, wk 는 해당 위치의 가중치입니다.
가중치가 좌우 대칭이면 양의 k 와 음의 k 가 상쇄되어 μ = 0. 필터 출력이 원래 시간 위치에 정확히 대응합니다.
비대칭 가중치 → 한쪽 방향으로 "끌림" → 출력 값이 원본 신호의 다른 시점에 해당 → 시간 정렬 왜곡.
핵심 : 대칭 가중치에서는 양의 모멘트 (+k · wk) 와 음의 모멘트 (−k · w−k) 가 정확히 상쇄됩니다. left == right 이면 μ = 0 이 수학적으로 보장됩니다.
구체적인 수치 예시로 위상 편이가 발생하는 메커니즘을 단계적으로 추적합니다.
데이터 = [1, 2, 3, 4, 5], r = 2, 중심 i = 1, Gaussian (σF = 6)
원본 전폭 가중치 (오프셋 −2 ~ +2) : w = [0.054, 0.244, 0.403, 0.244, 0.054]
윈도우 [−1, 0, 1, 2, 3] 중 인덱스 −1 은 존재하지 않으므로 해당 가중치 0.054 를 제거합니다.
남은 가중치 [0.244, 0.403, 0.244, 0.054] → 합 = 0.946
재정규화 : [0.258, 0.426, 0.258, 0.057] (합 = 1.0)
오프셋별 가중치 : k = −1 → 0.258, k = 0 → 0.426, k = +1 → 0.258, k = +2 → 0.057
μ = (−1 × 0.258 + 0 × 0.426 + 1 × 0.258 + 2 × 0.057) / 1.0 = +0.114
위치 i = 1 에 기록되는 값이 실제로는 i = 1.114 시점의 신호에 해당합니다. 이 편이가 데이터 전체에서 왼쪽 경계 → 내부로 갈수록 줄어들어 불균일한 시간 왜곡을 유발합니다.
경계에서 왼쪽 L 개의 가중치가 잘려 나갈 때, 위상 편이 μ 를 일반적으로 도출합니다.
원본 가중치가 대칭 (w−k = wk) 이었다면, 왼쪽 L 개를 제거하면 음의 오프셋 기여분이 사라져 분자가 양수가 됩니다. 따라서 μskip > 0 (오른쪽 방향 편이).
$$\mu_{\text{shrink}} = \frac{\displaystyle\sum_{k=-\text{symR}}^{+\text{symR}} k \cdot w_k}{\displaystyle\sum_{k=-\text{symR}}^{+\text{symR}} w_k} = 0 \qquad \text{(left == right} \to \text{always symmetric)}$$| 항목 | Skip-and-Renormalize | Symmetric Shrinking (SonataSmooth) |
|---|---|---|
| 원리 | 범위 밖 가중치 제거 + 남은 것 재정규화 | symR = min(r, min(i, n − 1 − i)) 로 양쪽 동일 축소 |
| 윈도우 크기 | 원본 크기 유지 (OOB 제외 시 실효 크기 감소) | 2·symR + 1 로 축소 |
| 가중치 대칭성 | 비대칭 (한쪽 가중치 제거) | 항상 대칭 (left == right) |
| 유효 중심 μ | μ ≠ 0 (경계에서) | μ = 0 (항상) |
| 위상 편이 | ⚠ 발생 - 경계 근처에서 위치 왜곡 | ✓ 없음 - 영위상 보장 |
| 스무딩 강도 | 경계에서도 넓은 윈도우 사용 → 강한 스무딩 | 경계에서 윈도우 축소 → 스무딩 약화 |
| 데이터 활용 | 범위 내 모든 샘플 사용 | 대칭 범위 내 샘플만 사용 (일부 실제 샘플 미사용) |
| 구현 복잡도 | 비교적 단순 (가중치 합만 재계산) | 약간 복잡 (symR 계산 + 가중치 재추출) |
| 적합 용도 | 위상 무관한 에너지 분석 | 시간 정밀도 필요한 모든 신호 처리 |
SonataSmooth 는 왜 Skip-and-Renormalize 대신 Symmetric Shrinking 을 선택했는지, 필터별 적용 전략을 정리합니다.
// 대칭 축소 - left == right 보장 int symR = Math.Min(r, Math.Min(i, n - 1 - i)); // 윈도우 = [i − symR, i + symR] // → 항상 대칭 → 영위상 보장
커널 피크를 항상 위치 i 에 정렬합니다. Binomial 은 binom[(pos − symR) + r] 로 원본 커널에서 추출, Gaussian 은 원본 σ 로 offset = pos − symR 기반 exp() 재계산.
// GetAdaptiveSides - W 보존 비대칭 var (left, right) = GetAdaptiveSides(i, r, n); // left ≠ right 가능 (W 보존 우선) // → 비대칭 QR 분해로 위상 보정
SG 는 다항식 피팅에 충분한 포인트 (≥ polyOrder + 1) 가 필요하므로 W 를 보존합니다. 비대칭 설계 행렬로 QR 분해를 다시 수행하여 x = 0 에서의 다항식 평가로 위상 편이를 최소화합니다.
위상 편이를 주파수 영역에서 해석하면 그 영향을 더 명확하게 이해할 수 있습니다.
대칭 계수 (h−k = hk) 를 가진 필터에서는:
비대칭 계수의 경우:
동일한 신호에 대해 두 가지 경계 처리 방식의 차이를 실시간으로 비교합니다. 반경을 키우면 경계 영향이 증가하여 Skip-and-Renormalize 의 위상 편이가 뚜렷해집니다.
각 데이터 인덱스에서 Skip-and-Renormalize 방식의 유효 커널 중심 μ 를 계산합니다. 내부 인덱스에서는 μ = 0 이지만, 경계에 가까울수록 μ 값이 커지는 것을 확인하세요.
ApplySmoothing 을 포함한 모든 공개 필터 진입점은 실제 필터링 루프 이전에 입력 배열을 1회 전체 순회하여 비정상 부동소수점 값을 0.0 으로 대체한 안전 복사본 (safeInput) 을 생성합니다. 원본 배열은 수정되지 않습니다.
// SmoothingConductor.cs - 공통 NaN / Infinity 전처리 (line 146–151) double[] safeInput = new double[n]; for (int i = 0; i < n; i++) { double v = input[i]; safeInput[i] = (double.IsNaN(v) || double.IsInfinity(v)) ? 0.0 : v; // NaN 또는 ±Inf → 0.0 대체 / 정상값 → 그대로 복사 }
double.NaN - 부정 연산 결과 (0 / 0, √−1 등)double.PositiveInfinity - 오버플로 (1 / 0)double.NegativeInfinity - 음수 오버플로 (−1 / 0)
0.0 대체는 ZeroPad 경계 모드와 동일한 의미로 작동합니다. 필터 특성 (평균 · 중앙값 · SG 모두) 이 NaN 전파 없이 안전하게 동작하며, 실사용 데이터 (센서 이상치, 결측값 등) 에서 예외를 방지합니다.
applySmoothing 도 동일하게 isNaN(v) || !isFinite(v) 검사로 0 으로 대체한 safe[] 배열을 사용합니다. C# 과 JS 양측의 동작이 일치합니다.
SmoothingConductor.ApplySmoothing 과 동일한 JavaScript 구현으로 필터링 결과를 확인합니다.
데이터 길이: 0 개
SonataSmooth 핵심 애플리케이션 코드, .NET Standard 2.0 기반 스무딩 라이브러리 NuGet 패키지, 그리고 라이브러리 기능을 직접 실험해볼 수 있는 실습용 Etude 애플리케이션을 아래 링크에서 확인하실 수 있습니다.
SonataSmooth 의 핵심 소스 코드 저장소입니다. C# .NET Windows Forms 기반으로 제작된 수치 데이터 노이즈 제거 및 평활화 애플리케이션으로, 수동 입력, 클립보드 붙여넣기, 드래그 앤 드롭 등 다양한 입력 방식과 강력한 유효성 검사를 지원합니다.
SonataSmooth은 "Sonata"와 "Smooth"의 합성어입니다. 소나타 (Sonata) 는 서로 다른 악장 (악장 = 알고리즘) 이 하나의 조화로운 전체로 어우러지는 음악 형식으로, 여러 가지 스무딩 알고리즘이 협주 (concert) 하여 함께 작동한다는 철학을 담고 있습니다.
대부분의 구성 요소에는 MIT 라이선스 적용. 단, 파스칼의 삼각형 계수 기반 Binomial Weighted Median Smoothing Filter 는 특허 출원 중 (patent-pending) 으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.
.NET Standard 2.0 을 기반으로 하는 고성능 1D 수치 신호 평활화 & 내보내기 툴킷 NuGet 패키지입니다. Rectangular (Moving Average), Binomial (Pascal), Weighted Median (Binomial Weights), Gaussian Weighted Median (GWMF), Gaussian, Savitzky-Golay 스무딩을 경계 처리 옵션과 병렬화 설정과 함께 제공하며, CSV 및 Excel (COM) 내보내기 Helper 로 여러 스무딩 결과를 나란히 비교 · 차트화할 수 있습니다.
대부분의 구성 요소에는 MIT 라이선스 적용. 단, 파스칼의 삼각형 계수 기반 Binomial Weighted Median Smoothing Filter 는 특허 출원 중 (patent-pending) 으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.
using SonataSmooth.Tune; double[] data = LoadYourData(); var (rect, binom, median, gaussMed, gauss, sg) = SmoothingConductor.ApplySmoothing( data, r: 5, polyOrder: 2, boundaryMode: BoundaryMode.Symmetric, doRect: true, doAvg: true, doMed: false, doGaussMed: false, doGauss: true, doSG: true, alpha: 1.0, sigmaFactor: 6.0);
SonataSmooth.Tune 라이브러리의 기능을 직접 체험하고 학습할 수 있는 실습용 샘플 애플리케이션입니다. 음악에서 에튀드 (Étude) 가 최종 작품을 위한 준비 연습곡이듯, 이 저장소는 본격적인 데이터 처리 애플리케이션을 구현하기 전에 SonataSmooth.Tune 의 다양한 스무딩 알고리즘을 실험하고 이해하기 위한 스케치이자 학습 공간입니다.
SonataSmooth.Tune은 데이터를 악기 조율하듯 정밀하게 다듬는 C# / .NET 스무딩 라이브러리이며, SonataSmooth.Tune.Etude는 그 라이브러리를 위한 연습곡 (Étude) - 완성된 작품에 앞서 사용법을 탐구하고 숙달하는 실습 샘플입니다.
대부분의 구성 요소에는 MIT 라이선스 적용. 단, 파스칼의 삼각형 계수 기반 Binomial Weighted Median Smoothing Filter 는 특허 출원 중 (patent-pending) 으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.