Saltar al contenido

Remuestrear una matriz numpy

Solución:

NumPy tiene numpy.interp que hace interpolación lineal:

In [1]: numpy.interp(np.arange(0, len(a), 1.5), np.arange(0, len(a)), a)
Out[1]: array([  1. ,   2.5,   4. ,   5.5,   7. ,   8.5,  10. ])

SciPy tiene scipy.interpolate.interp1d que puede hacer una interpolación lineal y más cercana (aunque es posible que el punto más cercano no sea obvio):

In [2]: from scipy.interpolate import interp1d
In [3]: xp = np.arange(0, len(a), 1.5)
In [4]: lin = interp1d(np.arange(len(a)), a)

In [5]: lin(xp)
Out[5]: array([  1. ,   2.5,   4. ,   5.5,   7. ,   8.5,  10. ])

In [6]: nearest = interp1d(np.arange(len(a)), a, kind='nearest')

In [7]: nearest(xp)
Out[7]: array([  1.,   2.,   4.,   5.,   7.,   8.,  10.])

Como scipy.signal.resample puede ser muy lento, busqué otros algoritmos adaptados para audio.

Parece que el SRC de Erik de Castro Lopo (también conocido como Secret Rabbit Code, también conocido como libsamplerate) es uno de los mejores algoritmos de remuestreo disponibles.

  • Es utilizado por scikit’s scikit.samplerate, pero esta biblioteca parece ser complicada de instalar (renuncié a Windows).

  • Afortunadamente, existe un contenedor de Python fácil de usar y de instalar para libsamplerate, realizado por Tino Wagner: https://pypi.org/project/samplerate/. Instalación con pip install samplerate. Uso:

    import samplerate
    from scipy.io import wavfile
    sr, x = wavfile.read('input.wav')  # 48 khz file
    y = samplerate.resample(x, 44100 * 1.0 / 48000, 'sinc_best')  
    

Lectura / comparación interesante de muchas soluciones de remuestreo: http://signalsprocessed.blogspot.com/2016/08/audio-resampling-in-python.html


Apéndice: comparación de espectrogramas de un barrido de frecuencia remuestreado (20 Hz a 20 kHz):

1) Original

2) Remuestreado con libsamplerate / samplerate módulo

3) Remuestreado con numpy.interp (“Interpolación lineal unidimensional”):

Dado que menciona que se trata de datos de un archivo .WAV de audio, puede mirar scipy.signal.resample.

Remuestrear x para num muestras usando el método de Fourier a lo largo del eje dado.

La señal remuestreada comienza en el mismo valor que x pero se muestrea con un espaciado de len(x) / num * (spacing of x). Debido a que se utiliza un método de Fourier, se supone que la señal es periódica.

Tu matriz lineal a no es bueno para probar esto, ya que no es periódico en apariencia. Pero considera sin datos:

x=np.arange(10)
y=np.sin(x)
y1, x1 =signal.resample(y,15,x)  # 10 pts resampled at 15

comparar estos con cualquiera

y1-np.sin(x1) # or
plot(x, y, x1, y1)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *