Find flat regions in a signal above origin (time series data)

29 vues (au cours des 30 derniers jours)
Ganesh Naik
Ganesh Naik le 23 Juin 2022
Commenté : Mathieu NOE le 24 Juin 2022
Hi all, I would like to detect flat regions in a time series data above the origin. For your reference I have attached a figure and highlighted the region of interest in green color. I have also included the sample data for the same.
I have tried the following code and got the below figure, where it identifes too many flat regions and I dont know how to adjust it to get the above results. Any help in this regard is highly appreciated.
load data.mat;
x=1:numel(data);
y=data;
z = y;
thresh = 0.05; % height threshold
% find peaks
[pks,locs] = findpeaks(z,'MinPeakProminence',thresh);
% remove signal noise between peaks
for ii = 1:length(locs)-1
zz = z(locs(ii)+1:locs(ii+1)-1);
zz(abs(zz) < thresh) = 0;
z(locs(ii)+1:locs(ii+1)-1) = zz;
end
% plot
plot(x,y);
hold on
plot(x,z);
plot(x(locs),pks,'og');
legend('original signal','modified signal','peaks')

Réponse acceptée

Mathieu NOE
Mathieu NOE le 23 Juin 2022
hello
IMHO, you don't need the peaks code (and the for loop) to make the low amplitude signals to zero
you can do it directly on the raw signal
then I added a new portion of code to detect the flat sections that are longer than min_contiguous_samples contiguous samples
so you can also discard if needed the short ones
see the demo below :
load data.mat;
x=1:numel(data);
y=data;
z = y;
thresh = 0.05; % height threshold
%% your for loop simplified :
ind = abs(z) < thresh; % NB we need ind in the new code below
z(ind) = 0;
%% new code
min_contiguous_samples = 300; % select segments only if they are at least this length => detect signal = 1
detect_signal = zeros(size(x))+0.5; % initialisation
% now define start en end point of segments above threshold
%%%%%%%%%%
% This locates the beginning /ending points of data groups
D = diff([0;ind;0]);
begin = find(D == 1);
ends = find(D == -1) - 1;
%%%%%%%%%%
length_ind = ends - begin;
ind2= length_ind>min_contiguous_samples; % check if their length is valid (above min_contiguous_samples value)
begin = begin(ind2); % selected points
ends = ends(ind2); % selected points
x2 = x(ind);
y2 = y(ind);
% define the begin / ending x, y values of raw data
x2_begin = x(begin);
y_begin = interp1(x,y,x2_begin);
x2_ends = x(ends);
y_ends = interp1(x,y,x2_ends);
for ci = 1:length(begin)
ind = (x>=x2_begin(ci) & x<=x2_ends(ci));
detect_signal(ind) = 1;
end
% plot
plot(x,y,x,z,x,detect_signal);xlim([2 2.3]*1e5);ylim([-1.5 1.5]);
legend('original signal','modified signal','flat sections detected')
  4 commentaires
Ganesh Naik
Ganesh Naik le 23 Juin 2022
Dear Mahtieu, thanks for the answer, yes I can create a vector using x2_begin and x2_ends data. I will also adjust the min_contiguous_samples as per my requirements.
Thanks and regards
Mathieu NOE
Mathieu NOE le 24 Juin 2022
ok
as always, my pleasure !

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by