一种均值滤波算法

FliterAlgorithm.c


#include <stdio.h>
#include "FliterAlgorithm.h"


/**
 * @brief  初始化均值滤波器
 */
void MeanFilter_Init(MeanFilter_t *f)
{
    unsigned short int i;
    f->index = 0;
    f->count = 0;
    for (i = 0; i < MEAN_FILTER_BUF_LEN; i++)
    {
        f->buf[i] = 0;
    }
}

/**
 * @brief  输入一个新样本,计算去最大最小后的均值
 * @param  f        滤波器对象
 * @param  new_val  新采样值
 * @param  out      输出滤波后的结果
 * @return 0: 缓存未填满,未输出有效滤波值
 *         1: 缓存已填满,*out 为有效滤波结果
 */
int MeanFilter_PutSample(MeanFilter_t *f, unsigned int new_val, unsigned int *out)
{
    unsigned short int i;
    unsigned int sum, max_val, min_val;
    unsigned int count_valid;

    // 写入环形缓存
    f->buf[f->index] = new_val;
    f->index++;
    if (f->index >= MEAN_FILTER_BUF_LEN)
    {
        f->index = 0;
    }

    if ( f->count < (MEAN_FILTER_BUF_LEN-1) )
    {
        f->count++;
        // 缓存未填满,不进行滤波
        return 0;
    }
    else if ( f->count == (MEAN_FILTER_BUF_LEN-1) )
    {
        f->count++;
        // 缓存刚填满,进行滤波
    }

    // 缓存已填满,先找到最大值和最小值
    max_val = f->buf[0];
    min_val = f->buf[0];

    for (i = 1; i < MEAN_FILTER_BUF_LEN; i++)
    {
        unsigned int v = f->buf[i];
        if (v > max_val)
        {
            max_val = v;
        }
        if (v < min_val)
        {
            min_val = v;
        }
    }

    // === 修复点1:如果所有值相等,直接返回该值 ===
    if (max_val == min_val)
    {
        *out = max_val;
        return 1;
    }

// 现在计算sum,只包括不等于max_val且不等于min_val的样本
    sum = 0;
    count_valid = 0;
    for (i = 0; i < MEAN_FILTER_BUF_LEN; i++)
    {
        unsigned int v = f->buf[i];
        if (v != max_val && v != min_val)
        {
            sum += v;
            count_valid++;
        }
    }

    // 如果有有效样本,进行均值计算;否则,所有值相等,输出该值
    if (count_valid > 0)
    {
        *out = sum / count_valid;
    }
    else
    {
        *out = max_val;  // 所有值相等
    }

    return 1;
}



#if 1

static void Test_NotFullBuffer(void)
{
    MeanFilter_t f;
    unsigned int out;
    int ret;
    int i;

    printf("=== Test_NotFullBuffer ===\n");
    MeanFilter_Init(&f);

    for (i = 0; i < MEAN_FILTER_BUF_LEN - 1; i++)
    {
        ret = MeanFilter_PutSample(&f, 100 + i, &out);
        printf("Put %d, ret=%d", 100 + i, ret);
        if (ret)
        {
            printf(", out=%ld", (long)out);
        }
        printf("\n");
    }
    printf("\n");
}

static void Test_NormalCase(void)
{
    MeanFilter_t f;
    unsigned int out;
    int ret;
    int i;

    // 构造:{1, 2, 3, 4, 5, 6, 7, 100, -50, 8}
    // max = 100, min = -50
    // 去掉所有 != 100 且 != -50 的值求均值
    unsigned int data[MEAN_FILTER_BUF_LEN] = {1,2,3,4,5,6,7,100,-50,8};

    printf("=== Test_NormalCase ===\n");
    MeanFilter_Init(&f);

    for (i = 0; i < MEAN_FILTER_BUF_LEN; i++)
    {
        ret = MeanFilter_PutSample(&f, data[i], &out);
        printf("Put %ld, ret=%d", (long)data[i], ret);
        if (ret)
        {
            printf(", out=%ld", (long)out);
        }
        printf("\n");
    }
    printf("\n");
}

static void Test_AllEqual(void)
{
    MeanFilter_t f;
    unsigned int out;
    int ret;
    int i;

    printf("=== Test_AllEqual ===\n");
    MeanFilter_Init(&f);

    for (i = 0; i < MEAN_FILTER_BUF_LEN; i++)
    {
        ret = MeanFilter_PutSample(&f, 50, &out);
        printf("Put %d, ret=%d", 50, ret);
        if (ret)
        {
            printf(", out=%ld", (long)out);
        }
        printf("\n");
    }
    printf("\n");
}

static void Test_MultiMaxMin(void)
{
    MeanFilter_t f;
    unsigned int out;
    int ret;
    int i;

    // 例如:{10,10,10,100,100,100, -50,-50,-50, 10}
    // max = 100, min = -50
    // v != max && v != min 的只有 10
    unsigned int data[MEAN_FILTER_BUF_LEN] = {10,10,10,100,100,100,-50,-50,-50,10};

    printf("=== Test_MultiMaxMin ===\n");
    MeanFilter_Init(&f);

    for (i = 0; i < MEAN_FILTER_BUF_LEN; i++)
    {
        ret = MeanFilter_PutSample(&f, data[i], &out);
        printf("Put %ld, ret=%d", (long)data[i], ret);
        if (ret)
        {
            printf(", out=%ld", (long)out);
        }
        printf("\n");
    }
    printf("\n");
}

static void Test_RingOverwrite(void)
{
    MeanFilter_t f;
    unsigned int out;
    int ret;
    int i;
    unsigned int val;

    printf("=== Test_RingOverwrite ===\n");
    MeanFilter_Init(&f);

    // 连续写入 2*MEAN_FILTER_BUF_LEN 个值,看环形覆盖后结果是否稳定
    for (i = 0; i < 2 * MEAN_FILTER_BUF_LEN; i++)
    {
        // 简单构造数据:0,1,2,3,... (你也可以随便改成其他模式)
        val = i;
        ret = MeanFilter_PutSample(&f, val, &out);
        printf("Put %ld, ret=%d", (long)val, ret);
        if (ret)
        {
            printf(", out=%ld", (long)out);
        }
        printf("\n");
    }
    printf("\n");
}

int filiter_main(void)
{
    Test_NotFullBuffer();
    Test_NormalCase();
    Test_AllEqual();
    Test_MultiMaxMin();
    Test_RingOverwrite();

    return 0;
}
#endif

FliterAlgorithm.h

#ifndef __FILTER_ALGORITHM_H__
#define __FILTER_ALGORITHM_H__

#include <stdio.h>


#define MEAN_FILTER_BUF_LEN   10   // 根据需要修改

typedef struct
{
    unsigned int buf[MEAN_FILTER_BUF_LEN];
    unsigned short int index;   // 写入位置
    unsigned short int count;   // 当前有效元素个数 (<= MEAN_FILTER_BUF_LEN)
} MeanFilter_t;

int MeanFilter_PutSample(MeanFilter_t *f, unsigned int new_val, unsigned int *out);
void MeanFilter_Init(MeanFilter_t *f);

#if 1
    int filiter_main(void);
#endif

#endif
posted on 2025-12-02 11:34  Aron·Zhou  阅读(5)  评论(0)    收藏  举报