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

31 次查看(过去 30 天)
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')

采纳的回答

Mathieu NOE
Mathieu NOE 2022-6-23
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 个评论
Ganesh Naik
Ganesh Naik 2022-6-23
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

请先登录,再进行评论。

更多回答(0 个)

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by