-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy paththresholding.py
More file actions
150 lines (116 loc) · 3.58 KB
/
thresholding.py
File metadata and controls
150 lines (116 loc) · 3.58 KB
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
150
"""
=====================
Thresholding
=====================
Otsu method: https://en.wikipedia.org/wiki/Otsu%27s_method
Otsu method divides the signal into two classes, the background and the foreground.
It is a very simple method, but it is very effective. It is based on the histogram
of the signal. The method is based on the assumption that the signal contains two classes
of values following bi-modal histogram (foreground and background). The algorithm calculates
the optimum threshold separating the two classes so that their intra-class variance is minimal.
"""
print(__doc__)
# %%
import csv
import numpy as np
import matplotlib.pyplot as plt
results = []
with open('data/blinking.dat') as inputfile:
for row in csv.reader(inputfile):
rows = row[0].split(' ')
results.append(rows[1:])
print ('Length:'+str(len(results)))
# Convert the file into numpy array of ints.
results = np.asarray(results)
results = results.astype(int)
# Strip from the signal anything you want
eeg = results[1:,1]
print (eeg)
plt.plot(eeg,'r', label='EEG')
plt.xlabel('t');
plt.ylabel('eeg(t)');
plt.title(r'EEG Signal') # r'' representa un raw string que no tiene caracteres especiales
plt.ylim([-2000, 2000]);
plt.xlim([0,len(eeg)])
plt.show()
# Otsu method provides the umbralization vlaue
# %%
val = [-40,-50,-45,-25,-44,-33,-45,-15,-23,-45,96,97,94,92,93,93,92,93,94,87,88]
val = eeg
signal = np.asarray(val)
def w1(p,t):
s = p[0:t].sum()
return s
def w2(p,t):
s = p[t:].sum()
return s
def mu1(p,t):
val = 0
for i in range(0,t):
val = val + (i * p[i])/(w1(p,t))
return val
def mu2(h,t):
val = 0
for i in range(t,len(p)):
val = val + (i * p[i])/(w2(p,t))
return val
def sigma1(h,t):
val = 0
for i in range(0,t):
val = val + ((i - mu1(h,t))**2) * h[i] / w1(h,t)
return val
def sigma2(h,t):
val = 0
for i in range(0,t):
val = val + ((i - mu2(h,t))**2) * h[i] / w2(h,t)
return val
h = np.histogram(signal,bins=np.ptp(signal))
bins = h[1]
p = h[0] / len(signal)
prob = p
maxval = 0
maxt = 0
sigmas = []
for t in range(len(prob)):
sigmab = w1(prob,t) * w2(prob,t) * (mu1(prob,t) - mu2(prob,t))**2
sigmas.append(sigmab)
maxt = np.where(sigmas == np.amax(sigmas))
#otsuvalue = otsu(signal)
otsuvalue = bins[int(maxt[0].mean())]
print( f'Otsu thresholding:{otsuvalue}')
#reval = signal[signal>otsuvalue]
# %%
import matplotlib.pyplot as plt
plt.plot(bins[:-1], p*20000, linewidth=2, color='r')
plt.plot(bins[:-1], sigmas)
plt.axvline(x=otsuvalue, color='k', linestyle='--')
plt.xlim([bins.min(), bins.max()])
plt.show()
#threshold = otsu(eeg)
# %%
# This is wikipedia's implementation of Otsu's method:
def otsu_intraclass_variance(image, threshold):
"""
Otsu’s intra-class variance.
If all pixels are above or below the threshold, this will throw a warning that can safely be ignored.
"""
return np.nansum([
np.mean(cls) * np.var(image[cls])
# weight · intra-class variance
for cls in [image>=threshold,image<threshold]
])
# NaNs only arise if the class is empty, in which case the contribution should be zero, which `nansum` accomplishes.
otsu_threshold = min(
range( np.min(eeg)+1, np.max(eeg) ),
key = lambda th: otsu_intraclass_variance(eeg,th)
)
print( f'Otsu thresholding:{otsuvalue}')
plt.plot(eeg,'r', label='EEG')
plt.axhline(y=otsu_threshold, color='k', linestyle='--')
plt.xlabel('t');
plt.ylabel('eeg(t)');
plt.title(r'EEG Signal') # r'' representa un raw string que no tiene caracteres especiales
plt.ylim([-500, 500]);
plt.xlim([0,len(eeg)])
plt.show()
# %%