2013-02-27 10 views
8

私は、デジタル出力を表すCSV値の配列を持っています。それはアナログオシロスコープを使用して収集されており、完全なデジタル信号ではありません。私はピリオド(変化する可能性があります)を計算するための完全なデジタル信号を持つためにデータをフィルタリングしようとしています。 このフィルタリングから得られる最大誤差を定義したいと思います。このようなアナログ信号のデジタル化

何か:

enter image description here

アイデア

データOD tresholdを適用します。ここに擬似コードがあります。

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 

私には2つの問題があります。

  1. これはデジタル信号処理の一般的な問題のようですが、あらかじめ定義された標準機能が見つかりませんでした。これはフィルタリングを実行する良い方法ですか?
  2. 最大エラーはどのようにして得られますか?
+0

完全に接線ですが、アナログオシロスコープはデジタルスコープよりもベンチではるかに優れています。デジタルスコープは、(入力と表示の両方の出力において)最小の粒度を有し、外れ値よりも光沢を帯びる傾向がある。 – L0j1k

+0

あなたは[Matlab?](http://www.mathworks.com/products/matlab/)をPythonと組み合わせて考えましたか?[This](https://sites.google.com/site/pythonforscientists/python-対MATLAB)。と[This](http://matplotlib.org/) –

+0

@ L0j1kまあ、それは実際にデジタルです、私たちは変換を自分で行うことができるようにアナログプローブを使用しています:) – TheMeaningfulEngineer

答えて

6

ここで役立つ可能性のあるコードのビットです。

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() 

出力:

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 

Plot

あなたはさらにperiods(t, y, threshold)によって返された配列を分析するためにnumpy.histogramおよび/またはmatplotlib.pyplot.histを使用することができます。

1

本当に興味があるのであれば、フーリエ変換をプロットすることができます。信号の周波数が出現するところにピークがあります。

import numpy as np 

data = np.asarray(my_data) 

np.fft.fft(data) 
+0

涼しいアイデアは、期間のヒストグラムを得るために探していますので、私たちのニーズに合ったパーセンテージを教えてください。これは、ラズベリーパイのさまざまなソフトウェアPWMを実装する領域での実験用です。 – TheMeaningfulEngineer

1

あなたの期間の測定誤差が大きいほど、フーリエ領域におけるピーク幅の広いあなたのフィルタリングは結構です、それは基本的にはシュミットトリガと同じだが、それとのあなたが持っている可能性がある主な問題は速度です。 Numpyを使用する利点は、Cと同じくらい速いことですが、各要素を一度反復する必要があります。

SciPyのメジアンフィルタを使用すると、同様の効果を得ることができます。同様の結果を達成(および任意の大きさに依存していない)必要があり、次

filtered = scipy.signal.medfilt(raw) 
filtered = numpy.where(filtered > numpy.mean(filtered), 1, 0) 

調整することができますして中央値フィルタリングの強度medfilt(raw, n_samples)n_samplesデフォルト3.エラーについては

に、それは非常に主観的になるだろう。 1つの方法は、フィルタリングせずに信号を離散化し、次に差異を比較することです。例:

discrete = numpy.where(raw > numpy.mean(raw), 1, 0) 
errors = np.count_nonzero(filtered != discrete) 
error_rate = errors/len(discrete) 
2

これはあなたの質問の答えではなく、ちょっと参考になるかもしれません。私はコメントにイメージを置くことができないので、私はここにそれを書いています。

何らかの処理の前にデータを何らかの形で正規化する必要があると思います。

0 ... 1の範囲に正規化したら、フィルタを適用する必要があります。

enter image description here

+1

チップをありがとう。しかし、この具体的な例では、信号をブール値に変換しているので、正規化のメリットはわかりません。 – TheMeaningfulEngineer

関連する問題