Matlab - Удаление шумового сигнала - PullRequest
8 голосов
/ 29 июля 2011

У меня есть вектор данных, который содержит целые числа в диапазоне -20 20.

Ниже приведен график со значениями:

enter image description here

Это выборка из 96 элементов из векторных данных. Большинство элементов расположены в интервале -2, 2, как видно из приведенного графика.

Я хочу устранить шум из данных. Я хочу устранить пики низкой амплитуды и сохранить пик высокой амплитуды, а именно пики, подобные пику с индексом 74.

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

Не могли бы вы предложить мне способ сделать это?

Я пробовал mapstd функцию, но проблема в том, что она также нормализует этот пик с высокой амплитудой.

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

Можете ли вы порекомендовать мне способ сделать это?

Ответы [ 5 ]

9 голосов
/ 29 июля 2011

Одним из подходов к обнаружению выбросов является использование правила трех стандартных отклонений . Пример:

%# some random data resembling yours
x = randn(100,1);
x(75) = -14;
subplot(211), plot(x)

%# tone down the noisy points
mu = mean(x); sd = std(x); Z = 3;
idx = ( abs(x-mu) > Z*sd );         %# outliers
x(idx) = Z*sd .* sign(x(idx));      %# cap values at 3*STD(X)
subplot(212), plot(x)

enter image description here


EDIT:

Кажется, я неправильно понял цель здесь. Если вы хотите сделать наоборот, может быть, что-то вроде этого:

%# some random data resembling yours
x = randn(100,1);
x(75) = -14; x(25) = 20;
subplot(211), plot(x)

%# zero out everything but the high peaks
mu = mean(x); sd = std(x); Z = 3;
x( abs(x-mu) < Z*sd ) = 0;
subplot(212), plot(x)

enter image description here

7 голосов
/ 29 июля 2011

Если это только для демонстрационных целей, и вы на самом деле не собираетесь использовать эти масштабированные значения для чего-либо, я иногда хотел бы увеличить контраст следующим образом:

% your data is in variable 'a'
plot(a.*abs(a)/max(abs(a)))

edit: так как мыВыкладываем изображения, вот мои (до / после): enter image description here

6 голосов
/ 29 июля 2011

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

k = [L L L L L L 0 0 0 x 0 0 0 R R R R R R]

Для каждой выборки x вы усредняете полосу окружающих выборок слева (L) и полосу окружающих выборок справа,Если ваши образцы положительные и отрицательные (как у вас), вы должны взять пресс.значение в первую очередь.Затем вы делите выборку х на среднее значение этих окружающих выборок.

y[n] = x[n] / mean(abs(x([L R])))

Каждый раз, когда вы делаете это, пики усиливаются, а шум сглаживается.Вы можете сделать более одного прохода, чтобы увеличить эффект.Он несколько чувствителен к выбору ширины этих полос, но может работать.Например:

before

Два прохода:

after

3 голосов
/ 29 июля 2011

Что вам действительно нужно, так это какое-то сжатие для масштабирования ваших данных, то есть: значения между -2 и 2 масштабируются по определенному коэффициенту, а все остальное масштабируется по другому коэффициенту.Грубый способ выполнить такую ​​вещь - это обнулить все малые значения, то есть

x = randn(1,100)/2; x(50) = 20; x(25) = -15; % just generating some data
threshold = 2;
smallValues = (abs(x) <= threshold);
y = x;
y(smallValues) = 0;
figure; 
plot(x,'DisplayName','x'); hold on; 
plot(y,'r','DisplayName','y'); 
legend show;

. Пожалуйста, не делайте это очень нелинейной операцией (например, когда вы хотите, чтобы пики оценивались в 2,1 и 1,9, они приведут к совершенно другому поведению: одно будет удалено, другое сохранится).Так что для отображения это может быть все, что вам нужно, для дальнейшей обработки это может зависеть от того, что вы пытаетесь сделать.

enter image description here

2 голосов
/ 29 июля 2011

Чтобы устранить пики низкой амплитуды, вы будете приравнивать весь сигнал низкой амплитуды к шуму и игнорировать.

Если у вас есть априорные знания, просто используйте их.

если ваш сигнал, то

a(abs(a)<X) = 0

где X - максимальный ожидаемый размер вашего шума.

Если вы хотите проявить фантазию и найти это «на лету», используйте kmeans of 3. Это в наборе инструментов статистики, здесь:

http://www.mathworks.com/help/toolbox/stats/kmeans.html

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

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

...