How to find zero crossings with hysteresis?

前端 未结 2 1918
半阙折子戏
半阙折子戏 2020-12-09 05:42

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. T

2条回答
  •  南笙
    南笙 (楼主)
    2020-12-09 06:20

    Modifications I had to do for my work, all based on the answer above by Bas Swinckels, to permit detection of threshold-crossing when using standard as well as reversed thresholds.

    I'm not happy with the naming tough, maybe it should now read th_hi2lo and th_lo2hi instead of th_lo and th_hi? Using the original values, the behaviour ist the same tough.

    def hyst(x, th_lo, th_hi, initial = False):
        """
        x : Numpy Array
            Series to apply hysteresis to.
        th_lo : float or int
            Below this threshold the value of hyst will be False (0).
        th_hi : float or int
            Above this threshold the value of hyst will be True (1).
        """        
    
        if th_lo > th_hi: # If thresholds are reversed, x must be reversed as well
            x = x[::-1]
            th_lo, th_hi = th_hi, th_lo
            rev = True
        else:
            rev = False
    
        hi = x >= th_hi
        lo_or_hi = (x <= th_lo) | hi
    
        ind = np.nonzero(lo_or_hi)[0]  # Index für alle darunter oder darüber
        if not ind.size:  # prevent index error if ind is empty
            x_hyst = np.zeros_like(x, dtype=bool) | initial
        else:
            cnt = np.cumsum(lo_or_hi)  # from 0 to len(x)
            x_hyst = np.where(cnt, hi[ind[cnt-1]], initial)
    
        if rev:
            x_hyst = x_hyst[::-1]
    
        return x_hyst
    

    And as above a test of the code to see what it does:

    x = np.linspace(0,20, 1000)
    y = np.sin(x)
    h1 = hyst(y, -0.2, 0.2)
    h2 = hyst(y, +0.5, -0.5)
    plt.plot(x, y, x, -0.2 + h1*0.4, x, -0.5 + h2)
    plt.legend(('input', 'output, classic, hyst(y, -0.2, +0.2)', 
                'output, reversed, hyst(y, +0.5, -0.5)'))
    plt.title('Thresholding with hysteresis')
    plt.show()
    

提交回复
热议问题