Алгоритм сглаживания сигнала (скользящее среднее Matlab) - PullRequest
1 голос
/ 14 мая 2019

Я написал простой код, который выполняет алгоритм сглаживания скользящих средних по 3 точкам.Он предназначен для того же базового алгоритма, что и гладкая (...) функция Matlab, как описано здесь .

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

Вот сравнение зашумленных данных, сглаженных с использованием моего кода (красный) и функции Matlab (синий):

Here is a comparison:

Вот мой код, написанный в виде функции:

function [NewSignal] = smoothing(signal)
NewSignal = signal;
for i = 2 : length(signal)-1
    NewSignal(i,:) = (NewSignal(i,:)+NewSignal(i-1,:)+NewSignal(i+1,:))./3;
end
end

Функция Matlab используется следующим образом:

signal = smooth(time, signal, 3, 'moving');

Насколько я понимаю, функция Matlab работает так же;это усредняет 3 смежных бункера к одному бинку.Поэтому я ожидал, что оба алгоритма дадут одинаковые результаты.

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

Редактировать:

Мои примеры данных можно найти здесь .Доступ к нему можно получить с помощью:

M = csvread('DS0009.csv');
time = M(:,1);
signal = M(:,2);

Вот новый результат (красный график) с использованием поправки Ринкерта:

enter image description here

Ответы [ 2 ]

5 голосов
/ 14 мая 2019

Одной из причин такой разницы может быть то, что вы частично используете сглаженный сигнал во время сглаживания.В вашем цикле вы сохраняете сглаженное значение в NewSignal(i,:), и для следующего сэмпла для сглаживания это значение будет вызываться NewSignal(i-1,:).

Пусть NewSignal будет определено только исходным signal:

function [NewSignal] = smoothing(signal)
    NewSignal = signal;
    for i = 2 : length(signal)-1
        NewSignal(i,:) = (signal(i,:)+signal(i-1,:)+signal(i+1,:))./3;
    end
end

Обновление: Чтобы показать, что вышеприведенная функция действительно выполняетТак же как и в smooth функции Matlab, давайте рассмотрим это MVCE :

t = (0:0.01:10).';      % time vector 
y = sin(t) + 0.5*randn(size(t));

y_smooth1 = smooth(t,y,3,'moving');
y_smooth2 = smoothing(y);

difference_methods = abs(y_smooth1-y_smooth2);

Итак, создав синусоидальную волну, добавьте немного шума и определите абсолютную разницу между двумя методами.Если вы возьмете сумму всех различий, вы увидите, что это в сумме примерно равно 7,5137e-14, что не может объяснить различия, которые вы видите.

Построение сигнала сглаживания (синий оригинал, сглаживание красного цвета):

figure(1); clf; hold on
plot(t,y)
plot(t,y_smooth2)

enter image description here

И затем нанесение разницы между двумяметоды:

figure(2); clf; hold on;
plot(t,y_smooth1-y_smooth2)

enter image description here

Как видите, разница составляет порядка 1e-16, поэтому она зависит от относительной точности с плавающей точкой(см. eps).

1 голос
/ 14 мая 2019

Чтобы ответить на ваш вопрос в комментариях: функции filter и smooth выполняют арифметически одинаково (в том случае, если они применяются для скользящей средней). однако в начале и в конечных точках существуют особые случаи, которые обрабатываются по-разному. Это также указано в документации «Сглаживание» * Из-за способа, которым сглаживание обрабатывает конечные точки, результат отличается от результата, возвращаемого функцией фильтра."

Здесь вы видите это в примере:

%generate randonm data
signal=rand(1,50);

%plot data
plot(signal,'LineWidth',2)
hold on
%plot filtered data
plot(filter(ones(3,1)/3,1,signal),'r-','LineWidth',2)
%plot smoothed data
plot( smooth(signal,3,'moving'),'m--','LineWidth',2)
%plot smoothed and delayed
plot([zeros(1,1); smooth(signal,3,'moving')],'k--','LineWidth',2)
hold off
legend({'Data','Filter','Smooth','Smooth-Delay'})

Example

Как видите, отфильтрованные данные (красным цветом) являются просто отложенной версией сглаженных данных (пурпурного цвета). Кроме того, они отличаются в начале. Задержка сглаженных данных приводит к тому же сигналу, что и к отфильтрованным данным (кроме начала). Как указал Ринкерт, ваш подход перезаписывает точки данных, к которым вы обращаетесь на следующем шаге. Это другая проблема.

В следующем примере вы увидите, что реализация rinkerts (smooth-rinkert) идентична matlabs smooth, и что ваш подход отличается от обоих из-за перезаписи значений:

comparison between your and rinkerts approach

Таким образом, ваша функция сильнее передает низкий уровень входного сигнала. (как указано Крисом)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...