2014-01-26 23 views
5

Mein Ziel ist es, eine Grafik mit den räumlichen Frequenzen eines Bildes zu erhalten - so wie man eine Fourier-Transformation darauf macht. Ich interessiere mich nicht für die Position auf dem Bild von Merkmalen mit der Frequenz f (zum Beispiel); Ich möchte nur eine Grafik, die mir sagt, wie viel von jeder Frequenz ich habe (die Amplitude für ein Frequenzband könnte durch die Summe der Kontraste mit dieser Frequenz dargestellt werden).Interpretieren numpy.fft.fft2 output

Ich versuche, dies über die numpy.fft.fft2 Funktion zu tun.

Hier ist ein Link zu einer minimal example porträtiert meine Anwendungsfall.

Wie sich herausstellt, bekomme ich nur deutlich größere Werte für frequencies[:30,:30], und von diesen ist der absolut höchste Wert frequencies[0,0]. Wie kann ich das interpretieren?

  • Wofür steht die Amplitude jedes Werts genau?
  • Was bedeutet es, dass mein höchster Wert in frequency[0,0] ist Was ist eine 0 Hz Frequenz?
  • Kann ich die Werte irgendwie bin, so dass mein Frequenzspektrum orientierungsunabhängig ist?
+1

Diese Frage scheint off-topic zu sein, weil es darum geht zu verstehen, was eine Fourier-Transformation tut (versuchen Sie http://dsp.stackexchange.com). –

+0

Ich verstehe, was ein fft im Prinzip macht, ich bekomme einfach nicht die 'numpy.fft.fft2' Ausgabe, ich hätte ein 1D Array ohne" Null "Frequenzband erwartet. – TheChymera

Antwort

9

freq hat ein paar sehr große Werte und viele kleine Werte. Sie können sehen, dass durch

plt.hist(freq.ravel(), bins=100) 

(siehe unten). Plotten Wenn Sie also

ax1.imshow(freq, interpolation="none") 

Matplotlib verwendet freq.min() als der niedrigste Wert im Farbbereich verwenden (was standardmäßig blau gefärbt wurde), und freq.max() als den höchsten Wert im Farbbereich (der standardmäßig rot markiert ist). Da fast alle Werte in freq in der Nähe des blauen Endes liegen, sieht die gesamte Darstellung blau aus.

Sie können ein aussagekräftigeres Diagramm erstellen, indem Sie die Werte in freq so skalieren, dass die niedrigen Werte im Farbbereich weiter verbreitet sind.

Zum Beispiel können Sie eine bessere Verteilung der Werte erhalten, indem Sie die log von freq nehmen. (Sie wollen wahrscheinlich nicht die höchsten Werte wegzuwerfen, da sie sich auf Frequenzen mit der höchsten Leistung entsprechen.)

import matplotlib as ml 
import matplotlib.pyplot as plt 
import numpy as np 
import Image 
file_path = "data" 
image = np.asarray(Image.open(file_path).convert('L')) 
freq = np.fft.fft2(image) 
freq = np.abs(freq) 

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(14, 6)) 
ax[0,0].hist(freq.ravel(), bins=100) 
ax[0,0].set_title('hist(freq)') 
ax[0,1].hist(np.log(freq).ravel(), bins=100) 
ax[0,1].set_title('hist(log(freq))') 
ax[1,0].imshow(np.log(freq), interpolation="none") 
ax[1,0].set_title('log(freq)') 
ax[1,1].imshow(image, interpolation="none") 
plt.show() 

enter image description here


Von the docs:

Die Ausgabe, analog zu fft, enthält den Begriff für Nullfrequenz in der unteren Ecke der transformierten Achsen,

Somit ist freq[0,0] der Begriff "Nullfrequenz". Mit anderen Worten, es ist der konstante Term in der discrete Fourier Transform.

+0

'freq.ravel()' entwirrt das 2D-Array in ein 1D-Array, wobei jede Zeile nacheinander gelesen wird - richtig? Wie kommt es, dass ich keinen zweiten Peak bei 200, einen dritten bei 400 usw. bekomme (wie der log (freq) Plot anzeigen würde)? Warum stoppt hist (log (freq)) bei 16 auf der x-Achse? – TheChymera

+3

'plt.hist' erstellt ein Histogramm der Werte. Die "x-Achse" repräsentiert Werte von "log (freq)" und die "y-Achse" repräsentiert eine Zählung, wie oft diese Werte auftreten. Es gibt keine sich wiederholenden Peaks, da ähnliche Werte zusammen gruppiert werden. Der obere Wert von "16" bedeutet, dass der größte Wert in "log (freq)" nahe 16 ist. Tatsächlich ist "np.log (freq.max())" gleich 14,8. – unutbu

+0

(Und ja, 'freq.ravel()' ist eine 1D-Ansicht des 2D-Arrays.) – unutbu