SonataSmooth.Tune · SmoothingConductor.cs · 1D 필터 완전 해설

1D Signal Smoothing
Filters · 완전 해설

Rectangular부터 Savitzky-Golay까지 6가지 1D 스무딩 필터의 수학적 원리, α 블렌딩, 경계 처리, 그리고 인터랙티브 시뮬레이터를 코드·다이어그램과 함께 완전 정리합니다.

Overview · Architecture

SmoothingConductor 전체 구조

SonataSmooth.Tune은 1차원 수치 시퀀스에 대해 6가지 스무딩 필터를 단일 순회(single traversal)로 병렬 적용할 수 있는 .NET Standard 2.0 라이브러리입니다.

6가지 필터 선택 구조

Filter 1
Rectangular
Filter 2
Binomial Avg
Filter 3
Binom. Median
Filter 4
Gauss. Median
Filter 5
Gaussian
Filter 6
Savitzky-Golay

🏗️ 전체 처리 흐름

ENTRY POINT
SmoothingConductor.ApplySmoothing()
double[] input · int r · BoundaryMode · filter flags · alpha · sigmaFactor
1
입력 방어 — NaN / ∞ → 0.0 (safeInput)

입력 배열의 비정상 값을 0.0으로 치환하여 모든 필터의 안정성을 보장합니다.

2
커널 계수 사전 계산

Binomial: CalcBinomialCoefficients(W) · Gaussian: ComputeGaussianCoefficients(W, σ) · SG: HouseholderQR

3
병렬화 결정 — N ≥ 2,000 → Parallel.For

데이터 길이가 2,000 이상이면 행 단위 자동 병렬 처리를 활성화합니다.

4
각 인덱스 i에 대해 6개 필터 동시 실행

단일 순회에서 활성화된 모든 필터의 결과를 동시에 계산합니다.

5
α 블렌딩 적용 (해당 필터만)

y[i] = α·filtered + (1−α)·original — Rect, SG 제외한 필터에 적용됩니다.

(Rect[], Binom[], Median[], GaussMed[], Gauss[], SG[])
6개 결과 배열 동시 반환
공유 인프라 CalcBinomialCoefficients ComputeGaussianCoefficients HouseholderQR BoundaryMode 4종 Parallel.For (N≥2000)

🎯 활용 분야

SonataSmooth는 1차원 데이터 스무딩 및 노이즈 제거에 특화되어 있습니다. 단일 차원 데이터셋에 한정되지만, 순차적 수치 신호의 전처리 또는 정제가 필요한 다양한 분야에 폭넓게 적용할 수 있습니다.

🤖 머신러닝 · 딥러닝 전처리
  • 스파이크, 지터, 불규칙 노이즈를 제거하여 원시 학습 데이터를 정제
  • 센서 측정값, 금융 신호 등 시계열 입력을 안정화하여 모델 정확도 향상
📡 IoT · 센서 데이터 처리
  • 온도, 습도, 진동 등 노이즈가 섞인 센서 출력을 평활화하여 안정적인 모니터링 구현
  • 무작위 변동에 의한 오탐(False Positive)을 줄여 이상 탐지 정확도 강화
💹 금융 · 경제 시계열
  • 주가, 환율, 거래량 등에서 단기 변동성을 필터링하여 추세 파악
  • 예측 모델을 위한 안정적인 데이터셋 준비
🔬 과학 · 실험 계측
  • 분광법, 환경 모니터링 등 실험실 · 현장 데이터에서 의미 있는 추세를 부각
  • 기저 패턴을 왜곡하지 않으면서 측정 노이즈를 저감
🎵 신호 처리 (1D 전용)
  • 오디오 파형 진폭 등 선형 신호를 평활화
  • 배경 노이즈를 줄이면서 핵심 특성을 보존
📊 데이터 시각화 · 리포팅
  • 산만한 노이즈를 제거하여 깔끔한 차트 · 플롯 생성
  • 이해관계자에게 보다 직관적인 데이터셋 제공

📊 6가지 필터 특성 비교

필터유형복잡도/점α 블렌딩강점
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
간헐적 랜덤 노이즈적정양호우수★ 탁월양호우수
빈번한 랜덤 노이즈미흡적정★ 탁월적정적정적정
완만한 대형 추세 변화미흡양호양호양호양호★ 탁월
간헐적 급격한 스파이크미흡적정★ 탁월우수적정적정
빈번한 / 연속 급격한 스파이크미흡적정적정★ 탁월적정적정
규칙적인 대진폭 파형미흡적정적정양호적정★ 탁월
계단 변화 (갑작스런 레벨 전환)미흡적정★ 탁월우수적정적정
복합 주파수 진동미흡양호적정양호양호★ 탁월
주기적 고주파 노이즈 (일정 톤)★ 탁월적정적정양호양호양호
느린 기저선 표류 + 미세 지터양호양호★ 탁월우수양호우수
부드러운 곡선 + 완만한 노이즈의 자연 신호적정양호양호★ 탁월★ 탁월우수
안정된 주기 신호 + 중간 강도 고주파 노이즈적정★ 탁월적정양호양호양호
★ 탁월 = 최적 선택 우수 = 매우 좋음 양호 = 좋음 적정 = 보통 미흡 = 부족

🏆 필터별 종합 평가

Rectangular

단순하지만 일정한 고주파 노이즈 억제에 효과적입니다. 계산 비용이 가장 낮아 빠른 처리가 필요한 상황에 적합합니다.

Binomial Avg

균형 잡힌 중간 지대. 특히 중간 강도 노이즈가 포함된 주기 신호에서 강점을 발휘합니다.

Binom. Median

다양한 데이터셋과 지표에서 가장 높은 종합 성능을 보여주는 필터. 간헐적 · 빈번한 스파이크, 빈번한 노이즈, 계단 변화 처리에 탁월하여 종합 최강자에 해당하지만, 연속 스파이크에서는 일관성이 다소 낮습니다.

Gauss. Median

가우시안의 부드러움과 중앙값의 강건함을 결합한 하이브리드 필터. 간헐적 스파이크와 부드러운 곡선 보존에 뛰어나며, 범용성이 높은 대안입니다.

Gaussian

부드러운 곡선과 자연 신호 흐름을 잘 재현하지만, 급격한 변화나 극단적 이상치에는 취약합니다.

Savitzky-Golay

파형, 추세, 복합 주파수 보존에 탁월. 과학 데이터 및 부드러운 곡선 분석에 이상적입니다.

종합 결론 : Binomial Median 필터링이 다양한 신호 유형과 평가 지표 전반에 걸쳐 가장 높은 종합 성능을 보여줍니다. Gaussian Median (GWMF)은 특히 간헐적 스파이크와 노이즈가 섞인 부드러운 곡선 시나리오에서 강력한 범용 대안이며, 나머지 필터들은 각자의 특정 상황에서 고유한 강점을 유지합니다.

⚙️ 공통 매개변수

매개변수타입범위설명
r (radius)int≥ 0커널 반경. 윈도우 크기 W = 2r + 1
polyOrderint0 ≤ p < WSG 다항식 차수
boundaryModeenum4종Symmetric · Replicate · ZeroPad · Adaptive
alphadouble[0, 1]블렌딩 계수. Rect, SG 제외 필터에 적용
sigmaFactordouble?> 0σ = W / sigmaFactor. 기본 6.0

🎹 Quick Preview

노이즈가 포함된 신호에 필터를 동시 적용한 결과를 미리 확인합니다.

5
Filter 1 / 6

Rectangular (Box / Uniform) Moving Average

가장 단순한 선형 평활화 필터. 윈도우 내 모든 샘플에 동일한 가중치를 부여하여 산술 평균을 계산합니다.

📐 수학적 정의

Rectangular Filter Output
$$y[i] = \frac{1}{W}\sum_{k=-r}^{r} x[i+k], \qquad W = 2r + 1$$

가중치 벡터:

$$\mathbf{w} = \left[\underbrace{\tfrac{1}{W},\;\tfrac{1}{W},\;\ldots,\;\tfrac{1}{W}}_{W\text{ 개}}\right]$$

🌊 주파수 영역 특성

$$H(\omega) = \frac{1}{W}\cdot\frac{\sin(\omega W/2)}{\sin(\omega/2)}$$

부엽(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;
α 블렌딩: 적용되지 않습니다. 정규 커널 동작 보존을 위한 설계 결정입니다.

🔬 Rectangular 시뮬레이터

5

⚡ 최적화 포인트

  • 역수 사전 계산: invRectDiv = 1.0 / windowSize로 나눗셈을 곱셈으로 대체
  • 병렬 처리: N ≥ 2,000 → Parallel.For 자동 활성화
  • Adaptive 모드: 경계에서 실제 존재하는 샘플만 사용
Filter 2 / 6

Binomial (Pascal) Weighted Average

파스칼 삼각형의 행(이항 계수)을 가중치로 사용하는 가중 이동 평균입니다.

📐 이항 계수 생성

Binomial Coefficient Recurrence
$$c_0 = 1, \qquad c_k = c_{k-1} \cdot \frac{W - k}{k}, \quad k = 1, 2, \ldots, W-1$$

📊 가중 평균 & α 블렌딩

Binomial Weighted Average
$$y_{\text{filtered}}[i] = \frac{\displaystyle\sum_{k=-r}^{r} c_{k+r}\cdot x[i+k]}{\displaystyle\sum_{k=-r}^{r} c_{k+r}}$$
Alpha Blending
$$y[i] = \alpha \cdot y_{\text{filtered}}[i] + (1-\alpha) \cdot x[i]$$

가중치 분포 (r=5)

정규화된 가중치

🔗 이항 필터 → 가우시안 수렴

$$\frac{\binom{n}{k}}{2^n} \;\xrightarrow{n \to \infty}\; \frac{1}{\sqrt{2\pi \sigma^2}}\exp\!\left(-\frac{(k-n/2)^2}{2\sigma^2}\right), \quad \sigma^2 = \frac{n}{4}$$

🔬 Binomial Average 시뮬레이터

5
1.00

⚡ 최적화 포인트

  • 곱셈 점화식: c_k = c_{k-1} · (W-k)/k — O(W)
  • 합계 사전 계산: binomSum 루프 전 1회 계산
  • Adaptive 모드: 축소 윈도우에 맞는 새 이항 계수 로컬 계산
Filter 3 / 6

Binomial Weighted Median - 이항 가중 중앙값

이항 계수를 가중치로 사용하여 가중 중앙값을 구합니다. 평균(Average)과 달리 극단값(이상치, spike)에 강건하고 신호의 엣지·피크 구조를 보존하는 비선형 필터입니다. Binomial Average와 동일한 가중치를 사용하되 출력 방법만 다릅니다.

📐 수학적 정의 — 가중 중앙값

Weighted Median Definition
$$\text{WMed} = x_{(j^*)} \quad\text{where}\quad j^* = \min\left\{j : \sum_{l=0}^{j} w_{(l)} > \frac{T}{2}\right\}, \qquad T = \sum_{k} w_k$$

가중치 벡터는 Binomial Average와 동일합니다:

1D Binomial Weights
$$w_k = C(W{-}1,\, k) = \frac{(W{-}1)!}{k!\,(W{-}1{-}k)!}, \quad k = 0, 1, \ldots, W{-}1$$

일반 중앙값(unweighted median)은 모든 샘플에 동등한 가중치를 부여합니다. 가중 중앙값은 중앙에 가까운 샘플에 높은 투표권을 부여하여, 원본 신호(중앙 근처)의 영향력을 극단값보다 우선합니다.

🔑 Average vs Median — 핵심 차이

Binomial Average와 Binomial Weighted Median은 동일한 가중치를 사용하되, 출력 계산 방식만 다릅니다. 이 한 가지 차이가 이상치(noise spike) 처리 능력을 근본적으로 바꿉니다.

Binomial Average (가중 합산)
$$y[i] = \frac{\sum w_k \cdot x_{i+k}}{\sum w_k}$$

예 : [100, 102, 99, 240, 101], w=[1,4,6,4,1]
= (100+408+594+960+101) / 16 = 135.2 ← 이상치에 끌림

Binomial Weighted Median (가중 투표)
$$\text{Find } m : \sum_{x \leq m} w > T/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 ← 이상치 무시

🔄 알고리즘 단계 — 상세 흐름

1
윈도우 내 (값, 가중치) 쌍 수집

인덱스 i를 중심으로 반경 r의 윈도우 [i−r, i+r]에서 W = 2r+1개의 샘플과 이항 가중치를 수집합니다. BoundaryMode에 따라 경계 밖 샘플 처리가 달라집니다.

2
값 기준 오름차순 정렬 — O(W log W)

(값, 가중치) 쌍을 값 기준으로 정렬합니다. 정렬 후 가중치 누적이 의미를 갖습니다. 1D에서는 배열이 작으므로(W ≤ 51) Array.Sort의 IntroSort가 효율적입니다.

3
가중치 누적합 탐색 — accum > T/2

정렬된 순서대로 가중치를 누적하며 전체 합(T)의 절반을 초과(strictly greater)하는 첫 위치를 찾습니다. 이 값이 가중 중앙값입니다. 이항 계수는 정수값이므로 부동소수점 오차가 없습니다.

4
짝수 TieBreak — accum == T/2이면 두 값 평균

누적합이 정확히 T/2와 같으면(짝수 가중치 합), 현재 값과 다음 값의 산술 평균을 반환합니다. 이항 계수의 합 = 2^(W−1)이므로, W가 홀수(일반적)이면 합이 2의 거듭제곱 → 짝수 → TieBreak 가능성 있음.

5
α 블렌딩 적용

y[i] = α · WMed + (1−α) · x[i] — α=1이면 완전 필터, α=0이면 원본 유지. 0 < α < 1에서 원본과 필터 결과의 혼합.

💻 구현 매핑 — SmoothingConductor.cs

// 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];

⚖️ TieBreak 메커니즘 — 정수 이항 가중치의 특성

이항 계수의 합 T = 2^(W−1)은 항상 짝수(W ≥ 2)입니다. 따라서 가중 누적합이 정확히 T/2에 도달할 수 있으며, 이 경우 두 인접 값의 평균을 반환합니다.

rW이항 계수합 TT/2TieBreak 가능
13[1, 2, 1]42✓ 예: accum = 1+1 = 2 = T/2
25[1, 4, 6, 4, 1]168✓ 예: accum = 1+4+... = 8
37[1, 6, 15, 20, 15, 6, 1]6432
Gaussian Median과의 차이: Gaussian 가중치는 실수(exp 값)이므로 정확한 T/2 일치가 사실상 불가능합니다. 따라서 Gaussian Median은 accum >= half(이상)을 사용하고 별도 짝수 처리가 없습니다.

🛡️ 이상치 저항 원리 — 수학적 증명

가중 중앙값이 이상치(spike)에 강건한 이유를 수학적으로 분석합니다.

Breakdown Point
$$\text{BP} = 1 - w_{\max} / T \quad \text{where } w_{\max} = C(W{-}1,\, r) = \text{중앙 가중치}$$

중앙 가중치가 전체의 50% 미만이면, 중앙에 이상치가 있어도 주변 정상 샘플들이 과반을 차지하여 이상치를 "outvote"합니다.

r중앙 가중치중앙 비율Breakdown Point의미
12 / 450.0%50.0%경계 — 중앙 1개만 오염되면 유효
26 / 1637.5%62.5%중앙+인접 2개 오염까지 유효
320 / 6431.3%68.8%높은 이상치 내성
5252 / 102424.6%75.4%매우 높은 이상치 내성
핵심: r이 커질수록 중앙 비율이 감소(Stirling 근사: ≈ 1/√(πr))하므로 Breakdown Point가 상승합니다. 즉 r↑ → 더 많은 이상치를 허용하면서도 필터가 유효합니다.

🔍 Adaptive 경계 처리 — 축소 윈도우 계수 재생성

Adaptive 모드에서는 경계에서 윈도우가 축소되며, 축소된 크기에 맞는 새로운 이항 계수가 생성됩니다.

// Adaptive 분기
int left = Math.Min(r, i);
int right = Math.Min(r, n - 1 - i);
int W_local = left + right + 1;

// 축소된 윈도우용 새 이항 계수
double[] localBinom = CalcBinomialCoefficients(W_local);
// 예: i=0, r=2 → left=0, right=2, W=3 → [1,2,1]
// 원본 r=2: [1,4,6,4,1] 의 부분이 아닌 완전히 새로운 계수!

var vals = new double[W_local];
for (int p = 0; p < W_local; p++)
    vals[p] = input[i - left + p];
filtered = WeightedMedianBinom(vals, localBinom);
Adaptive vs 다른 모드: Symmetric / Replicate는 경계 밖 샘플을 합성(미러 / 복제)하여 원래 크기 윈도우를 유지합니다. Adaptive는 합성 샘플 없이 실제 존재하는 데이터만 사용하므로, 경계에서 인위적인 패턴이 발생하지 않습니다.

🔬 Binomial Weighted Median 시뮬레이터

Spike 옵션을 변경하여 이상치에 대한 필터의 강건성을 확인하세요. α를 조절하여 원본과의 블렌딩 효과를 관찰합니다.

5
1.00

⚡ 최적화 포인트 & 성능

  • 이항 계수 캐싱: CalcBinomialCoefficients(W)는 곱셈 점화식 O(W)로 생성. 동일 W 반복 호출 시 캐싱 가능
  • 정수값 double: 이항 계수는 정수값(1.0, 4.0, 6.0 등)이므로 IEEE 754에서 정확히 표현됨 — 누적 오차 없음
  • Adaptive 모드: 경계마다 축소된 CalcBinomialCoefficients(W_local) 로컬 계산
  • 병렬화: N ≥ 2,000 → Parallel.For. 각 인덱스 i의 정렬이 독립적이므로 완전 병렬 가능
  • 복잡도: O(W log W) per point — 정렬 비용이 지배적. Average의 O(W)보다 느림
Filter 4 / 6

Gaussian Weighted Median - 가우시안 가중 중앙값

Binomial Median과 동일한 가중 중앙값 알고리즘에 가우시안 가중치를 사용합니다. sigmaFactor로 σ를 정밀 조절하여 커널의 감쇠 강도를 제어할 수 있습니다.

📐 가우시안 커널 생성

Gaussian Weight Function
$$g_k = \exp\!\left(-\frac{(k - r)^2}{2\sigma^2}\right), \qquad \sigma = \frac{W}{\text{sigmaFactor}}, \quad W = 2r+1$$
Normalization
$$\hat{g}_k = \frac{g_k}{\sum_{j=0}^{W-1} g_j} \quad \Rightarrow \quad \sum \hat{g}_k = 1$$

정규화 후 합=1이 됩니다. sigmaFactor가 클수록 σ가 작아져 중앙에 집중하고, 작을수록 σ가 커져 넓게 분산됩니다.

💻 구현 매핑 — Binomial Median과의 코드 차이

// 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)가 없습니다.

Binomial Median
if (accum > half)       → 반환
if (even && accum == half) → 평균
Gaussian Median
if (accum >= half)      → 반환
// TieBreak 없음

📐 sigmaFactor 영향 분석

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⁻⁶중앙 거의 단독 → 원본에 가까움
⚠ 주의: r=1(W=3), σF=6일 때 σ=0.5로 매우 작아 중앙 가중치가 ~78.7%에 달합니다. 이 경우 중앙 샘플이 과반을 차지하여 이상치가 중앙에 있으면 그대로 통과됩니다. 소형 커널에서는 σF를 2~3으로 낮추어야 합니다.

🔍 Adaptive 경계 처리 — σ 비례 축소

Adaptive 모드에서는 축소된 윈도우에 맞게 σ도 비례 축소됩니다. Binomial의 Dictionary 캐싱과 달리 매번 exp() 계산이 필요합니다.

// Gaussian Median — Adaptive 분기
int left  = Math.Max(0, i - r);
int right = Math.Min(n - 1, i + r);
int W_local = right - left + 1;

// σ를 축소된 윈도우에 비례하여 재계산
double sigmaLocal = W_local / sigmaFactor;
double[] gLocal = ComputeGaussianCoefficients(W_local, sigmaLocal);
// ↑ 매번 exp() O(W_local) 호출 — Binomial의 캐싱 대비 느림

🔬 Gaussian Weighted Median 시뮬레이터

σ Factor를 조절하여 가우시안 폭이 중앙값 결과에 미치는 영향을 관찰하세요.

5
6.0
1.00

⚡ 최적화 포인트

  • exp() 비용: ComputeGaussianCoefficients는 매번 exp()를 W번 호출 — Binomial의 곱셈 점화식보다 느림
  • 캐싱 제한: σ가 실수이므로 키 공간이 넓어 캐싱 효율이 Binomial보다 낮음
  • Adaptive 오버헤드: 경계마다 다른 (W_local, σ_local) 조합으로 exp() 재계산
  • Binomial 대비 장점: sigmaFactor로 분포 형태를 자유롭게 조절 가능 — 같은 r에서 넓게/좁게
Filter 3 vs Filter 4 · Deep Comparison

Binomial vs Gaussian Weighted Median

두 필터는 동일한 Weighted Median 알고리즘을 공유하되, 가중치 생성 방식이 다릅니다. 이 한 가지 차이가 결과물과 사용 시나리오에서 구체적으로 어떤 차이를 만드는지 깊이 분석합니다.

1. 원리의 차이 — 가중치 분포 형태

동일한 r에서 두 필터의 1D 가중치를 시각적으로 비교합니다.

Binomial — C(W−1, k) / 2^(W−1)
이산 · 정수값 · 파스칼 삼각형 · Dictionary 캐싱 가능
Gaussian — exp(−x² / 2σ²) / Σ
연속 분포 근사 · 실수값 · σ로 폭 조절 · 매번 exp() 계산
수학적 관계: Binomial B(2r, 0.5)는 CLT에 의해 r→∞일 때 N(r, r/2)로 수렴합니다. 따라서 σ = √(r/2) ≈ √(W/4)로 매칭하면 두 분포가 근사적으로 일치합니다. 그러나 유한 r에서는 첨도(kurtosis) 차이가 존재합니다.

2. 구현 차이점 상세

항목Binomial Weighted MedianGaussian Weighted Median
가중치 생성C(W−1,k) 점화식 O(W) — 정수값 doubleexp(−x²/2σ²) O(W) — 실수값 근사
σ 파라미터없음 — r에 의해 분포 자동 결정σ = W / sigmaFactor — σF로 분포 형태 조절
임계값 비교accum > half (strictly greater)accum >= half (greater or equal)
TieBreak (짝수 처리)accum == half → 두 값 평균해당 없음 (실수 가중치, 정확한 일치 불가)
캐싱CalcBinomialCoefficients 재사용 가능ComputeGaussianCoefficients 매번 계산
Adaptive 경계CalcBinomialCoefficients(W_local) 로컬 생성ComputeGaussianCoefficients(W_local, σ_local) 재계산
α 블렌딩
수치 정밀도정수값 double — 누적 오차 없음exp() 근사 — 미세 누적 오차 가능

3. 중앙 가중치 & 노이즈 저항력 분석

Weighted Median이 이상치를 제거하려면 중앙 가중치가 50% 미만이어야 합니다. 50% 이상이면 중앙 샘플 하나가 과반을 차지하여 이상치가 그대로 통과됩니다.

rWBinomial 중앙 %노이즈 제거Gaussian 중앙 % (σF=6)노이즈 제거
1350.0%✓ 경계78.7%✗ 필터 무효화
2537.5%47.9%
3731.3%34.3%
51124.6%21.8%
102117.6%11.4%
핵심 발견: r=1, σF=6에서 Gaussian의 중앙 가중치가 78.7% > 50%로 필터가 무효화됩니다. 중앙에 이상치가 있으면 그대로 통과됩니다. Binomial은 r=1에서 50.0%로 경계이지만 여전히 유효합니다. r=2부터 둘 다 정상 동작하지만, Binomial은 모든 r에서 안전합니다.

4. Binomial Weighted Median의 구조적 우위

σ를 일치시킨 조건에서도 Binomial WM이 미세하게 우위인 수학적 근거가 4가지 있습니다.

① Kurtosis (첨도) 차이

Binomial B(2r, 0.5)의 첨도 κ = 3 − 1/r은 Gaussian의 κ=3보다 항상 작습니다 (Platykurtic). 이는 가중치가 더 고르게 분산됨을 의미하여 유효 샘플 수(n_eff)가 높아지고 추정 분산이 감소합니다.

$$\kappa_{\text{Binom}} = 3 - \frac{1}{r} < 3 = \kappa_{\text{Gauss}} \quad \forall\, r \geq 1$$
② 정수값 double 정밀성

이항 계수는 정수값 double(1.0, 4.0, 6.0 등)로 IEEE 754에서 정확히 표현됩니다. 가중치 누적 연산에서 오차가 없습니다. Gaussian의 exp() 결과는 무리수 근사이므로 미세한 누적 오차가 발생합니다.

③ 유한 지지 (Finite Support)

Binomial 분포의 정의역 = [0, W−1]로 윈도우와 정확히 일치합니다. Gaussian은 이론적으로 무한 꼬리를 가지며 윈도우 경계에서 강제 절단(truncation) 후 재정규화합니다. 이 재정규화는 원래 분포 형태를 미세하게 변형시킵니다.

④ 중앙 노이즈 저항력

σ를 일치시켜도 Platykurtic인 Binomial은 중앙 가중치가 항상 Gaussian보다 낮습니다. 이는 이상치가 중앙에 위치할 때 주변 샘플들이 더 쉽게 "outvote"할 수 있음을 의미합니다.

결론: 4가지 근거 모두 유한 r의 구조적 성질에서 비롯되므로 반례가 없습니다. r → ∞ (CLT 수렴 완료)에서만 차이가 0에 수렴합니다. 실용적 r 범위(1~25)에서는 예외 없이 Binomial WM이 미세하게 우위입니다.

5. 장단점 종합 비교

Binomial Weighted Median
✅ 장점
  • 파라미터 없음: r만 결정하면 됨. 오조작 위험 없음
  • 캐싱 가능: 정수 기반 → 동일 W 재사용 O(1)
  • 정수 산술 정확성: 누적 오차 없음
  • 모든 r에서 안전: 중앙 가중치 ≤ 50%
  • Platykurtic → n_eff 우위: 추정 분산 더 낮음
⚠️ 단점
  • 분포 형태 고정 — 조절 불가
  • 이산 근사 — 연속 미세 조정 불가
Gaussian Weighted Median
✅ 장점
  • σF로 분포 형태 정밀 조절: 넓게/좁게 자유롭게
  • 연속 함수 기반: 수학적으로 잘 정의된 커널
  • σF 조절로 r과 무관한 분포 폭 제어
⚠️ 단점
  • r=1, σF=6에서 필터 무효화 (중앙 78.7%)
  • exp() 매번 계산 — 캐싱 효율 낮음
  • σF 튜닝 필수 — 기본값 위험
  • 부동소수점 누적 오차 가능

6. 선택 가이드 — 언제 어떤 필터를?

상황Binomial Median 추천Gaussian Median 추천
소형 커널 r=1 (기본 σF=6) ✓ 명백히 우위 ✗ 필터 무효화 — σF 재조율 필수
소형 커널 r=2 ✓ 미세 우위 (중앙 37.5%) △ 정상 동작 (중앙 47.9%)
Salt-Pepper 이상치 제거 ✓ 모든 r에서 안정 r≥2부터 정상 동작
배치 처리 (동일 r 반복) ✓ 캐시 재사용 효과 매번 exp() 재계산
신호 특성에 맞는 정밀 튜닝 r만 조절 — 유연성 낮음 ✓ σF로 세밀 조율
파라미터 없이 빠른 적용 ✓ r만 설정, 즉시 안전 σF 조율 필요
결론 Binomial은 파라미터 없이 안전하고 빠른 기본 선택. Gaussian은 σF 튜닝으로 정밀 제어가 필요한 전문가 용도.

🔬 Side-by-Side 비교 시뮬레이터

반경을 변경하며 두 필터의 결과 차이를 직접 확인하세요. 이상치(spike) 포함 신호에서 차이가 뚜렷해집니다.

6
Filter 5 / 6

Gaussian (Convolution) Filter - 가우시안 가중 평균

이산 가우시안 커널과의 컨볼루션을 통한 선형 평활화 필터입니다. 중앙 샘플에 가장 높은 가중치를 부여하며, σ(시그마)로 감쇠 속도를 제어합니다. Rectangular보다 부드러운 주파수 응답을 가집니다.

📐 수학적 정의

Gaussian Kernel
$$g_k = \exp\!\left(-\frac{(k - r)^2}{2\sigma^2}\right), \quad \hat{g}_k = \frac{g_k}{\sum_{j=0}^{W-1} g_j}, \quad \sigma = \frac{W}{\text{sigmaFactor}}$$
Convolution + Alpha Blending
$$y[i] = \alpha \sum_{k=-r}^{r} \hat{g}_{k+r}\cdot x[i+k] + (1-\alpha)\cdot x[i]$$

정규화 후 Σĝ = 1이므로 DC 성분(상수 신호)이 완벽히 보존됩니다. Binomial과 동일한 성질이지만, σ 파라미터로 분포 폭을 자유롭게 조절할 수 있습니다.

🌊 주파수 영역 특성 (자기 유사성)

Fourier Transform of Gaussian
$$\mathcal{F}\{g(t)\} = G(f) = \exp(-2\pi^2 \sigma^2 f^2)$$

가우시안의 푸리에 변환은 다시 가우시안입니다 (자기 유사성). 부엽(side lobe)이 없는 이상적인 저역 통과 필터에 가까우며, Rectangular의 sinc 응답과 대비됩니다.

Rectangular — sinc 응답

부엽이 높아 Gibbs 현상(ringing) 유발. 급격한 전이(step)에서 링잉 아티팩트 발생.

Gaussian — Gaussian 응답

부엽 없음. 부드러운 전이. σ가 클수록 더 강한 저역 통과. 이상적인 LPF에 가장 근접.

📊 sigmaFactor의 영향 분석

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 모드 : 축소 윈도우에 맞게 σ 재계산
if (boundary == Adaptive) {
    double sigmaLocal = W_local / sigmaFactor;
    var gLocal = ComputeGaussianCoefficients(W_local, sigmaLocal);
}
α 블렌딩: 적용됩니다. α=1이면 완전 필터, α=0이면 원본 유지.

🔬 Gaussian 시뮬레이터

σ Factor를 조절하여 커널 폭이 결과에 미치는 영향을 확인하세요.

5
6.0
1.00

⚡ 최적화 포인트

  • 사전 정규화: ComputeGaussianCoefficients에서 합=1로 정규화 → 루프 내 나눗셈 불필요
  • Adaptive σ 비례 축소: σ_local = W_local / σF로 비례 축소하여 분포 형태 유지
  • exp() 비용: 매번 exp()를 W번 호출 — Binomial의 곱셈 점화식보다 느림
  • 병렬화: N ≥ 2,000 → Parallel.For 자동 활성화. 각 인덱스 i가 독립적
Filter 6 / 6

Savitzky-Golay Filter - 다항식 최소제곱 피팅

윈도우 내 데이터에 m차 다항식을 최소제곱법으로 피팅하고, 피팅된 다항식의 중앙값을 출력합니다. 피크 높이·도함수 구조·신호 형태를 보존하는 유일한 필터입니다.

📐 설계 행렬 & QR 분해

Design Matrix (Vandermonde)
$$A_{ij} = i^{\,j}, \quad i = -r, \ldots, +r, \quad j = 0, \ldots, m$$

각 행은 윈도우 내 위치, 각 열은 다항식 차수에 해당합니다. 예를 들어 r=2, m=2이면:

$$A = \begin{pmatrix} (-2)^0 & (-2)^1 & (-2)^2 \\ (-1)^0 & (-1)^1 & (-1)^2 \\ 0^0 & 0^1 & 0^2 \\ 1^0 & 1^1 & 1^2 \\ 2^0 & 2^1 & 2^2 \end{pmatrix} = \begin{pmatrix} 1 & -2 & 4 \\ 1 & -1 & 1 \\ 1 & 0 & 0 \\ 1 & 1 & 1 \\ 1 & 2 & 4 \end{pmatrix}$$
Householder QR Decomposition
$$\mathbf{A} = \mathbf{Q}\mathbf{R} \quad \Rightarrow \quad \mathbf{h} = (\mathbf{A}^\top\mathbf{A})^{-1}\mathbf{A}^\top \mathbf{e}_0 \quad \Rightarrow \quad \hat{h}_k = h_k / \textstyle\sum h_j$$

QR 분해로 유사역행렬(pseudo-inverse)의 0번째 행을 추출합니다. 이 행이 컨볼루션 계수 h입니다. 정규화 후 합=1이 됩니다.

🔑 음수 계수 — 엣지 보존의 수학적 원리

SG 계수에는 음수가 나타납니다. 이는 수학적 필연이며, 엣지 보존의 핵심 메커니즘입니다.

예: r=2, m=2 (W=5)
$$\hat{\mathbf{h}} = \left[-\frac{3}{35},\; \frac{12}{35},\; \frac{17}{35},\; \frac{12}{35},\; -\frac{3}{35}\right]$$

양 끝의 음수 계수는 신호의 2차 도함수(곡률) 정보를 포함합니다. 이 구조가 피크 높이를 보존하면서도 노이즈를 제거할 수 있게 합니다. 다른 모든 필터(Rectangular, Binomial, Gaussian)는 양수 계수만 가지므로 피크를 반드시 감쇠시킵니다.

📊 다항식 차수(m)의 영향

polyOrder (m)피팅 다항식보존 특성스무딩 강도
0상수 (y = a₀)평균값만최대 — Rectangular과 동일
1직선 (y = a₀ + a₁x)추세(기울기)강함
2 (기본)포물선 (y = a₀+a₁x+a₂x²)피크 높이 + 곡률보통 — 가장 범용적
33차 다항식변곡점약함
4+고차 다항식세밀한 구조매우 약함 — 과적합 위험
제약 조건: m < W = 2r+1. m ≥ W이면 데이터를 완벽히 보간하여 스무딩 효과가 사라집니다. 일반적으로 m=2 (포물선)이 가장 널리 사용됩니다.

🔍 Adaptive 비대칭 계수

Asymmetric Window at Boundary
$$\text{left} = \min(r, i), \quad \text{right} = W - 1 - \text{left}$$

경계에서는 비대칭 윈도우에 맞는 새로운 설계 행렬 A'를 구성하고 QR 분해를 다시 수행합니다. 이로써 경계에서도 다항식 피팅의 정확성이 보장됩니다.

// Adaptive SG — 비대칭 계수 생성
var sides = GetAdaptiveSides(i, r, n);
var coeffs = ComputeSGAsymmetric(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;
// α 블렌딩 미적용 — 다항 피팅 특성 보존 우선
α 블렌딩: 적용되지 않습니다. 다항식 피팅의 수학적 특성(피크 보존, 도함수 구조)을 변질시키지 않기 위한 설계 결정입니다.

🔬 Savitzky-Golay 시뮬레이터

Poly Order를 변경하여 스무딩 강도와 피크 보존의 trade-off를 확인하세요.

5
2

⚡ 최적화 포인트

  • QR 분해 사전 계산: 대칭 윈도우(Interior) 계수는 1회만 QR 분해하여 재사용
  • Adaptive 비용: 경계 픽셀마다 QR 분해 → O(W · m²) 추가 비용. 6개 필터 중 가장 느림
  • Householder 방식: Gram-Schmidt보다 수치적으로 안정. 특이(singular) 행렬에 강건
  • 병렬화: N ≥ 2,000 → Parallel.For 자동 활성화
Core Infrastructure

Boundary Mode - 경계 샘플 합성 전략

커널이 데이터 경계를 넘어설 때 존재하지 않는 샘플을 어떻게 처리하는지 결정합니다. 4가지 모드가 모든 6개 필터에 공통 적용됩니다.

📦 4가지 모드 상세

모드경계 시각화 (data = [1,2,3,4,5])특성적합한 상황
Symmetric3 2 1 | 1 2 3 4 5 | 5 4 31차 도함수 연속일반적인 신호 처리 (DSP 표준)
Replicate1 1 1 | 1 2 3 4 5 | 5 5 5경계 평탄화에지 값을 유지해야 할 때
ZeroPad0 0 0 | 1 2 3 4 5 | 0 0 0경계 에너지 감쇠데이터 외부 = 0인 시나리오
Adaptive[1 2 3][2 3 4] → [3 4 5] → …합성 샘플 없음실제 데이터만 사용해야 할 때

💻 구현 — GetValueWithBoundary() / GetAdaptiveSides()

// 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 보상 적용)

⚙️ GetAdaptiveSides 상세 알고리즘 SG 전용

Adaptive Window Sizing (SG — 윈도우 크기 W 보존)
$$\text{left} = \min(r,\, i), \quad \text{right} = (2r{+}1) - 1 - \text{left}, \quad \text{if } \text{right} > n{-}1{-}i \Rightarrow \text{left} \mathrel{+}= \text{extra}$$
1
left = min(r, i)

왼쪽으로 가용한 샘플 수 계산. 인덱스 i가 r보다 작으면 왼쪽이 축소됩니다.

2
right = W − 1 − left

보상 메커니즘: 왼쪽이 줄어든 만큼 오른쪽이 늘어나 총 윈도우 크기 W를 유지합니다.

3
maxRight 제약 → left로 재분배

right > (n−1−i)이면 extra = right − maxRight를 계산하고, right = maxRight, left = min(i, left + extra)로 초과분을 왼쪽으로 재분배합니다. 이 보상으로 W가 가능한 한 유지됩니다.

4
Safety caps

left = min(left, i), right = min(right, n−1−i)로 최종 안전 제한을 적용합니다.

⚠ 필터별 Adaptive 처리 차이:
SG만 GetAdaptiveSides()를 사용하여 윈도우 크기 W를 보존(보상 재분배)합니다. 다항식 피팅에 최소 W개의 데이터 포인트가 필요하기 때문입니다.
Rect · Binomial · Gaussian은 인라인 Math.Min(r, i) / Math.Min(r, n−1−i)로 양쪽을 독립 축소합니다. W_local = left + right + 1이 원래 W보다 작아질 수 있으며, 보상 재분배 없이 축소된 크기에 맞는 새 계수를 생성합니다.
Gaussian MedianMath.Max(0, i−r) / Math.Min(n−1, i+r)로 절대 인덱스 범위를 직접 제한합니다.

🔬 Boundary Mode 시각화

반경을 늘려 경계 처리의 영향이 커지는 것을 확인하세요.

3

🔢 경계 처리 숫자 그리드 시뮬레이터

중심 인덱스(i)와 반경(r)을 변경하며, 각 경계 모드가 범위 밖 인덱스를 어떤 값으로 합성하는지 셀 단위로 비교합니다. 색상 셀 = 합성(가상) 샘플. 하단의 전체 인덱스 개요에서 Rectangular 필터 결과도 확인하세요.

2
0
Interactive · Laboratory

Filter Lab

SmoothingConductor.ApplySmoothing과 동일한 JavaScript 구현으로 필터링 결과를 확인합니다.

📥 데이터 입력

데이터 길이: 0

⚙️ 매개변수

5
2
1.00
6.0

🎚️ 활성 필터

Resources · Downloads

다운로드 및 외부 링크

SonataSmooth 메인 애플리케이션 소스, .NET Standard 2.0 기반 스무딩 라이브러리 NuGet 패키지, 그리고 라이브러리 기능을 직접 실험해볼 수 있는 실습용 Etude 애플리케이션을 아래 링크에서 확인하실 수 있습니다.

GitHub Repository happybono / SonataSmooth

SonataSmooth

SonataSmooth의 메인 소스 코드 저장소입니다. C# .NET Windows Forms 기반으로 제작된 수치 데이터 노이즈 제거 및 평활화 애플리케이션으로, 수동 입력, 클립보드 붙여넣기, 드래그 앤 드롭 등 다양한 입력 방식과 강력한 유효성 검사를 지원합니다.

NAMING PHILOSOPHY

SonataSmooth은 "Sonata"와 "Smooth"의 합성어입니다. 소나타(Sonata)는 서로 다른 악장(악장 = 알고리즘)이 하나의 조화로운 전체로 어우러지는 음악 형식으로, 여러 스뭔딩 알고리즘이 협주(concert)하여 함께 작동한다는 철학을 담고 있습니다.

⚠ SPECIAL LICENSING NOTICE

대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.

C# / .NET Windows Forms Noise Reduction Signal Processing
↗ View Source on GitHub
NuGet Package SonataSmooth.Tune · v5.3.0 · .NET Standard 2.0

SonataSmooth.Tune

.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) 내보내기 헬퍼로 여러 스무딩 결과를 나란히 비교 · 차트화할 수 있습니다.

C# / .NET Standard 2.0 Signal Smoothing CSV · Excel Export Parallelization
$ dotnet add package SonataSmooth.Tune --version 5.3.0
⚠ SPECIAL LICENSING NOTICE

대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.

↗ Download on NuGet Gallery

Quick Start

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);
GitHub Repository happybono / SonataSmooth.Tune.Etude

SonataSmooth.Tune.Etude

SonataSmooth.Tune 라이브러리의 기능을 직접 체험하고 학습할 수 있는 실습용 동반 애플리케이션입니다. 음악에서 에튀드(Étude)가 최종 작품을 위한 준비 연습곡이듯, 이 저장소는 본격적인 데이터 처리 애플리케이션을 구현하기 전에 SonataSmooth.Tune의 다양한 스무딩 알고리즘을 실험하고 이해하기 위한 스케치이자 학습 공간입니다.

NAMING PHILOSOPHY

SonataSmooth.Tune은 데이터를 악기 조율하듯 정밀하게 다듬는 C# / .NET 스뭔딩 라이브러리이며, SonataSmooth.Tune.Etude는 그 라이브러리를 위한 연습곡(Étude) - 완성된 작품에 앞서 기법을 탐구하고 숙달하는 실습 공간입니다.

⚠ SPECIAL LICENSING NOTICE

대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.

C# / .NET Hands-on Study App Signal Processing Sample · Docs Included
↗ View on GitHub