Sottocampionare un segnale con decimale


12

Sto sperimentando la decimazione di un segnale, in questo caso un impulso unitario.

Sto usando Python, con pylab. Innanzitutto, creo un impulso unitario e lo decimo di 5.

x = r_[zeros(0), 1, zeros(100)]
N = 2 ** 14
q = 5

y = decimate(x, q, ftype="fir")
subplot(211)
title("Original")
stem(range(len(x)), x)
subplot(212)
title("Decimated - FIR")
stem(range(len(y)), y)

figure()
subplot(211)
semilogx(log(abs(fft(x, N))))
subplot(212)
y = decimate(x, q, ftype="fir")
semilogx(log(abs(fft(y, N))))

Ciò risulta con i seguenti grafici

Impulso dell'unità con ritardo zero e il segnale decimato risultante

Aggiungo quindi alcuni esempi di ritardo prima dell'impulso, modificando x in:

x = r_[zeros(3), 1, zeros(100)]

Ciò si traduce nei seguenti grafici

Impulso unitario con ritardo di 3 campioni e il segnale decimato risultante

Nella seconda serie di grafici, il segnale decimato risultante non è più un singolo campione, ma è stato distorto.

Se ritardo il segnale con 5 - e qualsiasi multiplo di q - campioni, ottengo nuovamente il primo set di grafici.

Il codice sorgente per la funzione decimale è, https://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L1570

def decimate(x, q, n=None, ftype='iir', axis=-1):
    if not isinstance(q, int):
        raise TypeError("q must be an integer")

    if n is None:
        if ftype == 'fir':
            n = 30
        else:
            n = 8

    if ftype == 'fir':
        b = firwin(n + 1, 1. / q, window='hamming')
        a = 1.
    else:
        b, a = cheby1(n, 0.05, 0.8 / q)

    y = lfilter(b, a, x, axis=axis)

    sl = [slice(None)] * y.ndim
    sl[axis] = slice(None, None, q)
    return y[sl]

Sto usando un filtro passa basso abete prima di decimare, la risposta all'impulso del filtro è

risposta all'impulso del filtro passa basso

Questo spiega perché l'impulso è distorto quando c'è un ritardo, la decimazione sta selezionando parti della risposta all'impulso, quando il ritardo è un multiplo della decimazione, seleziona solo gli zero della risposta all'impulso e un campione diverso da zero a il picco.

C'è un modo per decimare un campione di unità con un ritardo arbitrario, che si traduce in un output di campione di unità in scala?


Capisci che l'impulso del "singolo campione" in realtà rappresenta una funzione sincera, giusto? Perché devi filtrare l'anti-alias prima del campionamento e la tua funzione di impulso matematico ideale cambia in una funzione sincera quando viene filtrata. Accade semplicemente che i campioni cadano esattamente sugli zeri del sinc, quindi non sembra, ma se i sinc fossero spostati di meno di un campione nel tempo, lo vedresti.
endolito il

Risposte:


11

x[n]

x[n]=δ[n]

h[n]

xf[n]=x[n]h[n]=δ[n]h[n]=h[n]

q5

xd[n]=xf[qn]=h[qn]

qq2qnq0xd[n]n=0

x[n]

xf[n]=h[nD]

xd[n]=xf[qn]=h[qnD]

Ancora una volta, come hai notato, questo ha l'effetto di strappare un diverso set di tocchi dalla risposta del filtro, in modo tale che il segnale di uscita decimato non sia più zero per tutti ma un campione (cioè non sembra più un impulso ). Questo è prevedibile. Perché?

xd[n]

xd[n]=h[qnD]ejωDH(ωq)

H(ω)xd[n]

Poiché il filtro è la fonte della "distorsione" che non si desidera, è possibile provare a ripetere il processo senza un filtro. Ma considera cosa otterresti allora:

xf[n]=x[n]=δ[nD]

xd[n]=xf[qn]=δ[qnD]

qDxd[n]=0  n

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.