Форум программистов, компьютерный форум, киберфорум
Цифровая обработка сигналов
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.78/23: Рейтинг темы: голосов - 23, средняя оценка - 4.78
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
1

Фильтрация зашумленого сигнала

31.05.2013, 23:46. Просмотров 4768. Ответов 24
Метки нет (Все метки)

Приятного времени суток,

Записываю с микрофона, и в записи постоянно присутствуют какие-то шумы. Имеется желание избавиться от них или как-то уменьшить. Как это можно сделать? Нашел несколько способов, но вот неважно "плаваю" в ЦОС.
1. FFT, обнуляем(убираем) частоты шума, IFFT. Но как определить какие это частоты?
2. Фильтры. Фильтрация Калмана. Рыскал по разделу: фильтрация есть свертка сигнала с импульсной характеристикой фильтра. Как проектировать такие штуки? Опять же, чтоб убирали нужные частоты.
И раз уж сказал про свертку, вопрос: оконные функции и фильтры - одно и то же ? Функции ведь тоже, можно сказать, убирают/ уменьшают/ изменяют нужным образом амплитуды частотных составляющих.
3. Мб еще что-нибудь есть?

Прошу подтолкнуть в нужно направлении, чтоб дело чутка быстрее пошло. Литература и т.д. Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.05.2013, 23:46
Ответы с готовыми решениями:

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

Фильтрация затухающего сигнала.
Есть затухающий сигнал записанный с частотой семплирования 4000Hz, длительность записи составляет...

ВЧ фильтрация звукового сигнала
Добрый день! Подскажите, пожалуйста, какой фильтр лучше использовать для ВЧ фильтрации звукового...

Фильтрация сигнала в частотной области
Здравствуйте! Не могу понять для себя один вопрос, буду очень благодарна, если поможете...

24
10208 / 6589 / 494
Регистрация: 28.12.2010
Сообщений: 21,165
Записей в блоге: 1
01.06.2013, 00:33 2
1- да. Например пройтись по всем гармоникам, кроме основной, определить средний уровень шума и все по среднему срезать, далее обратно IFFT. Или наложением окон-фильтров, ограничивающим полосу, к примеру Hemming по уровню -54 dB, Blackman-Harris по уровню -61 dB, -67 dB, -92 dB
2- вообще Калмановскую фильтрацию чаще применяют в адаптивных фильтрах замкнутых контуров http://kit-e.ru/articles/cad/2005_8_168.php ...они не убирают нужные частоты, а скорее оставляют ту полосу, где сосредоточена спектральная плотность мощности сигнала.


Вот рабочий алгоритм Калмана (но он для ПИД):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef KalmanFilterH
#define KalmanFilterH
//---------------------------------------------------------------------------
class TKalman
{
private:
   float q; //process noise covariance
   float r; //measurement noise covariance
   short x; //value
   float p; //estimation error covariance
   float k; //kalman gain
 
   void KalmanUpdate(short value);
 
public:
   TKalman();
   ~TKalman();
 
   void KalmanInit(float q, float r, float p, short intial_value);
 
   short GetResult(short data);
 
};
//---------------------------------------------------------------------------
#endif //KalmanFilterH
 
===================
 
#include "KalmanFilter.h"
//---------------------------------------------------------------------------
void TKalman::KalmanInit(float q, float r, float f, short intial_value)
{
   this->q = q;
     this->r = r;
     this->p = p;
     this->x = intial_value;
}
//---------------------------------------------------------------------------
 
//---------------------------------------------------------------------------
void TKalman::KalmanUpdate(short data)
{
   //prediction update
   //omit x = x
   p = p + q;
 
   //measurement update
   k = p / (p + r);
   x = x + k * (data - x);
   p = (1 - k) * p;
}
//---------------------------------------------------------------------------
short TKalman::GetResult(short data)
{
   KalmanUpdate(data);
   return x;
}
//---------------------------------------------------------------------------
TKalman::TKalman()
{
 
}
//---------------------------------------------------------------------------
TKalman::~TKalman()
{
 
}
Литература и т.д. Спасибо!
тема закреплена между прочим - Литература по ЦОС и алгоритмам
1
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
01.06.2013, 00:53  [ТС] 3
Цитата Сообщение от raxp Посмотреть сообщение
определить средний уровень шума и все по среднему
Можно поподробнее? В ряде Фурье, как понял, первую гармонику не трогаем ( w=1), а как средний уровень шума посчитать?
Читал "Без паники! Цифровая обработка сигналов - Юкио Сато, 2010 год ". Там было что-то типа - сигнал есть сумма постоянной составляющей + шум - в каждой выборке. Просто берем большое кол-во выборок, складываем, затем делим на их кол-во, то есть среднее арифметическое. Та часть, которая всегда присутствует - остается неизменной, а шумы поскольку случайны - уменьшаются. Это и есть то, что нужно? Не совсем понимаю, как применить к Фурье ряду.
0
10208 / 6589 / 494
Регистрация: 28.12.2010
Сообщений: 21,165
Записей в блоге: 1
01.06.2013, 02:25 4
...именно так. Вообще, в своих материалах по FFT и блоге об этом уже вел речь.

Описать можно примерно так:
Код
// средний уровень шума
  средний уровень шума = (суммарный уровень по всем гармоникам, исключая нулевую - уровень максимальной гармоники) / количество точек преобразования бабочки FFT
1
2009 / 1281 / 60
Регистрация: 05.06.2010
Сообщений: 2,213
01.06.2013, 09:50 5
Цитата Сообщение от IamRain Посмотреть сообщение
1. FFT, обнуляем(убираем) частоты шума, IFFT. Но как определить какие это частоты?
Это самый плохой из существующих фильтров - с прямоугольным окном. Как вы говорили - фильтрация(в обобщенном виде) есть свертка сигнала с импульсной характеристикой фильтра. В частотной области операция свертки есть умножение. То есть, обнуление частот шума как вы говорите, есть умножение спектра на прямоугольное окно. Это можно делать без fft, так так обратное преобразование фурье от прямоугольного окна известно - это функция sin(wt)/wt. Сворачивайте сигнал с этой функцией (это функция по сути и будет импульсной характеристикой фильтра) с домножением на оконную функцию, это будет самый простейший ких фильтр полученный оконным методом.
Естественно, когда вы фильтруете что то, надо иметь соответствующие требования к фильтру. То есть, вам надо знать структуру сигнала и характер шумов, то есть знать с чем бороться, иначе все попытки "улучшить" сигнал будут тыканьем вслепую. Причем в адаптивной фильтрации тоже(если вы упомянули калмана). Есть конечно алгоритмы слепой адаптации, но они сложные, на практике я с такими не сталкивался, плохо представляю как они работают.
Так что первым делом вам надо провести анализ спектрального состава сигнала с шумом и без(если есть такая возможность). Подозреваю, что простенький нч фильтр вам поможет
2
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 07:43  [ТС] 6
Добрый день, уважаемые форумчане

Все еще мучаюсь с фильтрацией (недели 3 прошло), но пытаюсь добить этого зверя). Так вот решил попробовать просто через FFT, зануление нужных частот и IFFT. В результате сигнал не фильтруется, а наоборот - полная чушь, то бишь еще хуже. Предположил, что какие-то проблемы при обратном преобразовании и записи исходного wav-файла. Решил проверить просто FFT ->IFFT - восстановлю ли я полученный сигнал. Не восстановил: сигнал - сплошной шум.
Возникают следующие вопросы:
1. При занулении частот надо производить зануление еще и в отраженной области? Предполагаю что да, но не уверен.
2. Что в этом коде неправильно? Читаю wav-файл, считываю блоками по 240 сэмплов, FFT-IFFT, собираю обратно в новый файл. По идее должно быть то же самое. Но вот не получается. Обратите внимание на сборку нового файла ( запись), вероятно что-то делаю не так именно в этом месте. Комментарии для более быстрого восприятия.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
private static void  GoAndBack()
        {
            String path = @"C:\Users\Rain\Desktop\Testing Filtration\AudioTesting-44100Hz.wav";
            WaveFileReader freader = new WaveFileReader(path);
            byte[] data = new byte[freader.Length];
            freader.Read(data, 0, (int)freader.Length);
            freader.Close();
 
            int count = (int)freader.Length / 480;
            int left = data.Length - count * 480;
            String newPath = @"C:\Users\Rain\Desktop\audioTesting-GoandBack.wav";
            WaveFileWriter writer = new WaveFileWriter(newPath, new WaveFormat(44100, 1));
 
              
 
          // обработка файла блоками по 480 байт - 240 сэмплов
            #region FOR
            for (int i = 0; i < count + 1; i++)
            {
                byte[] currentData;
                if (i < count)
                    currentData = data.Skip(i * 480).Take(480).ToArray();
                else currentData = data.Skip(i * 480).Take(left).ToArray();
 
            //  формирование комплексных входных данных + дополнение нулями
                Complex[] complexData = new Complex[currentData.Length / 2 + (256 - currentData.Length / 2)];
                data.Initialize();
                int index = 0;
                // формируем 16-битные семплы
                for (int j = 0; j < currentData.Length; j += 2)
                {  
                    // мнимая часть - 0.
                    complexData[index++].X = BitConverter.ToInt16(currentData, j);
                }
 
                FastFourierTransform.FFT(true, 8, complexData);
                FastFourierTransform.FFT(false, 8, complexData);
 
                foreach (var item in complexData)
                {
                    //  input - float
                    writer.WriteSample(item.X * item.X + item.Y * item.Y);
                }
            }
            #endregion
            Console.WriteLine("The end.");
            Console.ReadKey(true);
            writer.Close();             
        }
Добавлено через 6 минут
При этом исходный файл весит - 504 кБ, вновь собранный - 536 кБ.
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 09:46 7
В строке 28 написано "data.Initialize();" — здесь всё правильно? Может имелось в виду complexData, а не data?

Добавлено через 2 минуты
И почему в строке 43 находится сумма квадратов действительной и мнимой частей? Если всё делать правильно, то результирующий сигнал должен оказаться в вещественной части, а мнимая должна быть равна нулю.

Добавлено через 3 минуты
Цитата Сообщение от IamRain Посмотреть сообщение
1. При занулении частот надо производить зануление еще и в отраженной области?
Да, конечно. В частотной области всё должно быть симметрично относительно нуля (амплитудная характеристика чётная, фазовая — нечётная), иначе не получится вещественный сигнал.

Добавлено через 2 минуты
Вот только если просто занулять отдельные частоты, то на границах точек появятся скачки сигнала, что явно не добавит качества сигналу.
1
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 09:53  [ТС] 8
Цитата Сообщение от grizlik78 Посмотреть сообщение
В строке 28 написано "data.Initialize();" — здесь всё правильно? Может имелось в виду complexData, а не data?
Да, все верно, спасибо. Но работает все равно также.
Цитата Сообщение от grizlik78 Посмотреть сообщение
И почему в строке 43 находится сумма квадратов действительной и мнимой частей? Если всё делать правильно, то результирующий сигнал должен оказаться в вещественной части, а мнимая должна быть равна нулю.
Ну я просто знаю, что записываем амплитуды - это как страховка, если мнимая - ноль, то ошибки не будет.
Убрал мнимую часть, работает так же, ну не совсем. Суть в том, что я произношу в записи цифры от 1 до 5, два раза. Там где идут звуки речи, то есть произнесенные мной цифры, величина шума уменьшается, но все равно абсолютно неразборчиво.

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

Добавлено через 1 минуту
Если надо, могу скинуть файлы - оригинал и собранный после.
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 09:54 9
Цитата Сообщение от IamRain Посмотреть сообщение
Перекрытия и оконные функции не используются, это может настолько сильно повлиять на сигнал ограниченной длительности?
До тех пор, пока в частотной области ничего не происходит (как в приведённой программе) — вообще влиять не должно. В этой программе на выходе должно оказаться точно то же, что было на входе.
Я не специалист в C#, поэтому ошибку, если она есть, могу и не увидеть.
Если FFT и IFFT отключить — всё нормально? Думаю, что нет.
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 09:57  [ТС] 10
Если их отключить, то смысла уже никакого не будет. Записать то назад считанные байты - однозначно получу исходный файл без потерь. )
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 10:03 11
А если они друг-друга не компенсируют, то ошибка в них. Если же компенсируют, то и так должен получиться исходный файл без потерь. Получается?
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:09  [ТС] 12
Цитата Сообщение от grizlik78 Посмотреть сообщение
Получается?
Издеваетесь?
Это если я вам предложу считать файл через fin и записать то, что считали через fout. А потом спросить также.

Не по теме:

Только вот не смешно - дипломная горит.

0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 10:12 13
Цитата Сообщение от IamRain Посмотреть сообщение
Издеваетесь?
Ни в коем случае. В исходном посте есть предположение, что неправильно производится сборка нового файла. Оно проверяется временным отключением преобразования Фурье.

Кстати, а вообще откуда берётся это FastFourierTransform? И что означает второй параметр, который 8?
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:14  [ТС] 14
Цитата Сообщение от grizlik78 Посмотреть сообщение
Кстати, а вообще откуда берётся это FastFourierTransform? И что означает второй параметр, который 8?
Управляемая библиотека для работы со звуком - Naudio.dll. (Naudio.dsp namespace). 8 - степень числа 2, размер окна - 256.
240 сэмплов + 16 нулей справа.
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:23  [ТС] 15
Вообще, пытаюсь точно воспроизвести алгоритм извлечения MFCC вот по этой вот работе:
0
Вложения
Тип файла: pdf Robust MFCC-features extraction-2002.pdf (720.9 Кб, 16 просмотров)
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:25  [ТС] 16
Да вот застрял на фильтрации. Там алгоритм фильтрации Райнера Мартина был - более крутой. Но я может его и вкурил, но из-за FFT/IFFT ни*ера не получается. Мне нужно просто убрать стационарный шум микрофона.
Любой алгоритм. Столько литературы перерыл, ппц. Помогите. ) 2 июля защита. А еще классификатор писать. - нейронную сеть.
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 10:26 17
Так. Ну хотя бы понятно, откуда больший размер файла. 536/504 это примерно 256/240. Из каждого сегмента результата надо записывать только первые 240 отсчётов, остальные должны получится нулевыми.
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:28  [ТС] 18
Цитата Сообщение от grizlik78 Посмотреть сообщение
Так. Ну хотя бы понятно, откуда больший размер файла. 536/504 это примерно 256/240. Из каждого сегмента результата надо записывать только первые 240 отсчётов, остальные должны получится нулевыми.
Ну на качестве, предположительно, не должно отразиться.
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
22.06.2013, 10:30 19
Цитата Сообщение от IamRain Посмотреть сообщение
Ну на качестве, предположительно, не должно отразиться.
Когда каждые 240 отсчётов сигнала прерывается дыркой из 16 нулевых отсчётов — это очень сильно отразится на качестве.
0
2140 / 1624 / 485
Регистрация: 02.08.2011
Сообщений: 4,688
22.06.2013, 10:45  [ТС] 20
Цитата Сообщение от grizlik78 Посмотреть сообщение
Когда каждые 240 отсчётов сигнала прерывается дыркой из 16 нулевых отсчётов — это очень сильно отразится на качестве.
мм, вероятно, на этих "дырках" шума и меньше, а не на участках речи.

Добавлено через 1 минуту
Вообще фильтрация, только промежуточный этап - записываю в файл для ее проверки. Если бы не проверял - была бы fail-утая реализация алгоритма MFCC. А это мне не нужно.

Добавлено через 11 минут
Вообщем, если есть какие-то идеи - пишите. Первоначально вообще хотел свой велосипед изобрести - обертку для FFTW (очень быстрая), да вот нашел в Naudio. На данный момент нужно хотя бы корректное FFT/IFFT.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.06.2013, 10:45

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Избавиться от шума (фильтрация сигнала)
Доброго времени суток. Помогите пожалуйста с такой задачкой: с прибора по Com-порту приходит...

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

Фильтрация отраженного сигнала с задержкой
Всем доброго времени суток. Задача передо мной стоит следующая: есть сигнал записанный семплами...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.