电子产业一站式赋能平台

PCB联盟网

搜索
查看: 189|回复: 0
收起左侧

【滤波第二期】中值滤波的原理和C代码

[复制链接]

397

主题

397

帖子

2463

积分

三级会员

Rank: 3Rank: 3

积分
2463
发表于 2023-12-4 21:00:00 | 显示全部楼层 |阅读模式

r0ephhzpp4m6401888610.png

r0ephhzpp4m6401888610.png
. d7 @% Z8 e7 A- v8 e0 w5 `
中值滤波是一种非线性数字滤波技术,主要应用于信号处理和图像处理领域,用于减小信号中的噪声和离群值。中值滤波的核心思想是通过计算一组数据点的中间值,以抑制脉冲噪声等离群值的影响,从而实现信号的平滑处理。
& P% i! J" `3 x  S$ k2 j1 M' _, r& a8 x2 x2 G
1,中值滤波的操作步骤如下:
8 J: @( |2 g8 A+ e. g. T/ S: Q, ?1 N# p% H5 F! V- i8 f
窗口设置: 中值滤波使用一个固定大小的窗口覆盖信号中的数据点。这个窗口的大小是根据具体应用需求事先确定的,通常是奇数,例如3x3、5x5等。+ N0 F4 T7 J, k, S* s2 ]

6 q! i" \' @$ h数据排序: 在每个窗口位置,将窗口内的数据点按照大小进行排序。这样,窗口中的数据就被排列成一个有序序列。3 Z1 [' }3 o& t8 Q& Q
; R( V6 ~+ K7 ^; F! b) {
中值计算: 选择排序后序列的中间位置的值作为滤波结果。如果窗口大小是奇数,中值就是排序序列的正中间的值;如果窗口大小是偶数,中值通常是中间两个值的平均值。
" w0 e. l: {) c8 j) @* X
* E+ h$ T# Q: a. Q4 q. {2,中值滤波的原理可通过以下几个关键概念来理解:
7 j+ a0 W- T- n( a/ R1 X
% `9 D$ d+ M; d3 e! K$ y排序特性: 中值滤波的核心在于对数据进行排序。排序后,中间值处于排序序列的中间位置,因此能够较好地反映数据的趋势
) g, c8 W9 o! w+ o/ q) ~; r. V' K# R, K
非线性特性: 与线性滤波器不同,中值滤波是一种非线性滤波方法。它对噪声和离群值的敏感性相对较低,因为中值主要受窗口中排序序列的中间位置的影响,而不受其他数值的大小影响。( q3 q: H/ L% F' S
! Z5 Y; X6 j7 k  ^
适用于离散信号: 中值滤波通常适用于处理离散信号,例如时间序列中的测量数据。在图像处理中,中值滤波也常被用于去除图像中的噪声。0 o0 W8 @' _, T$ a: |
, P# }3 W" c9 M7 U; ~3 c% V9 q
中值滤波的优点在于它能够有效抑制离群值,同时保持信号边缘信息,不引入额外的相位变化。然而,中值滤波也有一些缺点,比如在处理高斯噪声等均值为零的噪声时效果相对较差,因为中值滤波并不是最优的线性估计器。, p& S0 F' ]. d( i' E

# h8 `% W7 U( g- N# G3,示例代码:% M9 t2 S: J( A/ [# x! a( o* d
  • #include #define WINDOW_SIZE 3// 函数原型float medianFilter(float data[], int dataSize);int main() {// 输入数据float inputData[] = {1.0, 3.0, 5.0, 2.0, 8.0, 6.0, 4.0, 7.0, 9.0, 10.0};int dataSize = sizeof(inputData) / sizeof(inputData[0]);// 创建输出数组    float outputData[dataSize];// 对每个数据点应用中值滤波for (int i = 0; i         outputData = medianFilter(inputData, dataSize);    }// 打印结果printf("Original Data:8 n1 I9 ]  d/ V" s4 H0 ]1 c* P
    ");for (int i = 0; i printf("%f ", inputData);    }printf("3 `  o6 y- v% v
    Filtered Data:/ _. ^" B2 H7 E. o) d0 I( |  ^4 ^
    ");for (int i = 0; i printf("%f ", outputData);    }return 0;}// 计算中值滤波float medianFilter(float data[], int dataSize) {float window[WINDOW_SIZE];for (int i = 0; i // 填充窗口for (int j = 0; j int index = i - (WINDOW_SIZE / 2) + j;// 处理窗口边界情况if (index                 window[j] = data[0];            } else if (index >= dataSize) {                window[j] = data[dataSize - 1];            } else {                window[j] = data[index];            }        }// 对窗口内数据进行排序for (int j = 0; j for (int k = 0; k if (window[k] > window[k + 1]) {// 交换float temp = window[k];                    window[k] = window[k + 1];                    window[k + 1] = temp;                }            }        }// 选择中间值作为滤波结果float median = window[WINDOW_SIZE / 2];return median;    }}5 }0 o5 W6 A+ X5 g( v* f. J" ^& o- g
    在这个简单的示例中,WINDOW_SIZE 定义了中值滤波的窗口大小。medianFilter 函数对每个数据点应用中值滤波,处理窗口边界情况以确保滤波窗口不越界。请注意,这只是一个基本的实现,实际应用中可能需要根据具体需求进行调整和优化。. \- z: J7 s2 r5 B2 h3 s

    : n5 o/ W" }. j2 J& f==========( }% n0 O5 p6 K2 C9 a, Z4 r
    往期回顾:移动平均滤波的原理和C代码
    9 w7 E. n2 h' t2 k0 K$ vMOS管防反接电路" Q, n  w# _8 d2 _( E7 n
    STM32的看门狗原理和示例代码. _- V6 T# q7 }6 _2 t, o
    Keil仿真调试STM32与LED* @0 T/ @$ w; w' `. E: [- s
    ==========
    3 v/ [* N9 e, m  N2 a
    - u/ d: P5 F$ e7 h) G6 l5 I

    ndsmhrll0ua6401888710.png

    ndsmhrll0ua6401888710.png
    ) R- i. k4 \# w# D/ j. F

    * X* w( Y8 F, i$ y4 t7 H& P. x

    pnizdpsf1m36401888811.png

    pnizdpsf1m36401888811.png

    ; K0 B6 \0 a. J1 ?
    , G; x/ U. ^2 A8 J; B' P  S, i

    4uw0youdfym6401888911.png

    4uw0youdfym6401888911.png
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表