[英]Digitizing an analog signal
I have a array of CSV values representing a digital output. 我有一组表示数字输出的CSV值。 It has been gathered using an analog oscilloscope so it is not a perfect digital signal.
它是使用模拟示波器收集的,因此它不是一个完美的数字信号。 I'm trying to filter out the data to have a perfect digital signal for calculating the periods (which may vary).
我试图过滤掉数据以获得完美的数字信号来计算周期(可能会有所不同)。 I would also like to define the maximum error i get from this filtration.
我还想定义从这个过滤得到的最大误差。
Something like this: 像这样的东西:
Idea 理念
Apply a treshold od the data. 应用数据阈值。 Here is a pseudocode:
这是一个伪代码:
for data_point_raw in data_array:
if data_point_raw < 0.8: data_point_perfect = LOW
if data_point_raw > 2 : data_point_perfect = HIGH
else:
#area between thresholds
if previous_data_point_perfect == Low : data_point_perfect = LOW
if previous_data_point_perfect == HIGH: data_point_perfect = HIGH
There are two problems bothering me. 有两个问题困扰着我。
Here's a bit of code that might help. 这里有一些可能有用的代码。
from __future__ import division
import numpy as np
def find_transition_times(t, y, threshold):
"""
Given the input signal `y` with samples at times `t`,
find the times where `y` increases through the value `threshold`.
`t` and `y` must be 1-D numpy arrays.
Linear interpolation is used to estimate the time `t` between
samples at which the transitions occur.
"""
# Find where y crosses the threshold (increasing).
lower = y < threshold
higher = y >= threshold
transition_indices = np.where(lower[:-1] & higher[1:])[0]
# Linearly interpolate the time values where the transition occurs.
t0 = t[transition_indices]
t1 = t[transition_indices + 1]
y0 = y[transition_indices]
y1 = y[transition_indices + 1]
slope = (y1 - y0) / (t1 - t0)
transition_times = t0 + (threshold - y0) / slope
return transition_times
def periods(t, y, threshold):
"""
Given the input signal `y` with samples at times `t`,
find the time periods between the times at which the
signal `y` increases through the value `threshold`.
`t` and `y` must be 1-D numpy arrays.
"""
transition_times = find_transition_times(t, y, threshold)
deltas = np.diff(transition_times)
return deltas
if __name__ == "__main__":
import matplotlib.pyplot as plt
# Time samples
t = np.linspace(0, 50, 501)
# Use a noisy time to generate a noisy y.
tn = t + 0.05 * np.random.rand(t.size)
y = 0.6 * ( 1 + np.sin(tn) + (1./3) * np.sin(3*tn) + (1./5) * np.sin(5*tn) +
(1./7) * np.sin(7*tn) + (1./9) * np.sin(9*tn))
threshold = 0.5
deltas = periods(t, y, threshold)
print("Measured periods at threshold %g:" % threshold)
print(deltas)
print("Min: %.5g" % deltas.min())
print("Max: %.5g" % deltas.max())
print("Mean: %.5g" % deltas.mean())
print("Std dev: %.5g" % deltas.std())
trans_times = find_transition_times(t, y, threshold)
plt.plot(t, y)
plt.plot(trans_times, threshold * np.ones_like(trans_times), 'ro-')
plt.show()
The output: 输出:
Measured periods at threshold 0.5:
[ 6.29283207 6.29118893 6.27425846 6.29580066 6.28310224 6.30335003]
Min: 6.2743
Max: 6.3034
Mean: 6.2901
Std dev: 0.0092793
You could use numpy.histogram
and/or matplotlib.pyplot.hist
to further analyze the array returned by periods(t, y, threshold)
. 您可以使用
numpy.histogram
和/或matplotlib.pyplot.hist
来进一步分析由periods(t, y, threshold)
返回的数组。
This is not an answer for your question, just and suggestion that may help. 这不是您的问题的答案,只是建议可能有所帮助。 Im writing it here because i cant put image in comment.
我在这里写它是因为我不能把图像放在评论中。
I think you should normalize data somehow, before any processing. 我认为你应该在任何处理之前以某种方式规范化数据。
After normalization to range of 0...1 you should apply your filter. 归一化到0 ... 1范围后,您应该应用您的过滤器。
If you're really only interested in the period, you could plot the Fourier Transform, you'll have a peak where the frequency of the signals occurs (and so you have the period). 如果你真的只对这段时间感兴趣,你可以绘制傅立叶变换,你会有一个峰值信号的频率出现(所以你有周期)。 The wider the peak in the Fourier domain, the larger the error in your period measurement
傅立叶域中的峰值越宽,周期测量中的误差越大
import numpy as np
data = np.asarray(my_data)
np.fft.fft(data)
Your filtering is fine, it's basically the same as a schmitt trigger, but the main problem you might have with it is speed. 你的过滤很好,它与施密特触发器基本相同,但你可能遇到的主要问题是速度。 The benefit of using Numpy is that it can be as fast as C, whereas you have to iterate once over each element.
使用Numpy的好处是它可以像C一样快,而你必须在每个元素上迭代一次。
You can achieve something similar using the median filter from SciPy. 您可以使用SciPy的中值滤波器实现类似的功能。 The following should achieve a similar result (and not be dependent on any magnitudes):
以下应该可以达到类似的结果(并且不依赖于任何大小):
filtered = scipy.signal.medfilt(raw)
filtered = numpy.where(filtered > numpy.mean(filtered), 1, 0)
You can tune the strength of the median filtering with medfilt(raw, n_samples)
, n_samples
defaults to 3. 您可以使用
medfilt(raw, n_samples)
调整中值过滤的强度, n_samples
默认为3。
As for the error, that's going to be very subjective. 至于错误,那将是非常主观的。 One way would be to discretise the signal without filtering and then compare for differences.
一种方法是在不过滤的情况下对信号进行离散,然后比较差异。 For example:
例如:
discrete = numpy.where(raw > numpy.mean(raw), 1, 0)
errors = np.count_nonzero(filtered != discrete)
error_rate = errors / len(discrete)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.