【发布时间】:2026-01-25 01:35:01
【问题描述】:
我需要一种算法(最好使用类似 Pascal 的语言,但它的结尾并不重要),它将使左侧的“信号”(实际上是一系列数据点)看起来像右侧的。
信号来源:
信号由机器产生。解释过于简单,机器正在测量流过透明管的液体的密度。因此,该信号与电信号(音频/射频)完全不同。
数据点可能如下所示: [1, 2, 1, 3, 4, 5, 4, 3, 2, 1, 13, 14, 15, 18, 23, 19, 17, 15, 15, 15, 14 , 11, 9, 4, 1, 1, 2, 2, 1, 2]
我需要什么:
我需要准确检测“峰值”。为此,我已经有一段代码,但它不适用于下图所示的不良信号。
我认为我们可以将其视为意外通过低通滤波器的信号,现在我想恢复它。
注意事项:
有 4 个信号,但它们是分开的,因此可以单独分析。因此,只需考虑如何处理其中一个就足够了。
在一个峰值之后,如果信号下降得不够快,我们可以认为存在多个峰值(您可以在系列末尾的“红色”信号中最好地看到这一点)。
优点是全系列都可用(所以信号不是实时的,已经存档了)!
[由 Spektre 编辑]我从图像中提取了红色样本点
float f0[]={ 73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,71,69,68,66,64,62,58,54,49,41,33,25,17,13,15,21,30,39,47,54,59,62,64,66,67,68,69,70,71,71,72,72,72,71,71,70,69,68,67,66,65,63,62,60,56,51,45,37,29,22,18,18,22,28,33,35,36,35,32,26,20,15,12,15,20,26,31,35,37,36,34,30,25,22,22,27,33,41,48,55,60,63,66,67,68,69,70,71,72,72,73,73,73,73,73,73,72,71,70,69,67,65,63,60,55,49,40,30,21,13, 7,10,17,27,36,45,52,56,59,60,61,62,62,62,62,61,61,59,57,53,47,40,32,24,18,15,18,23,28,32,33,31,28,23,16,10, 6, 8,13,20,27,31,32,31,28,22,15,10, 6,10,16,23,30,34,36,36,34,29,24,20,19,24,30,37,44,51,56,59,61,62,63,64,64,64,65,64,64,62,60,57,53,48,43,38,36,39,43,49,54,59,63,66,68,69,70,71,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73 };
float f1[]={ 55,58,60,62,64,66,67,68,68,69,69,70,71,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,73,73,73,72,72,72,72,71,71,71,71,71,71,70,70,69,68,67,66,64,63,61,60,59,57,55,52,49,46,43,40,37,35,34,33,32,32,33,34,36,37,39,41,43,45,47,50,52,55,57,59,60,61,61,62,62,62,62,61,61,60,58,57,55,53,51,49,48,46,44,42,40,38,35,32,30,29,28,27,27,26,26,26,25,25,24,23,23,23,24,24,25,25,26,26,26,27,28,29,31,33,35,38,40,41,43,44,46,48,50,53,55,57,59,60,61,62,63,64,64,65,65,64,63,61,59,57,54,52,50,47,45,42,39,37,34,32,31,30,30,30,31,32,34,36,37,39,40,41,42,43,44,44,44,44,43,42,41,40,38,36,34,32,30,28,26,25,24,23,22,21,20,18,17,17,17,17,18,18,18,18,18,18,18,18,18,18,19,19,19,19,20,20,21,23,24,25,26,26,26,27,28,29,31,34,36,37,38,40,41,43,45,47,48,49,50,51,51,51,50,49,49,48,48,47,47,47,47,47,47,48,60 };
const int n=sizeof(f0)/sizeof(f0[0]);
所有值都需要转换:
f0[i] = 73.0-f0[i];
f1[i] = 73.0-f1[i];
要从图像偏移...f0 是原始红色信号,f1 是失真的黄色信号。
这是我使用一阶 FIR 滤波器得到的最接近的结果:
上半部分是使用的 FIR 滤波器权重图(可通过鼠标编辑,因此 FIR 是手绘的,以便快速找到权重...)。下面是信号图:
-
红色原始(理想)信号
f0 -
深绿色测量信号
f1 -
浅绿色 FIR 滤波理想信号
f2FIR 滤波器只是卷积,其中零偏移元素是最后一个,这里是权重值:
float fir[35] = { 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.0007506932, 0.003784107, 0.007575874, 0.01060929, 0.01591776, 0.02198459, 0.03032647, 0.04170178, 0.05686884, 0.06445237, 0.06900249, 0.07203591, 0.07203591, 0.0705192, 0.06900249, 0.06672744, 0.06217732, 0.05611049, 0.04928531, 0.04170178, 0.03335989, 0.02653471, 0.02046788, 0.01515941, 0.009850933, 0.005300813, 0.0007506932 };
所以要么有更高程度的 FIR,要么需要对权重进行更多调整。无论如何,这对于去卷积和/或拟合应该足够了......顺便说一句,FIR 滤波器的完成如下:
const int fir_n=35; // size (exposure time) [samples]
const int fir_x=fir_n-1; // zero offset element [samples]
int x,y,i,j,ii;
float a,f2[n];
for (i=0;i<n;i++)
for (f2[i]=0.0,ii=i-fir_x,j=0;j<fir_n;j++,ii++)
if ((ii>=0)&&(ii<n)) f2[i]+=fir[j]*f0[ii];
【问题讨论】:
-
?????????????????????????????????????????? ?
-
描述太模糊了……我的直觉告诉我你的信号被低通滤波了(不情愿地),你想重建原始信号。如果您知道滤出的正弦波的频率、相位和幅度(常数或与基本信号成比例),那么您可以用它来调制输入信号。添加一些示例数据集(数字)和有关信号的更多信息,以便我们可以实际进行一些测试。
-
由于这更像是一个 DSP 理论问题,而不是一个实际的实际编程问题,我建议您尝试在 dsp.stackexchange.com 上提问。
-
@Spektre-谢谢。我更新了问题。如果仍有歧义,请告诉我,我将添加更多解释。 PS:信号没有被过滤,但是是的,我的问题是这样的。
-
@SolarWind 所以听起来测量的(左)信号是某些管中流体的准确表示。目标(右)信号是某种控制流入管子的驱动信号?您给了我们一个物理问题,并且可能会通过 (a) 将其发布到 Stack Exchange 的不同频道,以及 (b) 实际描述实验设置和 机械 (因果)两个信号之间的联系。本着与 Spektre 的回答相同的精神,我的直觉是您可以将平滑建模为卷积,并且应该研究 1D 反卷积。
标签: algorithm time-series signal-processing data-analysis