Как сгладить данные в Matlab без использования метода из любого инструментария

Я пытаюсь сгладить некоторые данные измерений в Matlab, и я так думаю, что-то упускаю. Я написал свой собственный код для создания окна Гаусса. Однако остальная часть кода скопирована с этой ссылки:

% Generate sample data.
vector = 5*(1+cosd(1:3:180)) + 2 * rand(1, 60);
hist (vector)  ;
plot(vector, 'r-', 'linewidth', 3);
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.

% Construct blurring window.
windowWidth = int16(11);
halfWidth = windowWidth / 2 ;
gaussFilter = Gaussain (-5:5, 0, 1 ) ;
gaussFilter = gaussFilter / sum(gaussFilter); % Normalize.

% Do the blur.
smoothedVector = conv(vector(halfWidth:end-halfWidth), gaussFilter) ;

% plot it.
hold on;
plot(smoothedVector, 'b-', 'linewidth', 3);

Пожалуйста, помогите мне исправить мою ошибку. Ниже приведен код для создания окна Gaussain:

function y = Gaussain ( window, mu, sigma) 
% y = exp (-((window - mu).^2)/(2*sigma^2)).* (1/(sigma * sqrt(2* pi)))  ;
y = exp (-((window - mu).^2)/(2*sigma^2)) ;
end

Я ищу решение, которое не использует какой-либо метод набора инструментов Matlab. После исправления нескольких вещей я получаю следующий вывод: введите здесь описание изображения


person User1551892    schedule 31.07.2013    source источник
comment
Какую именно проблему вы видите?   -  person Luis Mendo    schedule 31.07.2013
comment
@LuisMendo: код ведет себя не так, как должен. Я получаю некоторые выходные данные, и данные результатов не сглажены. Вы можете попробовать этот код. Его рабочий код.   -  person User1551892    schedule 31.07.2013
comment
Я сделал. Посмотрите мое решение и скажите, поможет ли оно   -  person Luis Mendo    schedule 31.07.2013


Ответы (2)


Похоже, что WindowWidth должно быть int16(11), чтобы соответствовать вашему фильтру. Или вы можете использовать WindowWidth = int16(50) с фильтром, который имеет 50 отводов вместо 11. С текущими значениями вы слишком сильно обрезаете свой выходной сигнал.

См. рисунок с WindowWidth = int16(11): http://i.stack.imgur.com/WOnW9.png

введите здесь описание изображения

person Luis Mendo    schedule 31.07.2013
comment
Попробуйте с 11, посмотрите на рисунок и скажите, ожидаемое ли это решение - person Luis Mendo; 31.07.2013
comment
Или, если вы хотите использовать 50, создайте фильтр с 50 образцами, а не с 11. - person Luis Mendo; 31.07.2013
comment
Не могли бы вы помочь мне построить фильтр, потому что я не хочу использовать встроенный метод фильтрации Matlab. Мне нужно перевести этот код на какой-то другой язык. - person User1551892; 31.07.2013
comment
Просто перейдите к своему коду, замените 50 на 11 и скажите, устраивает ли вас результат. - person Luis Mendo; 31.07.2013
comment
Почему вы изменили последнюю сюжетную линию?? Это было нормально, как это было раньше. - person Luis Mendo; 31.07.2013
comment
Я не получал никакого вывода, и из-за этого я отредактировал последнюю строку, чтобы сохранить вывод на том же рисунке. - person User1551892; 31.07.2013
comment
Ваша исходная последняя строка сработала для меня. Пожалуйста, посмотрите рисунок, который я приложил к моему решению. - person Luis Mendo; 31.07.2013
comment
да, на этот раз это сработало для меня. Я так думаю, что была какая-то другая ошибка. Спасибо за вашу помощь. У меня есть вопрос, если вы можете помочь, почему первые несколько точек не сглажены. - person User1551892; 31.07.2013
comment
Это переходный процесс, введенный фильтром. В первых выборках WindowWidth-1 фильтр еще не заполнен выборками сигнала и выдает выходные значения, смещенные к нулю. Вы просто не можете этого избежать. Что вы можете сделать, так это обрезать эту часть (в обоих сигналах), если вы не хотите ее показывать. - person Luis Mendo; 31.07.2013
comment
Большое спасибо за вашу помощь и драгоценное время. - person User1551892; 31.07.2013
comment
Добро пожаловать :-) Я предлагаю вам отредактировать свой вопрос и оставить его таким, каким он был изначально: с windowWidth = int16(11); и последней строкой plot(smoothedVector(halfWidth:end-halfWidth), 'b-', 'linewidth', 3); . Таким образом, ответ будет иметь больше смысла для тех, кто его прочитает. - person Luis Mendo; 31.07.2013
comment
Я подумал, я поправил, но может быть я забыл нажать кнопку сохранения. Спасибо - person User1551892; 01.08.2013

Я исследовал ту же тему, основав этот пост, который решил мою проблему, внес некоторые коррективы и обобщения. Большое спасибо автору предыдущего ответа, вот мой обобщенный код, который работает также с n-мерными векторами точек

% SMOOTH Simple gaussian smooth function
% vector = input vector
% width = width of the smoothing
% window = width of the window to be used in the convolution
% 
% Credits: Generalization of a post made by User1551892 and Louis Mendo on 
% StackOverflow
% Created by: Leonardo Daga, 2016
function smoothedVector = smooth(vector, width, window)

% Check arguments and fill with defaults
if nargin < 2,
    width = 2;
end

if nargin < 3,
    window = width * 5 + 1;
end

% Rotate vector to a column vector (if needed) to make the code easier
if size(vector,1) > size(vector,2)
    isColumn = true;
else
    isColumn = false;
    vector = vector';
end

% Construct blurring window.
windowWidthInt = int16(window);
halfWidth = double(windowWidthInt / 2);
gaussFilter = Gaussian(-(halfWidth-1):(halfWidth-1), 0, width/2 ) ;
gaussFilter = gaussFilter / sum(gaussFilter);

% Do the blur, enlarging the vector to blur from the start with a
% convenient value and cutting the vector back when the blurring is done
enlargedVector = [ones(window, 1)*vector(1,:);
    vector;
    ones(window, 1)*vector(end,:)];

smoothedVector = zeros(size(enlargedVector,1)-1,size(enlargedVector,2));

for i=1:size(vector,2),
    smoothedVector(:,i) = conv(enlargedVector(halfWidth:end-halfWidth,i), gaussFilter) ;
end

smoothedVector = smoothedVector(window:end-window,:);

% Rotate back the vector, if it was a row vector
if (isColumn == false)
    smoothedVector = smoothedVector';
end

end

%% Create a gaussian vector to be used for the convolution
function y = Gaussian ( window, mu, sigma)
y = exp (-((window - mu).^2)/(2*sigma^2)) ;
end

Вы можете запустить эту функцию со следующим примером кода:

% Generate sample data.
vector = [5*(1+cosd(1:3:900)) + 2 * rand(1, 300);
    5*(1+sind(1:3:900)) + 2 * rand(1, 300)];

smoothedVector = smooth(vector, 5) ;

% plot it.
figure
plot(1:size(vector,2), vector, 'r-', 1:size(smoothedVector,2), smoothedVector, 'b-');
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.

получив следующий рисунок:

Сглаженный косинус и синус с размытием по Гауссу

person Leonardo Daga    schedule 12.11.2016