Как сгладить сюжет в MATLAB?

У меня есть около 9000 точек, которые нанесены на график:

[ Полное разрешение]

альтернативный текст

На самом деле, сюжет не такой гладкий, как мне хотелось бы. Есть ли способ, как я могу сгладить график до необходимой степени?

Или какая-то форма порога, чтобы я мог выборочно сгладить слишком неровные части?

Я не уверен, но может ли помочь быстрое преобразование Фурье?

5 ответов

Решение

Простой (ad hoc) способ состоит в том, чтобы просто взять средневзвешенную alpha) в каждой точке со своими соседями:

data(2:n-1) = alpha*data(2:n-1) + (1-alpha)*0.5*(data(1:n-2)+data(3:n))

или какой-то их вариант. Да, чтобы быть более сложным, вы можете сначала преобразовать данные Фурье, а затем обрезать высокие частоты. Что-то вроде:

f = fft(data)
f(n/2+1-20:n/2+20) = zeros(40,1)
smoothed = real(ifft(f))

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

Если у вас есть Curve Fitting Toolbox, вы можете использовать smooth функция. По умолчанию используется метод скользящего среднего размера 5 (метод можно изменить). Пример:

% some noisy signal
Fs = 200; f = 5;
t = 0:1/Fs:1-1/Fs;
y = sin(2*pi*f*t) + 0.6*randn(size(t));
subplot(411)
plot(y), title('Noisy signal')

% smoothed signal
subplot(412)
plot( smooth(y, 5, 'moving') ), title('smooth')
ylim([-2 2])

Если нет, вы можете использовать свою собственную оконную функцию, используя filter функция от ядра MATLAB:

% equivalent to a moving average window
wndwSize = 5;
h = ones(1,wndwSize)/wndwSize;
subplot(413)
plot( filter(h, 1, y) ), title('filter + square window')

% Guassian
h = pdf('Normal',-floor(wndwSize/2):floor(wndwSize/2),0,1);
subplot(414)
plot( filter(h, 1, y) ), title('filter + Guassian window')

Скриншот

БПФ не плохая идея, но, вероятно, это излишне. Бегущие или скользящие средние дают, как правило, плохие результаты, и их следует избегать во всем, кроме поздней домашней работы (и белого шума).

Я бы использовал фильтрацию Савицкого-Голея (в Matlab sgolayfilt(...)). Это даст вам лучшие результаты для того, что вы ищете - некоторое локальное сглаживание при сохранении формы кривой.

-Павел

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

Сначала я бы попытался отобразить скользящее среднее по нескольким точкам, например 5 или 10. Таким образом, единственное расхождение в значениях лишь незначительно влияет на график. Конечно, это зависит от того, насколько точным должен быть график.

Другие вопросы по тегам