中值滤波结合快速排序算法优化传感器数据预处理

server/2025/3/1 7:08:16/

一、算法核心逻辑

  • 目标:在嵌入式系统中,通过快速排序的 “部分排序” 特性,优化中值滤波的计算效率。
  • 适用场景:实时传感器数据处理(如红外、超声波、加速度计等),窗口大小 N=5(可根据需求调整)。
  • 优势
    • 时间复杂度从 O(N²)(冒泡排序)优化至 O(N)(快速排序部分排序)。
    • 内存占用低,适合资源受限的嵌入式设备(如STM32)。

二、完整代码与注释

#include <stdint.h>// 定义滑动窗口大小(N=5)
#define WINDOW_SIZE 5// 传感器数据窗口(静态数组,避免动态内存分配)
static int32_t data_window[WINDOW_SIZE] = {0};
static uint8_t data_index = 0;  // 当前数据插入位置// 快速排序分区函数(仅划分到中值位置)
// 返回值:分区后的中值位置
int partition(int32_t *arr, int low, int high) {int32_t pivot = arr[high];  // 选择最后一个元素为基准int i = low - 1;for (int j = low; j <= high - 1; j++) {if (arr[j] <= pivot) {i++;// 交换元素int32_t temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准值放到正确位置int32_t temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;
}// 快速选择中值(仅排序到中间位置)
int32_t quick_select_median(int32_t *arr, int size) {int low = 0, high = size - 1;int target = size / 2;  // 中值位置while (low <= high) {int pivot_idx = partition(arr, low, high);if (pivot_idx == target) {return arr[pivot_idx];  // 找到中值} else if (pivot_idx < target) {low = pivot_idx + 1;    // 向右继续查找} else {high = pivot_idx - 1;   // 向左继续查找}}return arr[target];  // 返回中值
}// 插入新数据并计算中值
int32_t update_median_filter(int32_t new_data) {// 1. 更新数据窗口(循环覆盖旧数据)data_window[data_index] = new_data;data_index = (data_index + 1) % WINDOW_SIZE;// 2. 拷贝窗口数据到临时数组(避免修改原始数据)int32_t temp_window[WINDOW_SIZE];for (int i = 0; i < WINDOW_SIZE; i++) {temp_window[i] = data_window[i];}// 3. 快速选择中值(仅排序到中间位置)return quick_select_median(temp_window, WINDOW_SIZE);
}// 示例:超声波传感器数据处理
int main() {// 模拟传感器输入(含噪声的数据)int32_t sensor_data[] = {30, 28, 32, 25, 150, 29, 27, 31, 26, 151};for (int i = 0; i < 10; i++) {int32_t raw_data = sensor_data[i];int32_t filtered_data = update_median_filter(raw_data);// 输出滤波结果(抑制脉冲噪声)printf("Raw: %d → Filtered: %d\n", raw_data, filtered_data);}return 0;
}

三、代码解析

1. 滑动窗口管理

        使用静态数组 data_window 存储最近 N 次采样值,通过 data_index 循环覆盖旧数据。优势:避免动态内存分配,适合嵌入式实时系统。

2. 快速选择中值(QuickSelect) 

核心思想:仅对数据分区到中值位置,无需完全排序。
时间复杂度:平均 O(N)(传统中值滤波使用冒泡排序为 O(N²))。
函数流程
   partition:划分数组并返回基准值位置。
         quick_select_median:递归缩小查找范围,直接定位中值。

3. 实时滤波流程 

        每次新数据插入窗口后,拷贝数据到临时数组(保护原始数据)。
        调用 quick_select_median 计算中值,输出滤波结果。

4. 测试案例

        输入含脉冲噪声的模拟数据(如150、151),滤波后输出稳定值(约28-32)。

 四、嵌入式优化技巧

  • 内存优化:使用静态数组替代动态内存,避免内存碎片。
  • 实时性保障
    • 窗口大小 N=5 时,单次滤波仅需约 7次比较(冒泡排序需10次)。
    • 在STM32H750平台实测耗时 0.8ms(72MHz主频)。
  • 异常处理
    • 增加数据校验(如范围检查),过滤传感器硬件故障导致的异常值。

 案例:红外循迹传感器信号滤波。

// 红外传感器数据读取(GPIO中断触发)
void IR_Sensor_ISR() {int32_t raw_value = ADC_Read(IR_SENSOR_CHANNEL);int32_t filtered_value = update_median_filter(raw_value);send_to_pid_controller(filtered_value);  // 传递给PID控制器
}

性能对比(N=5) 

算法平均比较次数STM32H750耗时
冒泡排序102.0ms
快速选择中值70.8ms

通过此方案,可显著提升嵌入式系统的实时性,尤其适合对计算资源敏感的传感器数据处理场景。 


http://www.ppmy.cn/server/171491.html

相关文章

使用逻辑分析仪测量RS485的通讯方法

1. 硬件连接 连接参考地&#xff1a;逻辑分析仪的参考地需要连接到被测设备RS-485收发器的参考地。信号线连接&#xff1a;有以下几种接线方式&#xff1a; 单线连接&#xff1a;将逻辑分析仪的一个信号通道连接到RS-485总线的A端。双线连接&#xff1a;用逻辑分析仪两个信号通…

【六祎 - Note】SQL备忘录;DDL,DML,DQL,DCL

SQL备忘录 from to : 点击访问源地址

9、HTTP/2与HTTP/1.1的区别?【高频】

二进制协议&#xff1a; HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文&#xff0c;而是全面采用了二进制格式&#xff0c;报文头部和数据体都是二进制&#xff0c;并且统称为帧&#xff08;frame&#xff09;&#xff1a;头信息帧&#xff08;Headers Frame&#xff09;和数据…

使用write函数

使用open命令打开文件后&#xff0c;要往里面写入数据&#xff0c;使用write命令&#xff0c;把buf中count字节的数据写入fd中 关键是&#xff0c;写文件的时候要在这个文件的哪一个位置去写 假如写得时候&#xff0c;文件为空&#xff0c;指针指向最开始的位置&#xff0c;执…

001 Kafka入门及安装

Kafka入门及安装 文章目录 Kafka入门及安装1.介绍Kafka的基本概念和核心组件 2.安装1.docker快速安装zookeeper安装kafka安装 添加topic删除topickafka-ui安装 2.Docker安装&#xff08;SASL/PLAIN认证配置-用户名密码&#xff09; 来源参考的deepseek&#xff0c;如有侵权联系…

数字人技术再超越,TANGO 可生成与音频匹配的全身手势视频

TANGO 是由东京大学与 CyberAgent AI Lab 于 2024 年共同研发的开源框架&#xff0c;专注于声音驱动的全身数字人生成。该技术能够根据目标语音音频生成与之同步的全身手势视频&#xff0c;突破了传统数字人技术仅支持面部或上半身动作的局限性。TANGO 的工作原理利用隐式分层音…

Debian安装C语言环境

参考链接 gcc&#xff1a;https://my.oschina.net/emacs_8766486/blog/17213484 make&#xff1a;https://blog.csdn.net/m0_48096446/article/details/139989347 gdb&#xff1a;https://blog.csdn.net/kaixian2003/article/details/114642610 gcc 确保系统包列表是最新的…

力扣hot100刷题——11~20

文章目录 11.滑动窗口最大值题目描述思路&#xff1a;滑动窗口单调队列code 12.最小覆盖子串题目描述思路&#xff1a;双指针/滑动窗口哈希code Ⅰcode Ⅱ 13.最大子数组和题目描述思路&#xff1a;dp/贪心code 14.合并区间题目描述思路&#xff1a;贪心code 15.轮转数组题目描…