一种均值滤波算法
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
以前我总是逃避,我想好好面对余生。
浙公网安备 33010602011771号