How to Correct the baseline shift of the signal
82 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
amirhossein shahriari
le 15 Mai 2018
Rouvert : Star Strider
le 8 Juin 2018
I am trying to correct the baseline of the signal (picture attached) by using a single exponential curve fit to adjust the baseline.
The data file is attached as well.
0 commentaires
Réponse acceptée
Star Strider
le 16 Mai 2018
Modifié(e) : Star Strider
le 16 Mai 2018
I always use discrete filters to eliminate baseline drift, baseline offset, and high-frequency noise.
Try this:
[D,S] = xlsread('Book1GA.xls');
Tcl = regexp(S, '(\d\.\d+)', 'match'); % Time Values (Cell Array)
Tch = cell2mat([Tcl{:}]'); % Time Values (Character Array)
Tv = str2num(Tch); % Time Vector (Double)
L = numel(Tv);
Ts = mean(diff(Tv)); % Sampling Interval
Tsd = std(diff(Tv));
Fs = 1/Ts; % Sampling Frequency
Fn = Fs/2; % Nyquist Frequency
Dmd = D - mean(D);
FT_D = fft(Dmd)/L;
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv);
figure(1)
plot(Fv, abs(FT_D(Iv))*2)
grid
axis([0 25 ylim])
set(gca, 'XMinorTick','on')
xlabel('Frequency')
Wp = [2.1 15.0]/Fn; % Passband Frequency (Normalised)
Ws = [1.8 18.0]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 50; % Stopband Ripple (dB)
[n,Ws] = cheb2ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby2(n,Rs,Ws); % Filter Design, Sepcify Bandpass
[sos,g] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(2)
freqz(sos, 2^16, Fs) % Filter Bode Plot
D_Filtered = filtfilt(sos, g, D); % Filter Signal
figure(3)
plot(Tv, D_Filtered)
grid
xlabel('Time')
Experiment witht he passband and stopband frequencies to get the result you want. Note that in a bandpass filter, the passband frequency limnits must always be within the stopband frequency limits.
EDIT — Adding the plot:
10 commentaires
Star Strider
le 7 Juin 2018
As always, my pleasure.
The Savitzky-Golay filter is primarily used for curve-smoothing (or at least that is my experience). It is quite good for that purpose. However for signal processing, I find it difficult to design functional filters with it, and prefer using frequency-selective filters such as those I use here. The Tips (link) section of the documentation describes the use of the Savitzky-Golay filter much better than I can.
Also, if you have R2018a or later, the bandpass (link) and related functions make filter design significantly easier. If you use the ‘d’ output from it with an IIR filter, remember to use the filtfilt function to do the actual filtering, not the filter function as suggested in the documentation (that I consider to be an error).
Plus de réponses (2)
Image Analyst
le 16 Mai 2018
You might use fitnlm(), if you have the Statistics and Machine Learning Toolbox
[D, S] = xlsread('Book1GA.xls');
Tcl = regexp(S, '(\d\.\d+)', 'match'); % Time Values (Cell Array)
Tch = cell2mat([Tcl{:}]'); % Time Values (Character Array)
Tv = str2num(Tch); % Thanks to Star for figuring out how to get the time!
plot(Tv, D, 'b-')
grid on;
erodedSignal = imerode(D, ones(51, 1));
hold on;
plot(Tv, erodedSignal, 'r-', 'LineWidth', 2);
X = Tv;
Y = erodedSignal;
% Convert X and Y into a table, which is the form fitnlm() likes the input data to be in.
tbl = table(X, Y);
% Define the model as Y = a + exp(-b*x)
% Note how this "x" of modelfun is related to big X and big Y.
% x((:, 1) is actually X and x(:, 2) is actually Y - the first and second columns of the table.
modelfun = @(b,x) b(1) + b(2) * exp(-b(3)*x(:, 1));
beta0 = [10000, 300, 1]; % Guess values to start with. Just make your best guess.
% Now the next line is where the actual model computation is done.
mdl = fitnlm(tbl, modelfun, beta0);
% Now the model creation is done and the coefficients have been determined.
% YAY!!!!
% Extract the coefficient values from the the model object.
% The actual coefficients are in the "Estimate" column of the "Coefficients" table that's part of the mode.
coefficients = mdl.Coefficients{:, 'Estimate'}
% Create smoothed/regressed data using the model:
yFitted = coefficients(1) + coefficients(2) * exp(-coefficients(3)*X);
% Now we're done and we can plot the smooth model as a red line going through the noisy blue markers.
hold on;
plot(X, yFitted, 'k-', 'LineWidth', 3);
grid on;
title('Exponential Regression with fitnlm()', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
legendHandle = legend('Original Signal', 'Baseline', 'Fitted Y', 'Location', 'north');
legendHandle.FontSize = 25;
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
The black line is the exponential fit of the bottoms of the signal.
2 commentaires
Image Analyst
le 16 Mai 2018
Well you can try imerode() or movmin(). Or you can try some more sophisticated spectroscopic methods. It would have been easy for people to try things if you had attached your data. Try this link
0 commentaires
Voir également
Catégories
En savoir plus sur Measurements and Feature Extraction dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!