-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathenvelop_hilbert.m
149 lines (132 loc) · 5.71 KB
/
envelop_hilbert.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
function alarm = envelop_hilbert(y,Smooth_window,threshold_style,DURATION,gr)
%% function alarm = envelop_hilbert(y,Smooth_window,threshold_style,DURATION,gr)
%% ======================= Inputs ================================ %%
% y = Raw input signal to be analyzed
% Smooth_window :this is the window length used for smoothing your signal
% in terms of number of samples
% threshold_style : set it 1 to have an adaptive threshold OR set it 0
% to manually select the threshold from a plot
% DURATION : Number of the samples that the signal should stay in terms of
% number of samples
% gr = make it 1 if you want a plot and 0 when you dont want a plot
%===========================================
% Tuning parameters for the best results;
%===========================================
% 1. DURATION is correlated to your sampling frequency, you can use a multiple
% of your sampling frequency e.g. round(0.050*SamplingFrequency)
% 2. Smooth_window is correlated to your sampling frequency, you can use a multiple
% of your sampling frequency e.g. round(0.0500*SamplingFrequency), this is
% the window length used for smoothing your signal
%% ======================= Outputs ================================== %%
% alarm : vector resembeling the active parts of the signal
%% ======================= Method =================================== %%
% Calculates the analytical signal with the help of hilbert transfrom,
% takes the envelope and smoothes the signal. Finally , with the help of an
% adaptive threshold detects the activity of the signal where at least a
% minimum number of samples with the length of
% (DURATION) Samples should stay above the threshold). The threshold is a
% computation of signal noise and activity level which is updated online.
%% Example and Demo
% To run demo mode simply execute the following line without any input;
% Example 1 :
% alarm = envelop_hilbert()
% The script generates one artificial signal and analysis that
% v = repmat([.1*ones(200,1);ones(100,1)],[10 1]); % generate true variance profile
% y = sqrt(v).*randn(size(v));
% Example 2 : For real world signals with a certain Sampling frequency
% called (Fs) (In this example a smoothing window with length 200 msec,)
% alarm = envelop_hilbert(signal,round(0.050*Fs),1,round(0.020*Fs),1)
%% Author : Hooman Sedghamiz
% hoose792@student.liu.se
% Copy right April 2013
% Edited March 2014
%%
%--------------------------- input handling ---------------------------%
if nargin < 5
gr = 1;
if nargin < 4
DURATION = 20; % default
if nargin < 3
threshold_style = 1; % default 1 , means it is done automatic
if nargin < 2
Smooth_window = 20; % default for smoothing length
if nargin < 1
v = repmat([.1*ones(200,1);ones(100,1)],[10 1]); % generate true variance profile
y = sqrt(v).*randn(size(v));
end
end
end
end
end
%% ======= calculate the analytical signal and get the envelope ====== %%
test=y(:);
analytic = hilbert(test);
env = abs(analytic);
%% =========== take the moving average of analytical signal =========== %%
env = conv(env,ones(1,Smooth_window)/Smooth_window); % smooth
env = env(:) - mean(env); % get rid of offset
env = env/max(env); % normalize
%% ====================== threshold the signal =============== %%
if threshold_style == 0
hg=figure;plot(env);title('Select a threshold on the graph')
[~,THR_SIG] =ginput(1);
close(hg);
end
% ------------------------- Threshold Style ---------------------- %
if threshold_style
THR_SIG = 4*mean(env);
end
nois = mean(env)*(1/3); % noise level
threshold = mean(env); % signal level
% ------------------- Initialize Buffers -------------------------%
thres_buf = zeros(1,length(env)-DURATION);
nois_buf = zeros(1,length(env)-DURATION);
THR_buf = zeros(1,length(env));
h=1;
alarm =zeros(1,length(env));
for i = 1:length(env)-DURATION
%------ update threshold 10% of the maximum peaks found ------------%
if env(i:i+DURATION) > THR_SIG
alarm(i) = max(env);
threshold = 0.1*mean(env(i:i+DURATION));
h=h+1;
else
% ----------- update noise --------------%
if mean(env(i:i+DURATION)) < THR_SIG
nois = mean(env(i:i+DURATION));
else
if ~isempty(nois_buf)
nois = mean(nois_buf);
end
end
end
thres_buf(i) = threshold;
nois_buf(i) = nois;
% ------------------------- update threshold -------------------------- %
if h > 1
THR_SIG = nois + 0.50*(abs(threshold - nois));
end
THR_buf(i) = THR_SIG;
end
if gr
figure,ax(1)=subplot(211);
plot(test),hold on,plot(alarm.*max(test),'r','LineWidth',2.5),
hold on,plot(THR_buf,'--g','LineWidth',2.5);
title('Raw Signal and detected Onsets of activity');
legend('Raw Signal','Detected Activity in Signal',...
'Adaptive Treshold',...
'orientation','horizontal');
grid on;axis tight;
ax(2)=subplot(212);plot(env);
hold on,plot(THR_buf,'--g','LineWidth',2.5),
hold on,plot(thres_buf,'--r','LineWidth',2),
hold on,plot(nois_buf,'--k','LineWidth',2),
title('Smoothed Envelope of the signal(Hilbert Transform)');
legend('Smoothed Envelope of the signal(Hilbert Transform)',...
'Adaptive Treshold',...
'Activity level','Noise Level','orientation','horizontal');
linkaxes(ax,'x');
zoom on;
axis tight;
grid on;
end