如何找到具有滞后的零交叉? [英] How to find zero crossings with hysteresis?

查看:86
本文介绍了如何找到具有滞后的零交叉?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在numpy中,我想检测信号从某个阈值以下(以前)到某个其他阈值以上的交叉点。这是为了消除抖动或在有噪声的情况下精确过零等。

In numpy, I would like to detect the points at which the signal crosses from (having been previously) below a certain threshold, to being above a certain other threshold. This is for things like debouncing, or accurate zero crossings in the presence of noise, etc.

就像这样:

import numpy

# set up little test problem
N = 1000
values = numpy.sin(numpy.linspace(0, 20, N))
values += 0.4 * numpy.random.random(N) - 0.2
v_high = 0.3
v_low = -0.3

# find transitions from below v_low to above v_high    
transitions = numpy.zeros_like(values, dtype=numpy.bool)

state = "high"

for i in range(N):
    if values[i] > v_high:
        # previous state was low, this is a low-to-high transition
        if state == "low":
            transitions[i] = True
        state = "high"
    if values[i] < v_low:
        state = "low"

我想要一种不循环的方法显式地遍历数组:但是我想不出任何办法,因为每个状态值都取决于先前的状态。

I would like a way to do this without looping over the array explicitly: but I can't think of any way, since each state value depends on the previous state. Is it possible to do without a loop?

推荐答案

可以这样做:

def hyst(x, th_lo, th_hi, initial = False):
    hi = x >= th_hi
    lo_or_hi = (x <= th_lo) | hi
    ind = np.nonzero(lo_or_hi)[0]
    if not ind.size: # prevent index error if ind is empty
        return np.zeros_like(x, dtype=bool) | initial
    cnt = np.cumsum(lo_or_hi) # from 0 to len(x)
    return np.where(cnt, hi[ind[cnt-1]], initial)

说明: ind 是信号所在的所有样本的索引低于下限阈值或上限阈值之上,因此开关的位置已明确定义。使用总和,您可以进行某种计数,以指向最后定义明确的样本的索引。如果输入向量的起点在两个阈值之间,则 cnt 将为0,因此您需要使用<$ c $将相应的输出设置为初始值。 c> where 函数。

Explanation: ind are the indices of all the samples where the signal is below the lower or above the upper threshold, and for which the position of the 'switch' is thus well-defined. With cumsum, you make some sort of counter which points to the index of the last well-defined sample. If the start of the input vector is between the two thresholds, cnt will be 0, so you need to set the the corresponding output to the initial value using the where function.

信用:这是我在旧帖子在某些Matlab论坛上,我翻译成Numpy。该代码有点难以理解,还需要分配各种中间数组。如果Numpy包含一个类似于您的简单for循环的专用功能会更好,但是为了提高速度而在C中实现。

Credit: this is a trick I found in an old post on some Matlab forum, which I translated to Numpy. This code is a bit hard to understand and also needs to allocate various intermediate arrays. It would be better if Numpy would include a dedicated function, similar to your simple for-loop, but implemented in C for speed.

快速测试:

x = np.linspace(0,20, 1000)
y = np.sin(x)
h1 = hyst(y, -0.5, 0.5)
h2 = hyst(y, -0.5, 0.5, True)
plt.plot(x, y, x, -0.5 + h1, x, -0.5 + h2)
plt.legend(('input', 'output, start=0', 'output, start=1'))
plt.title('Thresholding with hysteresis')
plt.show()

结果:

这篇关于如何找到具有滞后的零交叉?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆