Розуміння результатів ШПФ


87

Мені потрібна допомога в розумінні результатів обчислення DFT / FFT.

Я досвідчений інженер-програміст, і мені потрібно інтерпретувати деякі показання акселерометра смартфона, такі як пошук основних частот. На жаль, я проспав більшість моїх коледжних занять з ЕЕ п’ятнадцять років тому, але останні кілька днів читав теми DFT та FFT (мабуть, мало).

Будь ласка, жодної відповіді "йдіть на уроки ЕЕ". Я насправді планую це зробити, якщо роботодавець мені заплатить. :)

Тож ось моя проблема:

Я вловлював сигнал на частоті 32 Гц. Ось 1 секундний зразок із 32 пунктів, який я накреслив у Excel.

введіть тут опис зображення

Потім я отримав код ШПФ написаний на Java, з Колумбійського університету (після дотримання пропозицій у дописі на тему " Надійний і швидкий ШПФ на Java ").

Результат роботи цієї програми такий. Я вважаю, що він працює на місці БПФ, тому він використовує один і той же буфер як для введення, так і для виводу.

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  ]

Отже, на даний момент я не можу зробити голови або хвости результату. Я розумію поняття DFT, такі як реальна частина - амплітуди компонентних косинусних хвиль, а уявна частина - амплітуди компонентних синусоїд. Я також можу слідувати цій схемі з великої книги " Керівництво вченого та інженера з цифрової обробки сигналів ": введіть тут опис зображення

Тож мої конкретні запитання:

  1. Як знайти на виході ШПФ "найбільш часто зустрічаються частоти"? Це частина мого аналізу даних мого акселерометра. Чи слід читати реальний (косинусний) чи уявний (синусовий) масиви?

  2. Я маю 32-точковий ввід у часовій області. Чи не повинен висновок ШПФ бути 16-елементним масивом для реалів та 16-елементним масивом для уявних? Чому програма дає мені реальні та уявні виходи масиву як розміром 32?

  3. Пов’язане з попереднім запитанням, як проаналізувати індекси у вихідних масивах? Враховуючи моє введення 32 зразків, відібраних з частотою 32 Гц, я розумію, що на виході 16-елементного масиву його індекс повинен мати рівномірний розподіл до 1/2 частоти дискретизації (32 Гц), тому я правильно розумію, що кожен елемент масиву представляє (32 Гц * 1/2) / 16 = 1 Гц?

  4. Чому вихід БПФ має від’ємні значення? Я думав, що значення представляють амплітуди синусоїди. Наприклад, вихід Real [3] = -1,075 повинен означати амплітуду -1,075 для косинусної хвилі частоти 3. Чи правильно? Як амплітуда може бути від’ємною?


Що ви хочете обчислити за показаннями акселерометра: швидкість, відстань? Шум показань акселерометра слідує за гауссовим розподілом, і я не можу зрозуміти, як підгонка синусоїди це може виправити.
Алі

2
тег java слід видалити, оскільки він є більш загальним, ніж для певної мови
user3791372

Дивлячись на суть Колумбійського університету, це зовсім не ефективно. Це проста, неоптимізована реалізація Cooley-Tucky з таблицями пошуку метеликів, і розворот бітів виконується вручну, замість використання існуючих бібліотечних функцій
Марк Єронімус,

@MarkJeronimus: Чи можете ви порекомендувати ефективну реалізацію ШПФ в Java? Якщо я правильно пам’ятаю, причиною того, що я погодився з кодом Колумбійського університету, була бібліотека FFTW, яка була занадто складною для роботи на смартфоні Android.
stackoverflowuser2010

Я знайшов кілька "оптимізованих" реалізацій, але в основному це один алгоритм для N розміру, тому, якщо вам потрібен діапазон розмірів, вам потрібні всі ці процедури. На практиці я в основному використовував інтегровані примітиви продуктивності Intel (так, від Java через JNA), але це не безкоштовно. Вдома я використовую в основному той самий алгоритм, який ви зв’язали, але написаний з нуля в 2005 році за допомогою підручника. Це просто ШПФ (Швидке перетворення Фур'є), і нічого такого "швидкого" в цьому не виправдовує назви "Швидке ШПФ".
Марк Єронімус

Відповіді:


85
  1. Вам також не слід шукати дійсну чи уявну частину комплексного числа (це ваш справжній та уявний масив). Натомість ви хочете шукати величину частоти, яка визначається як sqrt (реальний * реальний + imag * imag). Ця цифра завжди буде додатною. Тепер вам потрібно лише знайти максимальне значення (ігноруйте перший запис у вашому масиві. Це ваш зсув постійного струму і не містить інформації, що залежить від частоти).

  2. Ви отримуєте 32 реальних та 32 уявних виходу, оскільки використовуєте комплексний до складний ШПФ. Пам’ятайте, що ви перетворили свої 32 зразки на 64 значення (або 32 комплексні значення), розширивши їх нульовими уявними частинами. Це призводить до симетричного виходу ШПФ, де результат частоти трапляється двічі. Після того, як ви готові до використання на виходах від 0 до N / 2, а після дзеркального відображення на виходах від N / 2 до N. У вашому випадку найпростіше просто ігнорувати виходи N / 2 до N. Вони вам не потрібні, вони просто артефакт про те, як ви розраховуєте свій ШПФ.

  3. Частота рівняння fft-bin дорівнює (bin_id * freq / 2) / (N / 2), де freq - це ваша частота вибірки (вона ж 32 Гц, а N - розмір вашого FFT). У вашому випадку це спрощується до 1 Гц на смітник. Бункери від N / 2 до N представляють негативні частоти (дивна концепція, я знаю). Для вашого випадку вони не містять суттєвої інформації, оскільки вони є лише дзеркалом перших частот N / 2.

  4. Ваші реальні та уявні частини кожного контейнера утворюють комплексне число. Це нормально, якщо реальні та уявні частини є від’ємними, тоді як величина самої частоти позитивна (див. Мою відповідь на запитання 1). Я пропоную вам прочитати складні числа. Пояснення того, як вони працюють (і чому вони корисні), перевищує те, що можна пояснити в одному запитанні stackoverflow.

Примітка: Можливо, ви також захочете прочитати, що таке автокореляція та як вона використовується для пошуку основної частоти сигналу. У мене відчуття, що це те, чого ти справді хочеш.


1
Дякую. Щодо 1: Я бачив цю сторінку Matlab, яка показує частотний спектр ( mathworks.com/help/techdoc/ref/fft.html ). На цій сторінці є сюжет із заголовком "Односторонній амплітудний спектр у (t)". Це побудова графіку величини частоти, як ви запропонували, sqrt (real ^ 2 + img ^ 2)? Щодо 3: Я все ще не отримую 2 Гц на бін. У моєму випадку N = 32 і частота = 32, так? Отже, існує N / 2 = 32/2 = 16 бункерів, а найвища частота (Найквіст) - це частота / 2 = 32/2 = 16 Гц, в результаті чого 16 Гц на 16 бункерів дають 1 Гц на бункер?
stackoverflowuser2010

1
Так, графік показує величину спектра - | Y (f) |. Стовпчики абсолютного значення означають величину. Ширина бункера = частота дискретизації / розмір ШПФ. Частота вибірки - 32 гц, розмір ШПФ - 32. Так, ви маєте рацію щодо ширини бункера!
Matt Montag,

Виправлена ​​частота бункера.
Андре Шалелла,

1
Приємна відповідь, дякую! Вибачте, що я трохи запізнився на вечірку, але, можливо, ви могли б мені відповісти, якою одиницею є величина частоти (як ви згадали в пункті 1), загалом? У моєму випадку на сигнал значень з акселерометра (дорівнює м / с ^ 2). Я не можу це повністю зрозуміти.
Markus Wüstenberg

Захоплююче! Всі мої частотні смуги візуалізації музики виходили дзеркальними зліва направо; відповідь №2 пояснює це !! Божевільний !!
Ryan S

11

У вас вже є кілька хороших відповідей, але я просто додам, що вам дійсно потрібно застосувати функцію вікна до даних часового домену до ШВФ, інакше ви отримаєте неприємні артефакти у своєму спектрі через спектральну витоку .


Я розумію, що з моменту цієї відповіді минуло досить багато часу. Однак чи змогли б ви детальніше розказати про те, які саме артефакти ви маєте на увазі?
MattHusz

1
@MattHusz: загальним терміном походження цих артефактів є "спектральний витік" - я додав посилання на відповідь, яке пояснює це. Найкращий спосіб описати ефект - це те, що ваш спектр буде "розмитим" через неявне прямокутне вікно.
Paul R,

6

1) Шукайте індекси в реальному масиві з найбільшими значеннями, крім першого (це складова постійного струму). Ймовірно, вам знадобиться частота дискретизації, що значно перевищує 32 Гц, і більший розмір вікна, щоб значно завадити значущим результатам.

2) Друга половина обох масивів є дзеркалом першої половини. Наприклад, зверніть увагу , що останній елемент реального масиву (1.774) таким же , як другий елемент (1.774), а останній елемент масиву мнимого (1.474) є негативним другим елементом.

3) Максимальна частота, яку ви можете взяти на частоті дискретизації 32 Гц, становить 16 Гц ( межа Найквіста ), тому кожен крок становить 2 Гц. Як зазначалося раніше, пам'ятайте, що першим елементом є 0 Гц (тобто зміщення постійного струму).

4) Звичайно, негативна амплітуда має цілком сенс. Це просто означає, що сигнал "перевернутий" - стандартний БПФ базується на косинусі, який зазвичай має значення = 1 при t = 0, тому сигнал, який мав значення = -1 в момент часу = 0, матиме негативну амплітуду .


Дякую за відповідь. (1) Ви маєте на увазі, що я можу ігнорувати уявний (синусоїдальний) масив, і якщо так, то чому? Напевно, синусоїдальний компонент повинен бути важливим? (2) Чому відбувається це дзеркальне відображення? Це лише результат алгоритму ШПФ? Чи більшість людей ігнорують дзеркальну половину? (3) Як ви розрахували кроки 2 Гц? Я розумію межу Найквіста в 16 Гц, тож якщо є 16 (невіддзеркалених) елементів масиву, кожен елемент повинен мати 16 Гц / 16 = 1 Гц кожен? (4) Для пошуку основних частот я просто приймаю абсолютне значення значень амплітуди у вихідних масивах?
stackoverflowuser2010

Ви не повинні шукати в реальному масиві найвище значення, і ви не можете ігнорувати масив sine / I. Натомість вам потрібна величина складеного складного вектора. Дзеркальне відображення відбувається тому, що половина вхідних даних (масив I) - це всі нулі, тому результат має половину ступенів свободи. Ви можете ігнорувати це, якщо ваші дані є суто реальними.
hotpaw2

@duskwuff Велике спасибі: ви дали відповідь на запитання, яке я збирався розмістити, якби я не знайшов вашої відповіді: як інтерпретувати ДРУГУ частину ШПФ. Я хочу змінити дані та виконати зворотне, і я продовжував отримувати лише половину результатів, оскільки в цій частині я змінив неправильні дані. Знову дякую.
Мартін

(3), значення кроку = 2 Гц досі залишається для мене неявним. У нас 16 бункерів, представлених масивом довжини = 16. Нам потрібно описати всі частоти від 0 Гц до 16 Гц. Я припускаю, що кожен смітник описує частину цього діапазону, чи не так?
крафтер

@krafter Я думаю, що це зменшилося вдвічі, тому що ви не можете вивести частоту з одного значення (оскільки немає повторення).
JVE999

5

Зверніть увагу, що "найбільш часто зустрічається частота" може розбризкуватися в декілька бункерів ШПФ, навіть із функцією вікна. Отже, можливо, доведеться використовувати довше вікно, кілька вікон або інтерполяцію, щоб краще оцінити частоту будь-яких спектральних піків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.