Перейти к содержанию
    

Спектральный анализ Фурье

Требуется помощь!

 

Согласно ТЗ мне нужно сделать дискретное преобразование Фурье массива выборок.

С прямым, все отлично - получаем амплитудный и фазовый спектр, и непосредственно зеркальный спектр. а вот с обратным преобразованием не получается - результатом ОДПФ, согласно формуле появляются 2 массива состовляющих "Мнимые" и "реальные". Как из них получить результирующий массив(Например делая ДПФ и ОДПФ получить исходный массив)? Есть наброска на джаве:

 

Задаем массив signal

 

Прямое ДПФ

private static void DFT(double[] signal, double[] phase) 
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
     for(int k = 0; k < 1024; k++)
     {
        for(int n = 0; n < 1024; n++){  
     Re[k]=Re[k]+signal[n]*Math.cos(-2*Math.PI*k*n/1024);
     Im[k]=Im[k]+signal[n]*Math.sin(-2*Math.PI*k*n/1024);}
     }
        
        for(int k = 0; k < 1024; k++)
     {
        signal[k]=Math.sqrt(Re[k]*Re[k]+Im[k]*Im[k]);
        phase[k]=Math.atan(Im[k]/Re[k]);        
     }

 

Обратное ДПФ

private static void IDFT(double[] signal, double[] phase) 
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
    for(int n = 0; n < 1024; n++)
     {

        
        for(int k = 0; k < 1024; k++)  
        {  
            
     Re[n]=Re[n]+signal[k]*Math.cos(2*Math.PI*k*n/1024+phase[n]);
     Im[n]=Im[n]+signal[k]*Math.sin(2*Math.PI*k*n/1024+phase[n]);
                 
        }
       Re[n]=Re[n]/1024; 
       Im[n]=Im[n]/1024;
       
     }

  }

 

Как теперь получить исходя из этих массивов опратно массив signal выполнив подряд процедуры прямого и обратного преобразования

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из результата первой функции Вы не восстановите исходный сигнал, т.к. уже потеряли часть информации о нем, взяв квадратный корень. На вход обратного преобразования нужно подавать массивы Re и Im из прямой функции перед взятием корня и арктангенса. Тогда получите исходны сигнал в Re и нули в Im на выходе обратного преобразования. Разумеется, с точностью до ошибок счета.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из результата первой функции Вы не восстановите исходный сигнал, т.к. уже потеряли часть информации о нем, взяв квадратный корень.

Ни куда эта информация не делась. Она только претерпела изменение. И восстановить исходный сигнал по имеющимся значениям амплитуды и фазы можно.

 

А не работает скорей всего из за ошибки со знаками где то + с - перепутали. Где именно и как нужно смотреть формулы.

Изменено пользователем ivan219

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема была в том что нужно было использовать функции аргумента, а не арктангенса, а так же фильтровать спектр от зеркальной составляющей, занулив ее и удвоив исходный спектр

Может кому пригодится исходный код на java. Все это будет интегрироваться в Embedded систему с linux ядром.

 
private static void DFT(double[] signal, double[] phase) 
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
     for(int k = 0; k < 1024; k++)
     {
        for(int n = 0; n < 1024; n++)
        {  
     Re[k]=Re[k]+signal[n]*Math.cos(-2*Math.PI*k*n/1024 );
     Im[k]=Im[k]+signal[n]*Math.sin(-2*Math.PI*k*n/1024 );
        }
     }
         
       for(int k = 0; k < 1024; k++)
     {
        signal[k]=2*Math.sqrt(Re[k]*Re[k]+Im[k]*Im[k]);
        phase[k]=Math.atan2(Im[k],Re[k]);
     }   
                 
            
       for(int n = 512; n < 1024; n++)
             {
                       signal[n]=0;
                       phase[n]=0;   
             }
      
  }
  
  
  private static void ODFT(double[] signal, double[] phase) 
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
    for(int n = 0; n < 1024; n++)
     { 
            Re[n]=signal[n]*Math.cos(phase[n]);
            Im[n]=signal[n]*Math.sin(phase[n]);      
         }
    
    for(int n = 0; n < 1024; n++)
     {        
       signal[n]=0;
       phase[n]=0;
        for(int k = 0; k < 1024; k++)  
        { 
             signal[n]=signal[n]+Re[k]*Math.cos(2*Math.PI*k*n/1024)-Im[k]*Math.sin(2*Math.PI*k*n/1024);
        }
      
     }
    for(int n = 0; n < 1024; n++)
     { 
         signal[n]=signal[n]/1024;
        } 
  }

Изменено пользователем Navstar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте,
Мне очень неудобно из-за моего невежества в этом вопросе.

У меня куча мусора(наводка) в сигнале снятом с сенсора. Скажите можно ли в принципе Фурье анализом выделить данные соответствующие частотам, скажем ниже 5Гц? Я даже не понимаю корректно ли ставлю задачу. Буду благодарен любому комментарию.

Ну и чтоб два раза не вставать.

Я так понимаю что уже есть библиотеки фурье преобразования.

Если не сложно сбросьте пожалуйста примеры использования для выделения частот

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для выделения частот ниже 5 Гц нужен не Фурье, а обычный ФНЧ. КИХ или БИХ.

Это гораздо проще БПФ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, my504 сказал:

Для выделения частот ниже 5 Гц нужен не Фурье, а обычный ФНЧ. КИХ или БИХ.

Это гораздо проще БПФ.

В моем случае это не желательно. От наводок все равно не удастся избежать по многим причинам. И тем более знаю что это уже реализовано программным путем. Вот как не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Милостивый государь, частотная фильтрация определяется полосой, а не способом.

Либо внятно объясните про спектр сигнала и спектр помех, либо Вам никто не поможет.

Пока что Ваши возражения даже на детский лепет не тянут. Вы знаете что такое БИХ и КИХ ФНЧ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, my504 сказал:

 

 Вы знаете что такое БИХ и КИХ ФНЧ?

ФНЧ - думаю фильтр низкой частоты. Остальное не догадываюсь, но думаю железо.

В моем случае в железо вмешиваться нельзя, оно уже готовое и красиво выглядит. Можно только попытаться подчистить данные которые оно выдает програмно. И тут как назло вспомнился анализ Фурье. Еще до конца не вспомнил. Вот и спрашиваю. Пока там вникаю по новой, можно ли теоретически подчистить сигналы выше с частотой выше некой пороговой? Чтоб вы не беспокоились не наврежу ли я человечеству, обязуюсь исползовать эти знания только для медицинского оборудования ЕЕГ, ЕКГ, ИТД.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы думаете неправильно.  Это программный фильтр. Либо с кольцевым буфером (оконный буфер) - КИХ, либо рекурсивный фильтр - БИХ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, my504 сказал:

Вы думаете не правильно.  Это программный фильтр. Либо с кольцевым буфером (оконный буфер) - КИХ, либо рекурсивный фильтр - БИХ.

Вот с этого момента пожст по подробнее. Очень важно!!! Но это не все, мне надо будет еще выделять диапазон частот альфа, бета, гама ритмов мозга из общего сигнала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если речь идет о полосовой фильтрации то можно применить ДПФ, а не БПФ.

Дискретное Фурье преобразование применяют при небольшом количестве выделяемых полос.

Это тоже будет проще БПФ, который "либо всё, либо ничего"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, my504 сказал:

Если речь идет о полосовой фильтрации то можно применить ДПФ, а не БПФ.

Дискретное Фурье преобразование применяют при небольшом количестве выделяемых полос.

Это тоже будет проще БПФ, который "либо всё, либо ничего"...

Спасибо, иду гуглить. Только вы б уже расшифровали все эти ДПФ и БПФ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, IhorU сказал:

У меня куча мусора(наводка) в сигнале снятом с сенсора. Скажите можно ли в принципе Фурье анализом выделить данные соответствующие частотам, скажем ниже 5Гц? Я даже не понимаю корректно ли ставлю задачу. Буду благодарен любому комментарию.

Вы умолчали о самом главном важном - вам в реальном времени нужно сигнал чистить (т.е. в процессе его получения) или же он где-то запоминается, что позволяет его чистить неторопясь?

 

Если второе (это гораздо более простой вариант, чем первый), то советую заложить его в какой-нибудь Матлаб и там проверить, как выглядит его спектр и что дает его фильтрация. Т.е. не стоит решать такую задачу в общем виде, а желательно быть как можно ближе к конкретике. Хотя бы совсем грубым методом - взять и обрезать в спектре сигнала все частоты выше ниже 5Гц, а потом посмотреть, стал ли от этого сигнал выглядеть лучше с вашей точки зрения. Да и вообще интересно, что там творится за пределами 5Гц. Если там на каких-то частотах наблюдаются максимумы интенсивности, то имеет смысл давить именно их. Хуже случай, когда интенсивность спектра сигнала плавно уменьшается с ростом частоты. Однако в любом случае сперва нужна диагностика заболевания, а до этого делать операцию по вырезанию органов не рекомендуется :).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 минуты назад, Xenia сказал:

Вы умолчали о самом главном важном - вам в реальном времени нужно сигнал чистить (т.е. в процессе его получения) или же он где-то запоминается, что позволяет его чистить неторопясь?

Сигнал читается микроконтролером и может храниться в чисельном виде в массиве какое-то время(масив может быть и 256*10). В библиотеке для данного контролера есть библиотека быстрого Фурье анализа. Необходимо проанализировать масив данных, отфильтровать помехи от наводки и передать их на дисплей в виде кривой для анализа. Необходимо первое - очистить данные от частот выше 5 Гц (мы снимаем данные сопротивления кожи,ЕКГ, ЕЕГ). И вторая задача для ЕЕГ - выделить из общего сигнала альфа, бета, гама ритмы мозга. Каждый в своем частотном диапазоне и тоже передать на дисплей. Пока что у меня куча мусора не дающего правильно анализировать кривые.

Можно также рассматривать и другую схему - передача данных с сенсора на компьютер, программная фильтрация и вывод на экран. Все это должно быть в реальном времени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...