FFT çıktısını anlama


88

DFT / FFT hesaplamasının çıktısını anlamak için biraz yardıma ihtiyacım var.

Deneyimli bir yazılım mühendisiyim ve ana frekansları bulmak gibi bazı akıllı telefon ivme ölçer okumalarını yorumlamam gerekiyor. Ne yazık ki, on beş yıl önce kolej EE derslerimin çoğunda uyudum, ancak son birkaç gündür DFT ve FFT'yi okuyorum (görünüşe göre çok az boşuna).

Lütfen, "gidip bir EE dersi al" yanıtını vermeyin. Aslında işverenim bana ödeme yaparsa bunu yapmayı planlıyorum. :)

İşte benim sorunum:

32 Hz'de bir sinyal yakaladım. İşte Excel'de grafiğini çizdiğim 1 saniyelik 32 nokta örneği.

görüntü açıklamasını buraya girin

Daha sonra Columbia Üniversitesi'nden Java ile yazılmış bir FFT kodu aldım (" Java'da güvenilir ve hızlı FFT " konulu bir gönderideki önerileri izledikten sonra ).

Bu programın çıktısı aşağıdaki gibidir. Yerinde bir FFT çalıştırdığına inanıyorum, bu nedenle hem giriş hem de çıkış için aynı tamponu yeniden kullanıyor.

Before: 

Re: [0.887  1.645  2.005  1.069  1.069  0.69  1.046  1.847  0.808  0.617  0.792  1.384  1.782  0.925  0.751  0.858  0.915  1.006  0.985  0.97  1.075  1.183  1.408  1.575  1.556  1.282  1.06  1.061  1.283  1.701  1.101  0.702  ]

Im: [0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ]

After: 

Re: [37.054  1.774  -1.075  1.451  -0.653  -0.253  -1.686  -3.602  0.226  0.374  -0.194  -0.312  -1.432  0.429  0.709  -0.085  0.0090  -0.085  0.709  0.429  -1.432  -0.312  -0.194  0.374  0.226  -3.602  -1.686  -0.253  -0.653  1.451  -1.075  1.774  ]

Im: [0.0  1.474  -0.238  -2.026  -0.22  -0.24  -5.009  -1.398  0.416  -1.251  -0.708  -0.713  0.851  1.882  0.379  0.021  0.0  -0.021  -0.379  -1.882  -0.851  0.713  0.708  1.251  -0.416  1.398  5.009  0.24  0.22  2.026  0.238  -1.474  ]

Yani, bu noktada, çıktının tura veya kuyruklarını yapamıyorum. Gerçek bölümün bileşen kosinüs dalgalarının genlikleri ve hayali bölümün bileşen sinüs dalgalarının genlikleri olması gibi DFT kavramlarını anlıyorum. Bu diyagramı harika " The Scientist and Engineer's Guide to Digital Signal Processing " kitabından da takip edebilirim : görüntü açıklamasını buraya girin

Yani benim spesifik sorularım:

  1. FFT'nin çıkışından "en çok meydana gelen frekansları" nasıl bulurum? Bu, ivmeölçer verilerimin analizinin bir parçası. Gerçek (kosinüs) veya hayali (sinüs) dizileri okumalı mıyım?

  2. Zaman alanında 32 noktalı bir girdim var. FFT'nin çıktısı, gerçekler için 16 öğeli bir dizi ve sanal için 16 öğeli bir dizi olması gerekmez mi? Program neden bana hem gerçek hem de sanal dizi çıktılarını 32 boyutunda veriyor?

  3. Önceki soruyla ilgili olarak, çıktı dizilerindeki dizinleri nasıl ayrıştırırım? 32 Hz'de örneklenmiş 32 örnek girdim göz önüne alındığında, benim anladığım kadarıyla 16 öğeli bir dizi çıktısının indeksi, örnekleme hızının 1 / 2'sine (32 Hz) kadar eşit olarak yayılmalıdır, bu nedenle her bir öğeyi anlamakta haklı mıyım? dizinin değeri (32 Hz * 1/2) / 16 = 1 Hz?

  4. FFT çıktısının neden negatif değerleri var? Değerlerin bir sinüzoidin genliklerini temsil ettiğini sanıyordum. Örneğin, Real [3] = -1.075 çıkışı, frekans 3'ün kosinüs dalgası için -1.075'lik bir genlik anlamına gelmelidir. Bu doğru mu? Bir genlik nasıl negatif olabilir?


İvmeölçer okumalarından ne hesaplamak istersiniz: hız, mesafe? İvmeölçer okumalarının gürültüsü Gauss dağılımını takip ediyor ve bir sinüs dalgasının buna nasıl çare bulacağını göremiyorum.
Ali

2
java etiketi, belirli bir dilden daha genel olduğu için kaldırılmalıdır
user3791372

Columbia Üniversitesi'nin kaynağına bakıldığında, hiç verimli değil. Bir sade, kelebeğin referans tabloları içeren Cooley-Tucky ait optimize edilmemiş uygulanması, ve bit ters yerine mevcut kütüphane fonksiyonlarını kullanarak elle yapılır
Mark JERONIMUS

@MarkJeronimus: Java'da verimli bir FFT uygulaması önerebilir misiniz? Doğru hatırlıyorsam, Columbia Üniversitesi koduyla gitmemin nedeni, FFTW kitaplığının bir Android akıllı telefonda çalıştırılamayacak kadar karmaşık olmasıydı.
stackoverflowuser2010

Bazı dağınık 'optimize edilmiş' uygulamalar buldum, ancak bunlar temelde N boyutu başına bir algoritmadır , bu nedenle bir boyut aralığına ihtiyacınız varsa tüm bu rutinlere ihtiyacınız vardır. Pratikte esas olarak Intel Entegre Performans İlkellerini kullandım (evet, Java'dan JNA aracılığıyla), ancak bu ücretsiz değil. Evde, temelde bağladığınız algoritmanın aynısını kullanıyorum, ancak 2005'te bir ders kitabı kullanarak sıfırdan yazdım. Sadece FFT (Hızlı Fourier Dönüşümü), 'Hızlı FFT' adını haklı çıkarmak için bu kadar 'Hızlı' hiçbir şey yok.
Mark Jeronimus

Yanıtlar:


86
  1. Karmaşık bir sayının gerçek veya hayali kısmını aramamalısınız (gerçek ve hayali diziniz nedir). Bunun yerine, sqrt (gerçek * gerçek + görüntü * görüntü) olarak tanımlanan frekansın büyüklüğünü aramak istersiniz. Bu sayı her zaman pozitif olacaktır. Şimdi aramanız gereken tek şey maksimum değeri bulmaktır (dizinizdeki ilk girişi göz ardı edin. Bu sizin DC ofsetinizdir ve frekansa bağlı bilgi taşımaz).

  2. Karmaşıktan karmaşığa FFT kullandığınız için 32 gerçek ve 32 sanal çıktı elde edersiniz. 32 örneğinizi, sıfır hayali parça ile genişleterek 64 değere (veya 32 karmaşık değere) dönüştürdüğünüzü unutmayın. Bu, frekans sonucunun iki kez oluştuğu simetrik bir FFT çıkışı ile sonuçlanır. 0 ila N / 2 çıkışlarında kullanıma hazır olduğunda ve bir kez N / 2 ila N çıkışlarında yansıtıldığında, sizin durumunuzda N / 2 ila N çıkışlarını basitçe görmezden gelmek en kolay yoldur. Onlara ihtiyacınız yok, bunlar sadece FFT'nizi nasıl hesapladığınızla ilgili bir yapaylık.

  3. Fft-bin denkleminin frekansı (bin_id * frek / 2) / (N / 2) olup burada frekans örnek frekansınızdır (aka 32 Hz ve N, FFT'nizin boyutudur). Sizin durumunuzda bu, bölme başına 1 Hz'ye kadar basitleştirir. Kutular N / 2'den N'ye negatif frekansları temsil eder (garip bir kavram, biliyorum). Sizin durumunuz için önemli bir bilgi içermiyorlar çünkü bunlar sadece ilk N / 2 frekanslarının bir aynası.

  4. Her kutudaki gerçek ve hayali kısımlarınız karmaşık bir sayı oluşturur. Frekansın kendisinin büyüklüğü pozitifken gerçek ve hayali kısımların negatif olması sorun değil (1. soruya cevabıma bakın). Karmaşık sayıları okumanızı öneririm. Nasıl çalıştıklarını (ve neden yararlı olduklarını) açıklamak, tek bir yığın akışı sorusuyla açıklamanın mümkün olduğunu aşar.

Not: Otokorelasyonun ne olduğunu ve bir sinyalin temel frekansını bulmak için nasıl kullanıldığını da okumak isteyebilirsiniz. İçimde gerçekten istediğinin bu olduğuna dair bir his var.


1
Teşekkürler. 1 ile ilgili olarak: Bir frekans spektrumunu ( mathworks.com/help/techdoc/ref/fft.html ) gösteren bu Matlab sayfasını gördüm . Bu sayfada, "Tek Taraflı Genlik Spektrumu y (t)" başlıklı bir çizim var. Bu, önerdiğiniz gibi frekansın büyüklüğünü mi çiziyor, sqrt (real ^ 2 + img ^ 2)? 3 ile ilgili olarak: Hala 2Hz / bin sonucunu alamıyorum. Benim durumumda, N = 32 ve freq = 32, değil mi? Yani N / 2 = 32/2 = 16 bölme var ve en yüksek frekans (Nyquist) frek / 2 = 32/2 = 16 Hz'dir ve 16 bölmede 16 Hz ile sonuçlanır ve bölme başına 1 Hz verir?
stackoverflowuser2010

1
Evet, arsa spektrumun büyüklüğünü gösteriyor - | Y (f) |. Mutlak değer çubukları, büyüklük anlamına gelir. Bölme genişliği = örnekleme hızı / FFT boyutu. Örnek hızınız 32 hz, FFT boyutunuz 32. Evet, ambar genişliği konusunda haklısınız!
Matt Montag

Bin frekansı düzeltildi.
André Chalella

1
Güzel cevap, teşekkürler! Partiye biraz geç kaldığım için üzgünüm, ama genel olarak frekansın büyüklüğünün (sizin tarafınızdan 1. maddede belirtildiği üzere) ne kadar olduğunu bana cevaplayabilirsiniz. Benim durumumda, bir ivmeölçerden gelen değerlerin sinyalinde (m / s ^ 2'dir). Tam olarak anlayamıyorum.
Markus

Büyüleyici! Müzik görselleştirme frekans çubuklarımın tümü soldan sağa yansıtılmış olarak çıkıyordu; cevap 2 bunu açıklıyor !! Çılgın!!
Ryan S

11

Zaten bazı iyi yanıtlarınız var, ancak FFT'den önce zaman alanı verilerinize gerçekten bir pencere işlevi uygulamanız gerektiğini ekleyeceğim , aksi takdirde spektral sızıntı nedeniyle spektrumunuzda kötü eserler elde edersiniz .


Bu cevabın üzerinden epey zaman geçtiği için minnettarım .. Bununla birlikte, ne tür eserlerden bahsettiğinizi açıklayabilir misiniz?
MattHusz

1
@MattHusz: Bu eserlerin kökeni için genel terim "spektral sızıntı" dır - Şimdi cevaba bunu açıklayan bir bağlantı ekledim. Etkiyi tanımlamanın en iyi yolu, örtülü dikdörtgen pencere nedeniyle spektrumunuzun "bulaşması".
Paul R

6

1) İlkinin yanı sıra gerçek dizideki en yüksek değerlere sahip indisleri arayın (bu DC bileşeni). Anlamlı sonuçlar elde etmek için muhtemelen 32 Hz'den çok daha yüksek bir örnekleme hızına ve daha büyük bir pencere boyutuna ihtiyacınız olacak.

2) Her iki dizinin ikinci yarısı, ilk yarının aynasıdır. Örneğin, gerçek dizinin son öğesinin (1.774) ikinci öğeyle (1.774) aynı olduğuna ve sanal dizinin son öğesinin (1.474) ikinci öğenin negatif olduğuna dikkat edin.

3) 32 Hz örnekleme hızında alabileceğiniz maksimum frekans 16 Hz'dir ( Nyquist sınırı ), bu nedenle her adım 2 Hz'dir. Daha önce belirtildiği gibi, ilk elemanın 0 Hz olduğunu (yani DC ofset) unutmayın.

4) Elbette, negatif bir genlik mükemmel bir anlam ifade ediyor. Bu sadece sinyalin "ters çevrildiği" anlamına gelir - standart bir FFT, normalde t = 0'da değeri = 1 olan bir kosinüsü temel alır, yani zaman = 0'da değeri = -1 olan bir sinyalin negatif bir genliği olacaktır .


Yanıt için teşekkürler. (1) Hayali (sinüs) diziyi görmezden gelebileceğimi mi söylüyorsunuz, öyleyse neden? Elbette sinüs bileşeni önemli olmalı? (2) Bu yansıtma neden oluşur? Bu sadece FFT algoritmasının bir sonucu mu? Çoğu insan aynalı yarıyı görmezden mi geliyor? (3) 2Hz adımlarını nasıl hesapladınız? Nyquist'in 16Hz sınırını anlıyorum, bu nedenle 16 (yansıtılmamış) dizi öğesi varsa, her öğe 16 Hz / 16 = 1 Hz olmalıdır. (4) Ana frekansları bulmak için, çıktı dizilerindeki genlik değerlerinin sadece mutlak değerini mi almalıyım?
stackoverflowuser2010

En yüksek değer için gerçek diziye bakmamalısınız ve sinüs / I dizisini görmezden gelemezsiniz. Bunun yerine, bileşik karmaşık vektörün büyüklüğünü istiyorsunuz. Aynalama, girdinin yarısının (I dizisi) tamamı sıfır olduğu için oluşur, bu nedenle sonuç serbestlik derecesinin yarısına sahiptir. Verileriniz kesinlikle gerçekse bunu göz ardı edebilirsiniz.
hotpaw2

@duskwuff Çok teşekkürler: Eğer cevabınızı bulamazsam, göndereceğim bir soruya cevap verdiniz: FFT'nin İKİNCİ bölümünü nasıl yorumlayabilirim? Verileri değiştirmek ve tersini yapmak istiyorum ve sadece yarı sonuç almaya devam ettim çünkü o kısımdaki yanlış verileri değiştirdim. Tekrar teşekkürler.
Martin

(3), adım = 2Hz değeri şimdiye kadar benim için örtük kalır. Uzunluk = 16 dizisi ile temsil edilen 16 kutumuz var. 0Hz'den 16Hz'ye kadar tüm frekansları tanımlamamız gerekiyor. Her kutunun bu aralığın bir parçasını tanımladığını varsayıyorum, değil mi?
krafter

@krafter Sanırım yarıya indi çünkü tek bir değerden frekans çıkaramazsınız (tekrar olmadığı için).
JVE999

5

"En çok meydana gelen frekansın", bir pencere işleviyle bile birden çok FFT bölmesine sıçrayabileceğini unutmayın. Bu nedenle, herhangi bir spektral zirvenin frekansını daha iyi tahmin etmek için daha uzun bir pencere, birden çok pencere veya enterpolasyon kullanmanız gerekebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.