54 lines
1.5 KiB
C
54 lines
1.5 KiB
C
//
|
|
// Created by IRIS on 25-2-12.
|
|
//
|
|
|
|
#include "data_analyse.h"
|
|
#define WINDOW_SIZE 5 // 高斯滑动窗口大小(建议为奇数)
|
|
#define SIGMA 1.5 // 平滑程度,值越大平滑越强
|
|
|
|
|
|
// 计算高斯权重
|
|
void compute_gaussian_weights(double weights[], int size, double sigma) {
|
|
double sum = 0.0;
|
|
int half_size = size / 2;
|
|
|
|
for (int i = -half_size; i <= half_size; i++) {
|
|
weights[i + half_size] = exp(- (i * i) / (2 * sigma * sigma)); // 高斯分布公式
|
|
sum += weights[i + half_size];
|
|
}
|
|
// 归一化,使权重之和为 1
|
|
for (int i = 0; i < size; i++) {
|
|
weights[i] /= sum;
|
|
}
|
|
}
|
|
|
|
// SGI 平滑算法 (适用于 uint16_t 数据)
|
|
void sgi_smoothing(uint16_t data[], uint16_t result[], int size) {
|
|
double weights[WINDOW_SIZE];
|
|
compute_gaussian_weights(weights, WINDOW_SIZE, SIGMA);
|
|
|
|
int half_size = WINDOW_SIZE / 2;
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
double sum = 0.0;
|
|
double weight_sum = 0.0;
|
|
|
|
for (int j = -half_size; j <= half_size; j++) {
|
|
int idx = i + j;
|
|
if (idx >= 0 && idx < size) { // 确保索引有效
|
|
sum += data[idx] * weights[j + half_size];
|
|
weight_sum += weights[j + half_size];
|
|
}
|
|
}
|
|
// 四舍五入并转换为 uint16_t
|
|
result[i] = (uint16_t)round(sum / weight_sum);
|
|
}
|
|
}
|
|
|
|
|
|
void sgi(uint16_t *data, uint16_t *result) {
|
|
int size = sizeof(data) / sizeof(data[0]);
|
|
sgi_smoothing(data, result, size);
|
|
}
|
|
|