How to Correct the baseline shift of the signal

82 vues (au cours des 30 derniers jours)
amirhossein shahriari
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.

Réponse acceptée

Star Strider
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
amirhossein shahriari
amirhossein shahriari le 7 Juin 2018
Thank you so much . I have tried to experiment other sets of my data with savitzky filter but still seems like this band pass filter you design are way better and I can get way better average of my action potentials. So do you know why some other filters like savitzky are not helpful enough for this type of data
Star Strider
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).

Connectez-vous pour commenter.

Plus de réponses (2)

Image Analyst
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
amirhossein shahriari
amirhossein shahriari le 17 Mai 2018
thank you so much for your reply , how can I subtract the exponential fit of the data
Image Analyst
Image Analyst le 18 Mai 2018
Simply subtract yFitted from D
yCorrected = D - yFitted;

Connectez-vous pour commenter.


Image Analyst
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

Catégories

En savoir plus sur Measurements and Feature Extraction dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by