Formation gratuite Python
le Transformée de Fourier est un puissant outil d'analyse signaux et est utilisé dans tout, du traitement audio à la compression d'image. SciPy fournit une implémentation mature dans son scipy.fft
module, et dans ce didacticiel, vous apprendrez à l'utiliser.
le scipy.fft
module peut sembler intimidant au début car il existe de nombreuses fonctions, souvent avec des noms similaires, et la documentation utilise beaucoup de termes techniques sans explication. La bonne nouvelle est que vous n'avez besoin que de comprendre quelques concepts de base pour commencer à utiliser le module.
Ne vous inquiétez pas si vous n'êtes pas à l'aise avec les mathématiques! Vous aurez une idée de l'algorithme à travers des exemples concrets, et il y aura des liens vers d'autres ressources si vous souhaitez plonger dans les équations. Pour une présentation visuelle du fonctionnement de la transformation de Fourier, vous aimerez peut-être la vidéo de 3Blue1Brown.
Si vous souhaitez conserver un résumé de ce didacticiel une fois la lecture terminée, téléchargez la feuille de triche ci-dessous. Il a des explications sur toutes les fonctions du scipy.fft
module ainsi que le détail des différents types de transformées disponibles:
le scipy.fft
Module
La transformée de Fourier est un outil crucial dans de nombreuses applications, en particulier dans le calcul scientifique et la science des données. En tant que tel, SciPy en a depuis longtemps fourni une implémentation et ses transformations associées. Initialement, SciPy fournissait le scipy.fftpack
module, mais ils ont depuis mis à jour leur implémentation et l'ont déplacée vers le scipy.fft
module.
SciPy regorge de fonctionnalités. Pour une introduction plus générale à la bibliothèque, consultez Scientific Python: Utilisation de SciPy pour l'optimisation.
Installez SciPy et Matplotlib
Avant de pouvoir commencer, vous devez installer SciPy et Matplotlib. Vous pouvez faire celui-ci de deux manières:
-
Installer avec Anaconda: Téléchargez et installez Anaconda Individual Edition. Il est livré avec SciPy et Matplotlib, donc une fois que vous avez suivi les étapes du programme d'installation, vous avez terminé!
-
Installer avec
pépin
: Si vous avez déjàpépin
installé, vous pouvez ensuite installer les bibliothèques avec la commande suivante:
$ python -m pip install -U scipy matplotlib
Vous pouvez vérifier que l'installation a fonctionné en tapant python
dans votre terminal et exécutez le code suivant:
>>> importer scipy, matplotlib
>>> impression(scipy.__fichier__)
/usr/local/lib/python3.6/dist-packages/scipy/__init__.py
>>> impression(matplotlib.__fichier__)
/usr/local/lib/python3.6/dist-packages/matplotlib/__init__.py
Ce code importe SciPy et Matplotlib et imprime l'emplacement des modules. Votre ordinateur affichera probablement des chemins différents, mais tant qu'il imprime un chemin, l'installation a fonctionné.
SciPy est maintenant installé! Il est maintenant temps d’examiner les différences entre scipy.fft
et scipy.fftpack
.
scipy.fft
contre scipy.fftpack
Lorsque vous consultez la documentation SciPy, vous pouvez rencontrer deux modules qui se ressemblent beaucoup:
scipy.fft
scipy.fftpack
le scipy.fft
module est plus récent et doit être préféré à scipy.fftpack
. Vous pouvez en savoir plus sur la modification dans les notes de mise à jour de SciPy 1.4.0, mais voici un bref résumé:
scipy.fft
a une API améliorée.scipy.fft
permet d'utiliser plusieurs travailleurs, ce qui peut augmenter la vitesse dans certaines situations.scipy.fftpack
est considéré comme hérité et SciPy recommande d'utiliserscipy.fft
au lieu.
Sauf si vous avez une bonne raison d'utiliser scipy.fftpack
, tu devrais rester avec scipy.fft
.
scipy.fft
contre numpy.fft
L’implémentation de la transformation de Fourier rapide (FFT) de SciPy contient plus de fonctionnalités et est plus susceptible d’obtenir des corrections de bogues que l’implémentation de NumPy. Si vous avez le choix, vous devez utiliser l'implémentation SciPy.
NumPy maintient une implémentation FFT pour la compatibilité descendante même si les auteurs pensent que des fonctionnalités telles que les transformations de Fourier sont les mieux placées dans SciPy. Consultez la FAQ SciPy pour plus de détails.
La transformée de Fourier
L'analyse de Fourier est un domaine qui étudie comment un fonction mathématique peut être décomposé en une série de fonctions trigonométriques. La transformée de Fourier est un outil de ce champ pour décomposer une fonction en ses fréquences composantes.
D'accord, cette définition est assez dense. Pour les besoins de ce didacticiel, la transformée de Fourier est un outil qui vous permet de prendre un signal et de voir la puissance de chaque fréquence qu'il contient. Jetez un œil aux termes importants de cette phrase:
- UNE signal sont des informations qui changent avec le temps. Par exemple, les traces audio, vidéo et de tension sont tous des exemples de signaux.
- UNE la fréquence est la vitesse à laquelle quelque chose se répète. Par exemple, les horloges tournent à une fréquence d'un hertz (Hz), ou une répétition par seconde.
- Puissance, dans ce cas, signifie simplement la force de chaque fréquence.
L'image suivante est une démonstration visuelle de la fréquence et de la puissance sur certaines ondes sinusoïdales:
Les sommets de la haute fréquence les ondes sinusoïdales sont plus proches que celles de la basse fréquence onde sinusoïdale car ils se répètent plus fréquemment. le batterie faible l'onde sinusoïdale a des pics plus petits que les deux autres ondes sinusoïdales.
Pour rendre cela plus concret, imaginez que vous avez utilisé la transformation de Fourier sur un enregistrement de quelqu'un jouant trois notes sur le piano en même temps. La résultante Spectre de fréquences montrerait trois pics, un pour chacune des notes. Si la personne jouait une note plus doucement que les autres, la puissance de la fréquence de cette note serait inférieure à celle des deux autres.
Voici à quoi ressemblerait cet exemple de piano:
La note la plus élevée du piano a été jouée plus silencieusement que les deux autres notes, de sorte que le spectre de fréquences résultant pour cette note a un pic plus bas.
Pourquoi auriez-vous besoin de la transformée de Fourier?
La transformée de Fourier est utile dans de nombreuses applications. Par exemple, Shazam et d'autres services d'identification musicale utilisent la transformée de Fourier pour identifier les chansons. La compression JPEG utilise une variante de la transformée de Fourier pour supprimer les composants haute fréquence des images. La reconnaissance vocale utilise la transformée de Fourier et les transformations associées pour récupérer les mots prononcés à partir de l'audio brut.
En général, vous avez besoin de la transformée de Fourier si vous avez besoin de regarder les fréquences dans un signal. Si travailler avec un signal dans le domaine temporel est difficile, il vaut la peine d'essayer d'utiliser la transformée de Fourier pour le déplacer dans le domaine fréquentiel. Dans la section suivante, vous examinerez les différences entre les domaines temporel et fréquentiel.
Domaine temporel vs domaine fréquentiel
Tout au long du reste du didacticiel, vous verrez les termes dans le domaine temporel et domaine fréquentiel. Ces deux termes désignent deux manières différentes de regarder un signal, soit comme ses fréquences composantes, soit comme des informations qui varient dans le temps.
Dans le domaine temporel, un signal est une onde dont l'amplitude (axe y) varie dans le temps (axe x). Vous avez probablement l'habitude de voir des graphiques dans le domaine temporel, comme celui-ci:
Ceci est une image de l'audio, qui est un dans le domaine temporel signal. L'axe horizontal représente le temps et l'axe vertical représente l'amplitude.
Dans le domaine fréquentiel, un signal est représenté comme une série de fréquences (axe x) qui ont chacune une puissance associée (axe y). L'image suivante est le signal audio ci-dessus après avoir été transformé de Fourier:
Ici, le signal audio d'avant est représenté par ses fréquences constitutives. Chaque fréquence le long du bas a une puissance associée, produisant le spectre que vous voyez.
Pour plus d'informations sur le domaine de fréquence, consultez l'entrée du glossaire DeepAI.
Types de transformées de Fourier
La transformée de Fourier peut être subdivisée en différents types de transformée. La subdivision la plus élémentaire est basée sur le type de données sur lesquelles opère la transformée: fonctions continues ou fonctions discrètes. Ce tutoriel ne traitera que des transformée de Fourier discrète (DFT).
Vous verrez souvent les termes DFT et FFT utilisés de manière interchangeable, même dans ce didacticiel. Cependant, ce n’est pas tout à fait la même chose. le transformée de Fourier rapide (FFT) est un algorithme de calcul de la transformée de Fourier discrète (DFT), alors que la DFT est la transformée elle-même.
Une autre distinction que vous verrez faite dans le scipy.fft
la bibliothèque est entre différents types d'entrée. fft ()
accepte une entrée de valeur complexe, et rfft ()
accepte une entrée à valeur réelle. Passez directement à la section Utilisation de la transformation de Fourier rapide (FFT) pour une explication des nombres complexes et réels.
Deux autres transformations sont étroitement liées à la DFT: la transformée en cosinus discrète (DCT) et le transformée sinusoïdale discrète (DST). Vous en apprendrez plus sur ceux-ci dans la section Les transformées discrètes en cosinus et sinus.
Exemple pratique: supprimer le bruit indésirable de l'audio
Pour vous aider à mieux comprendre la transformée de Fourier et ce que vous pouvez en faire, vous allez filtrer certains éléments audio. Tout d'abord, vous allez créer un signal audio avec un bourdonnement aigu, puis vous supprimerez le buzz à l'aide de la transformation de Fourier.
Créer un signal
Les ondes sinusoïdales sont parfois appelées tons purs car ils représentent une seule fréquence. Vous utiliserez des ondes sinusoïdales pour générer le son, car elles formeront des pics distincts dans le spectre de fréquences résultant.
Un autre avantage des ondes sinusoïdales est qu'elles sont faciles à générer à l'aide de NumPy. Si vous n'avez jamais utilisé NumPy auparavant, vous pouvez consulter Qu'est-ce que NumPy?
Voici un code qui génère une onde sinusoïdale:
importer engourdi comme np
de matplotlib importer pyplot comme plt
TAUX D'ÉCHANTILLONNAGE = 44100 # Hertz
DURÉE = 5 # Secondes
def generate_sine_wave(fréq, taux d'échantillonnage, durée):
X = np.linspace(0, durée, taux d'échantillonnage*durée, point final=Faux)
fréquences = X * fréq
# 2pi parce que np.sin prend des radians
y = np.péché((2 * np.pi) * fréquences)
revenir X, y
# Génère une onde sinusoïdale de 2 hertz qui dure 5 secondes
X, y = generate_sine_wave(2, TAUX D'ÉCHANTILLONNAGE, DURÉE)
plt.terrain(X, y)
plt.montrer()
Après avoir importé NumPy et Matplotlib, vous définissez deux constantes:
TAUX D'ÉCHANTILLONNAGE
détermine le nombre de points de données que le signal utilise pour représenter l'onde sinusoïdale par seconde. Donc, si le signal avait une fréquence d'échantillonnage de 10 Hz et était une onde sinusoïdale de cinq secondes, alors il aurait10 * 5 = 50
points de données.durée
est la longueur de l'échantillon généré.
Ensuite, vous définissez une fonction pour générer une onde sinusoïdale puisque vous l’utiliserez plusieurs fois plus tard. La fonction prend une fréquence, fréq
, puis renvoie le X
et y
valeurs que vous utiliserez pour tracer la vague.
Les coordonnées x de l'onde sinusoïdale sont régulièrement espacées entre 0
et DURÉE
, donc le code utilise NumPy's linspace ()
pour les générer. Il prend une valeur de début, une valeur de fin et le nombre d'échantillons à générer. Réglage endpoint = Faux
est important pour que la transformée de Fourier fonctionne correctement car elle suppose qu'un signal est périodique.
np.sin ()
calcule les valeurs de la fonction sinus à chacune des coordonnées x. Le résultat est multiplié par la fréquence pour faire osciller l'onde sinusoïdale à cette fréquence, et le produit est multiplié par 2π pour convertir les valeurs d'entrée en radians.
Après avoir défini la fonction, vous l'utilisez pour générer une onde sinusoïdale de deux hertz qui dure cinq secondes et la tracer à l'aide de Matplotlib. Votre tracé sinusoïdal devrait ressembler à ceci:
L'axe des x représente le temps en secondes, et comme il y a deux pics pour chaque seconde de temps, vous pouvez voir que l'onde sinusoïdale oscille deux fois par seconde. Cette onde sinusoïdale est une fréquence trop basse pour être audible, donc dans la section suivante, vous allez générer des ondes sinusoïdales de fréquence plus élevée et vous verrez comment les mélanger.
Mixage des signaux audio
La bonne nouvelle est que le mixage de signaux audio ne se fait qu'en deux étapes:
- Ajouter les signaux ensemble
- Normaliser le résultat
Avant de pouvoir mélanger les signaux ensemble, vous devez les générer:
_, nice_tone = generate_sine_wave(400, TAUX D'ÉCHANTILLONNAGE, DURÉE)
_, noise_tone = generate_sine_wave(4000, TAUX D'ÉCHANTILLONNAGE, DURÉE)
noise_tone = noise_tone * 0,3
mixed_tone = nice_tone + noise_tone
Il n'y a rien de nouveau dans cet exemple de code. Il génère une tonalité moyenne et une tonalité aiguë assignées aux variables nice_tone
et noise_tone
, respectivement. Vous utiliserez le son aigu comme bruit indésirable, il sera donc multiplié par 0,3
pour réduire sa puissance. Le code ajoute ensuite ces tonalités ensemble. Notez que vous utilisez le trait de soulignement (_
) pour supprimer le X
valeurs renvoyées par generate_sine_wave ()
.
La prochaine étape est normalisation, ou mise à l'échelle du signal pour l'adapter au format cible. En raison de la façon dont vous stockerez l'audio ultérieurement, votre format cible est un entier 16 bits, compris entre -32768 et 32767:
normalized_tone = np.int16((mixed_tone / mixed_tone.max()) * 32767)
plt.terrain(normalized_tone[:[:[:[:1000])
plt.montrer()
Ici, le code évolue mixed_tone
pour l'adapter parfaitement à un entier 16 bits, puis le convertir en ce type de données à l'aide de NumPy's np.int16
. Partage mixed_tone
par sa valeur maximale le met à l'échelle entre -1
et 1
. Lorsque ce signal est multiplié par 32767
, il est mis à l'échelle entre -32767
et 32767
, qui est à peu près la plage de np.int16
. Le code trace uniquement le premier 1000
échantillons afin que vous puissiez voir la structure du signal plus clairement.
Votre intrigue devrait ressembler à ceci:
Le signal ressemble à une onde sinusoïdale déformée. L'onde sinusoïdale que vous voyez est la tonalité de 400 Hz que vous avez générée et la distorsion est la tonalité de 4 000 Hz. Si vous regardez de près, vous pouvez voir que la distorsion a la forme d'une onde sinusoïdale.
Pour écouter l'audio, vous devez le stocker dans un format lisible par un lecteur audio. Le moyen le plus simple de le faire est d’utiliser la méthode wavfile.write de SciPy pour le stocker dans un fichier WAV. Les entiers 16 bits sont un type de données standard pour les fichiers WAV. Vous allez donc normaliser votre signal en entiers 16 bits:
de scipy.io.wavfile importer écrire
# Souvenez-vous que sample_rate = 44100 Hz est notre taux de lecture
écrire("mysinewave.wav", taux d'échantillonnage, normalized_tone)
Ce code écrira dans un fichier mysinewave.wav
dans le répertoire où vous exécutez votre script Python. Vous pouvez ensuite écouter ce fichier en utilisant n'importe quel lecteur audio ou même avec Python. Vous entendrez une tonalité plus basse et une tonalité plus aiguë. Ce sont les ondes sinusoïdales de 400 Hz et 4000 Hz que vous avez mixées.
Une fois cette étape terminée, votre échantillon audio est prêt. La prochaine étape consiste à supprimer le son aigu à l'aide de la transformée de Fourier!
Utilisation de la transformation de Fourier rapide (FFT)
Il est temps d’utiliser la FFT sur l’audio généré. La FFT est un algorithme qui implémente la transformée de Fourier et peut calculer un spectre de fréquences pour un signal dans le domaine temporel, comme votre audio:
de scipy.fft importer fft, fftfreq
# Nombre d'échantillons dans normalized_tone
N = taux d'échantillonnage * durée
yf = fft(normalized_tone)
xf = fftfreq(N, 1 / TAUX D'ÉCHANTILLONNAGE)
plt.terrain(xf, np.abdos(yf))
plt.montrer()
Ce code calculera la transformée de Fourier de votre audio généré et le tracera. Avant de le décomposer, jetez un œil à l'intrigue qu'il produit:
Vous pouvez voir deux pics dans les fréquences positives et des miroirs de ces pics dans les fréquences négatives. Les pics de fréquence positive sont à 400 Hz et 4000 Hz, ce qui correspond aux fréquences que vous mettez dans l'audio.
La transformée de Fourier a pris votre signal compliqué et bancal et l'a transformé uniquement en fréquences qu'il contient. Puisque vous n'introduisez que deux fréquences, seules deux fréquences sont sorties. La symétrie négative-positive est un effet secondaire de la mise entrée à valeur réelle dans la transformée de Fourier, mais vous en saurez plus plus tard.
Dans les premières lignes, vous importez les fonctions de scipy.fft
que vous utiliserez plus tard et définirez une variable, N
, qui stocke le nombre total d'échantillons dans le signal.
Après cela vient la section la plus importante, le calcul de la transformée de Fourier:
yf = fft(normalized_tone)
xf = fftfreq(N, 1 / taux d'échantillonnage)
Le code appelle deux fonctions très importantes:
-
fft ()
calcule la transformation elle-même. -
fftfreq ()
calcule les fréquences au centre de chaque poubelle dans la sortie defft ()
. Sans cela, il n'y aurait aucun moyen de tracer l'axe des x sur votre spectre de fréquences.
UNE poubelle est une plage de valeurs qui ont été regroupées, comme dans un histogramme. Pour plus d'informations sur bacs, consultez cette question sur l'échange de pile de traitement du signal. Pour les besoins de ce didacticiel, vous pouvez les considérer comme des valeurs uniques.
Une fois que vous avez les valeurs résultantes de la transformée de Fourier et leurs fréquences correspondantes, vous pouvez les tracer:
plt.terrain(xf, np.abdos(yf))
plt.montrer()
La partie intéressante de ce code est le traitement que vous faites pour yf
avant de le tracer. Tu appelles np.abs ()
sur yf
parce que ses valeurs sont complexe.
UNE nombre complexe est un nombre en deux parties, un réel partie et un imaginaire partie. Il existe de nombreuses raisons pour lesquelles il est utile de définir des nombres comme celui-ci, mais tout ce que vous devez savoir pour le moment, c'est qu'ils existent.
Les mathématiciens écrivent généralement des nombres complexes sous la forme une + bi, où une est la vraie partie et b est la partie imaginaire. le je après b signifie que b est un nombre imaginaire.
Remarque: Parfois, vous verrez des nombres complexes écrits en utilisant je, et parfois vous les verrez écrits en utilisant j, comme 2 + 3je et 2 + 3j. Les deux sont les mêmes, mais je est davantage utilisé par les mathématiciens, et j plus par des ingénieurs.
Pour en savoir plus sur les nombres complexes, consultez le cours de la Khan Academy ou la page Maths is Fun.
Étant donné que les nombres complexes comportent deux parties, les représenter graphiquement par rapport à la fréquence sur un axe bidimensionnel vous oblige à calculer une valeur unique à partir d'eux. C'est ici que np.abs ()
entre. Il calcule √ (a² + b²) pour les nombres complexes, qui est une grandeur globale pour les deux nombres ensemble et surtout une valeur unique.
Remarque: En passant, vous avez peut-être remarqué que fft ()
renvoie une fréquence maximale d'un peu plus de 20 000 Hertz, 22050 Hz, pour être exact. Cette valeur est exactement la moitié de notre taux d'échantillonnage et est appelée fréquence de Nyquist.
C'est un concept fondamental dans le traitement du signal et signifie que votre fréquence d'échantillonnage doit être au moins deux fois la fréquence la plus élevée de votre signal.
Rendre les choses plus rapides avec rfft ()
Le spectre de fréquences qui fft ()
sortie était réfléchie autour de l'axe y de sorte que la moitié négative était un miroir de la moitié positive. Cette symétrie a été causée par l'entrée nombres réels (pas de nombres complexes) à la transformation.
Vous pouvez utiliser cette symétrie pour accélérer votre transformée de Fourier en n'en calculant que la moitié. scipy.fft
met en œuvre ce speed hack sous la forme de rfft ()
.
La grande chose à propos de rfft ()
est qu’il s’agit d’une solution de remplacement pour fft ()
. Rappelez-vous le code FFT d'avant:
yf = fft(normalized_tone)
xf = fftfreq(N, 1 / TAUX D'ÉCHANTILLONNAGE)
Échange rfft ()
, le code reste à peu près le même, juste avec quelques changements clés:
de scipy.fft importer rfft, rfftfreq
yf = rfft(normalized_tone)
# Notez le 'r' supplémentaire à l'avant
xf = rfftfreq(N, 1 / TAUX D'ÉCHANTILLONNAGE)
plt.terrain(xf, np.abdos(yf))
plt.montrer()
Depuis rfft ()
renvoie seulement la moitié de la sortie qui fft ()
fait, il utilise une fonction différente pour obtenir le mappage de fréquence, rfftfreq ()
au lieu de fftfreq ()
.
rfft ()
produit toujours une sortie complexe, de sorte que le code pour tracer son résultat reste le même. Le tracé, cependant, devrait ressembler à ce qui suit puisque les fréquences négatives auront disparu:
Vous pouvez voir que l'image ci-dessus n'est que le côté positif du spectre de fréquences qui fft ()
produit. rfft ()
ne calcule jamais la moitié négative du spectre de fréquences, ce qui le rend plus rapide que d'utiliser fft ()
.
En utilisant rfft ()
peut être jusqu'à deux fois plus rapide que d'utiliser fft ()
, mais certaines longueurs d'entrée sont plus rapides que d'autres. Si vous savez que vous ne travaillerez qu'avec des nombres réels, alors c'est un speed hack qui vaut la peine d'être connu.
Maintenant que vous disposez du spectre de fréquences du signal, vous pouvez passer au filtrage.
Filtrer le signal
L’un des avantages de la transformée de Fourier est qu’elle est réversible, de sorte que toute modification apportée au signal dans le domaine fréquentiel s’appliquera lorsque vous le transformerez de nouveau dans le domaine temporel. Vous en profiterez pour filtrer votre audio et vous débarrasser des fréquences aiguës.
Attention: La technique de filtrage présentée dans cette section ne convient pas aux signaux du monde réel. Consultez la section Éviter les pièges du filtrage pour en savoir plus.
Les valeurs renvoyées par rfft ()
représentent la puissance de chaque tranche de fréquence. Si vous définissez la puissance d'un bac donné sur zéro, les fréquences de ce bac ne seront plus présentes dans le signal de domaine temporel résultant.
En utilisant la longueur de xf
, la fréquence maximale et le fait que les intervalles de fréquences sont régulièrement espacés, vous pouvez calculer l’indice de la fréquence cible:
# La fréquence maximale est la moitié de la fréquence d'échantillonnage
points_per_freq = len(xf) / (TAUX D'ÉCHANTILLONNAGE / 2)
# Notre fréquence cible est de 4000 Hz
target_idx = int(points_per_freq * 4000)
Vous pouvez ensuite définir yf
à 0
à des indices autour de la fréquence cible pour s'en débarrasser:
yf[[[[target_idx - 1 : target_idx + 2] = 0
plt.terrain(xf, np.abdos(yf))
plt.montrer()
Votre code doit produire le tracé suivant:
Puisqu'il n'y a qu'un seul pic, il semble que cela a fonctionné! Ensuite, vous appliquerez la transformée de Fourier inverse pour revenir au domaine temporel.
Application de la FFT inverse
L'application de la FFT inverse est similaire à l'application de la FFT:
de scipy.fft importer irfft
new_sig = irfft(yf)
plt.terrain(new_sig[:[:[:[:1000])
plt.montrer()
Puisque vous utilisez rfft ()
, vous devez utiliser irfft ()
pour appliquer l'inverse. Cependant, si vous aviez utilisé fft ()
, alors la fonction inverse aurait été ifft ()
. Votre intrigue devrait maintenant ressembler à ceci:
Comme vous pouvez le voir, vous avez maintenant une seule onde sinusoïdale oscillant à 400 Hz et vous avez réussi à éliminer le bruit de 4000 Hz.
Une fois encore, vous devez normaliser le signal avant de l'écrire dans un fichier. Vous pouvez le faire de la même manière que la dernière fois:
norm_new_sig = np.int16(new_sig * (32767 / new_sig.max()))
écrire("clean.wav", taux d'échantillonnage, norm_new_sig)
Lorsque vous écoutez ce fichier, vous entendrez que le bruit ennuyeux a disparu!
Éviter les pièges du filtrage
L'exemple ci-dessus est plus à des fins éducatives que pour une utilisation dans le monde réel. La réplication du processus sur un signal du monde réel, tel qu'un morceau de musique, pourrait introduire plus de buzz qu'elle n'en supprime.
Dans le monde réel, vous devez filtrer les signaux à l'aide des fonctions de conception de filtre du scipy.signal
paquet. Le filtrage est un sujet complexe qui implique beaucoup de mathématiques. Pour une bonne introduction, consultez le Guide du scientifique et de l’ingénieur sur le traitement numérique du signal.
Les transformées discrètes en cosinus et sinus
Un tutoriel sur le scipy.fft
module ne serait pas complet sans examiner la transformée en cosinus discrète (DCT) et la transformée en sinus discrète (DST). Ces deux transformées sont étroitement liées à la transformée de Fourier mais fonctionnent entièrement sur des nombres réels. Cela signifie qu'ils prennent une fonction à valeur réelle comme entrée et produisent une autre fonction à valeur réelle comme sortie.
SciPy met en œuvre ces transformations comme dct ()
et dst ()
. le je*
et * n
les variantes sont l'inverse et n-Version dimensionnelle des fonctions, respectivement.
Le DCT et le DST sont un peu comme deux moitiés qui composent ensemble la transformée de Fourier. Ce n’est pas tout à fait vrai car le calcul est beaucoup plus compliqué, mais c’est un modèle mental utile.
Donc, si le DCT et le DST sont comme les moitiés d'une transformée de Fourier, alors pourquoi sont-ils utiles?
D'une part, ils sont plus rapides qu'une transformation de Fourier complète car ils font effectivement la moitié du travail. Ils peuvent être encore plus rapides que rfft ()
. En plus de cela, ils fonctionnent entièrement en nombres réels, vous n'avez donc jamais à vous soucier des nombres complexes.
Avant de pouvoir apprendre à choisir entre eux, vous devez comprendre les fonctions paires et impaires. Même fonctions sont symétriques par rapport à l'axe y, alors que fonctions impaires sont symétriques par rapport à l'origine. Pour imaginer cela visuellement, jetez un œil aux schémas suivants:
Vous pouvez voir que la fonction paire est symétrique par rapport à l'axe y. La fonction impaire est symétrique sur y = –X, qui est décrit comme étant symétrique par rapport à l'origine.
Lorsque vous calculez une transformée de Fourier, vous prétendez que la fonction sur laquelle vous la calculez est infinie. La transformée de Fourier complète (DFT) suppose que la fonction d'entrée se répète indéfiniment. Cependant, le DCT et le DST supposent que la fonction est étendue par symétrie. Le DCT suppose que la fonction est étendue avec une symétrie paire, et le DST suppose qu'elle est étendue avec une symétrie impaire.
L'image suivante illustre comment chaque transformation imagine que la fonction s'étend à l'infini:
Dans l'image ci-dessus, le DFT répète la fonction telle quelle. Le DCT reflète la fonction verticalement pour l'étendre, et le DST la reflète horizontalement.
Notez que la symétrie impliquée par le DST conduit à de grands sauts dans la fonction. Ceux-ci sont appelés discontinuités et produire plus de composants haute fréquence dans le spectre de fréquences résultant. Donc, à moins que vous ne sachiez que vos données ont une symétrie étrange, vous devriez utiliser le DCT au lieu du DST.
Le DCT est très couramment utilisé. Il existe de nombreux autres exemples, mais les normes JPEG, MP3 et WebM utilisent toutes le DCT.
Conclusion
La transformée de Fourier est un concept puissant qui est utilisé dans une variété de domaines, des mathématiques pures à l'ingénierie audio et même à la finance. Vous connaissez maintenant le transformée de Fourier discrète et sont bien équipés pour l'appliquer aux problèmes de filtrage en utilisant le scipy.fft
module.
Dans ce didacticiel, vous avez appris:
- Comment et quand utiliser le Transformée de Fourier
- Comment sélectionner la fonction correcte dans
scipy.fft
pour votre cas d'utilisation - Quelles sont les différences entre les dans le domaine temporel et le domaine fréquentiel
- Comment afficher et modifier le Spectre de fréquences d'un signal
- Comment utiliser
rfft ()
peut accélérer votre code
Dans la dernière section, vous avez également découvert les transformée en cosinus discrète et le transformée sinusoïdale discrète. Vous avez vu quelles fonctions appeler pour les utiliser et vous avez appris à utiliser l'une par rapport à l'autre.
Si vous souhaitez un résumé de ce didacticiel, vous pouvez télécharger la feuille de triche ci-dessous. Il a des explications sur toutes les fonctions du scipy.fft
module ainsi que le détail des différents types de transformées disponibles:
Continuez à explorer ce sujet fascinant et à expérimenter des transformations, et assurez-vous de partager vos découvertes dans les commentaires ci-dessous!
[ad_2]