Skip to main content

11 Digital Filtering Algorithms in C++

·815 words·4 mins
C++ Digital Filtering Algorithms
Table of Contents

Introduction
#

Digital filtering is widely used to remove noise from signals in embedded systems, sensor readings, or any data acquisition application. Here, we present 11 common filtering algorithms with generic C++ implementations suitable for microcontrollers, desktop applications, or any C++ environment.


1. Clipping Filter (Limit Filter)
#

Rejects abrupt changes beyond a defined threshold.

int filterValue = 300;

int getSample() {
    return 295 + rand() % 11; // Simulate a sample around 300
}

int limitFilter(int value, int threshold = 1) {
    int newVal = getSample();
    if (abs(newVal - value) > threshold) return value;
    return newVal;
}

void example() {
    filterValue = limitFilter(filterValue);
}

2. Median Filter
#

Sorts N consecutive samples and returns the middle value, effective for pulse noise.

#include <vector>
#include <algorithm>

int medianFilter(int N = 101) {
    std::vector<int> buf(N);
    for (int& v : buf) v = 295 + rand() % 11;

    std::sort(buf.begin(), buf.end());
    return buf[N / 2];
}

3. Arithmetic Mean Filter
#

Averages N consecutive samples to reduce random noise.

int meanFilter(int N = 12) {
    int sum = 0;
    for (int i = 0; i < N; ++i) sum += 295 + rand() % 11;
    return sum / N;
}

4. Recursive (Moving Average) Filter
#

A sliding window average filter with efficient incremental updates.

#include <array>

constexpr int N = 12;
std::array<int, N> buf = {300};

int movingAverageFilter() {
    int sum = 0;
    int newSample = 295 + rand() % 11;
    for (int i = 0; i < N - 1; ++i) {
        buf[i] = buf[i + 1];
        sum += buf[i];
    }
    buf[N - 1] = newSample;
    sum += buf[N - 1];
    return sum / N;
}

5. Median-Mean Filter
#

Combines median and arithmetic mean to remove spikes while smoothing.

int medianMeanFilter(int N = 100) {
    std::vector<int> buf(N);
    for (int& v : buf) v = 295 + rand() % 11;

    std::sort(buf.begin(), buf.end());
    int sum = 0;
    for (int i = 1; i < N - 1; ++i) sum += buf[i];
    return sum / (N - 2);
}

6. Limit-Average Filter
#

Applies limit filter before moving average to remove spikes and smooth signal.

int limitAverageFilter() {
    int newSample = 295 + rand() % 11;
    if (abs(newSample - buf[N-2]) > 1) newSample = buf[N-2];
    for (int i = 0; i < N - 1; ++i) buf[i] = buf[i+1];
    buf[N-1] = newSample;
    int sum = 0;
    for (int val : buf) sum += val;
    return sum / N;
}

7. First-Order Lag Filter
#

Implements an exponential smoothing filter:

double value = 300.0;
constexpr double alpha = 0.01;

double lagFilter() {
    double newSample = 295 + rand() % 11;
    value = alpha * newSample + (1.0 - alpha) * value;
    return value;
}

8. Weighted Recursive Filter
#

A moving average with weighted coefficients for recent samples.

int weightedFilter() {
    std::array<int, N> weights;
    for (int i = 0; i < N; ++i) weights[i] = i+1; // increasing weights
    int newSample = 295 + rand() % 11;
    buf[N] = newSample;

    int sum = 0;
    int weightSum = 0;
    for (int i = 0; i < N; ++i) {
        buf[i] = buf[i+1];
        sum += buf[i] * weights[i];
        weightSum += weights[i];
    }
    return sum / weightSum;
}

9. Debounce Filter
#

Prevents rapid toggling by requiring N consecutive changes to confirm a new value.

int value = 300;
int counter = 0;

int debounceFilter(int N = 12) {
    int newSample = 295 + rand() % 11;
    if (newSample != value) {
        if (++counter >= N) { value = newSample; counter = 0; }
    } else counter = 0;
    return value;
}

10. Limit-Debounce Filter
#

Combines limit and debounce filtering for robust spike removal.

int limitDebounceFilter() {
    int newSample = 295 + rand() % 11;
    if (abs(newSample - value) > 1) newSample = value;
    if (newSample != value) {
        if (++counter > 5) { value = newSample; counter = 0; }
    } else counter = 0;
    return value;
}

11. Kalman Filter (Non-Extended)
#

A state-space filter for sensor fusion or noisy measurements.

struct Kalman1D {
    double x = 0;   // estimated state
    double p = 1;   // estimated covariance
    double q = 0.0025; // process noise
    double r = 0.25;   // measurement noise

    double update(double measurement) {
        // Prediction
        p += q;
        // Kalman gain
        double k = p / (p + r);
        // Update estimate
        x += k * (measurement - x);
        // Update covariance
        p *= (1 - k);
        return x;
    }
};

Kalman1D kalmanX;
double filteredValue = kalmanX.update(295 + rand() % 11);

Conclusion
#

These 11 algorithms cover a wide range of filtering needs:

  • Clipping, median, mean, and moving average filters for simple noise removal.
  • Limit-average and weighted filters for robust smoothing.
  • Debounce and limit-debounce filters for digital signal stabilization.
  • First-order lag and Kalman filters for real-time sensor fusion.

Using modern C++ idioms—vectors, arrays, and RAII—makes the filters safe, maintainable, and portable across embedded and desktop applications.

Related

非常强大的高性能 C++ 服务器引擎
·72 words·1 min
程序 C++
htop: A Better Process Management Tool for Linux
·439 words·3 mins
Htop Linux Process Management System Monitoring
C File I/O Tutorial with Examples: fopen, fclose, fread, fwrite
·664 words·4 mins
C File Linux