|
7 | 7 | import itertools
|
8 | 8 | from scipy import interpolate, signal
|
9 | 9 | import sklearn.decomposition
|
10 |
| - |
| 10 | +from signals import * |
11 | 11 | import threading
|
12 | 12 | import Queue
|
13 | 13 |
|
@@ -46,7 +46,7 @@ def __init__(self,frameQueue,incrementalPCA,n_components,windowSize):
|
46 | 46 | self.daemon = True
|
47 | 47 | self.frameQueue = frameQueue
|
48 | 48 | self.windowSize = windowSize
|
49 |
| - if incremental: |
| 49 | + if incrementalPCA: |
50 | 50 | self.pca = sklearn.decomposition.IncrementalPCA(n_components=n_components)
|
51 | 51 | else:
|
52 | 52 | self.pca = sklearn.decomposition.PCA(n_components=n_components)
|
@@ -192,135 +192,6 @@ def get_moving_points(source_queue, do_draw=True, n_points=100):
|
192 | 192 | print "Heart rate by peak estimate: {} BPM".format(countbpm)
|
193 | 193 | ########################################################################################
|
194 | 194 |
|
195 |
| -def make_face_rects(rect): |
196 |
| - """ Given a rectangle (covering a face), return two rectangles. |
197 |
| - which cover the forehead and the area under the eyes """ |
198 |
| - x, y, w, h = rect |
199 |
| - |
200 |
| - rect1_x = x + w / 4.0 |
201 |
| - rect1_w = w / 2.0 |
202 |
| - rect1_y = y + 0.05 * h |
203 |
| - rect1_h = h * 0.9 * 0.2 |
204 |
| - |
205 |
| - rect2_x = rect1_x |
206 |
| - rect2_w = rect1_w |
207 |
| - |
208 |
| - rect2_y = y + 0.05 * h + (h * 0.9 * 0.55) |
209 |
| - rect2_h = h * 0.9 * 0.45 |
210 |
| - |
211 |
| - return ( |
212 |
| - (int(rect1_x), int(rect1_y), int(rect1_w), int(rect1_h)), |
213 |
| - (int(rect2_x), int(rect2_y), int(rect2_w), int(rect2_h)) |
214 |
| - ) |
215 |
| - |
216 |
| - |
217 |
| - |
218 |
| - |
219 |
| -def window(seq, n=2, skip=1): |
220 |
| - "Returns a sliding window (of width n) over data from the iterable" |
221 |
| - " s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... " |
222 |
| - # http://stackoverflow.com/questions/6822725/rolling-or-sliding-window-iterator-in-python |
223 |
| - |
224 |
| - it = iter(seq) |
225 |
| - result = tuple(itertools.islice(it, n)) |
226 |
| - if len(result) == n: |
227 |
| - yield result |
228 |
| - i = 0 |
229 |
| - for elem in it: |
230 |
| - result = result[1:] + (elem,) |
231 |
| - i = (i + 1) % skip |
232 |
| - if i == 0: |
233 |
| - yield result |
234 |
| - |
235 |
| - |
236 |
| -def interpolate_points(points, ratio=30.0 / 250.0, axis=0): |
237 |
| - """ Given an matrix of waveforms, interpolate them along an axis |
238 |
| - such that the number of new is multiplied by (1/ratio) """ |
239 |
| - # Define the old time space, i.e. the index of each point |
240 |
| - N = points.shape[axis] |
241 |
| - indices = np.arange(0, N) |
242 |
| - # Make an 'interpolation function' using scikit's interp1d |
243 |
| - f = interpolate.interp1d(indices, points, kind='cubic', axis=axis) |
244 |
| - # Define the new time axis, |
245 |
| - xnew = np.arange(0, N - 1, ratio) |
246 |
| - return f(xnew) |
247 |
| - |
248 |
| - |
249 |
| -def filter_unstable_movements(points): |
250 |
| - """ Filter unstable movements, e.g. coughing """ |
251 |
| - """ In the paper, they removed points which had maximum movements |
252 |
| - greater than the "mode" of rounded maximum movements. Or something. |
253 |
| - This didn't really work or make sense when we tried it, so we tried |
254 |
| - something else, then gave up... """ |
255 |
| - maximums = np.max(np.diff(points.T), axis=1) |
256 |
| - median = np.median(maximums) |
257 |
| - return points[:, maximums > median] |
258 |
| - |
259 |
| - |
260 |
| -def make_filter(order=5, low_freq=0.75, high_freq=5, sample_freq=250.0): |
261 |
| - """ Make the butterworth filter function required by the pulse paper""" |
262 |
| - nyq = 0.5 * sample_freq |
263 |
| - low = low_freq / nyq |
264 |
| - high = high_freq / nyq |
265 |
| - b, a = signal.butter(order, [low, high], btype='bandpass') |
266 |
| - return lambda x: signal.lfilter(b, a, x) |
267 |
| - |
268 |
| - |
269 |
| -def find_periodicities(X, sample_freq=250.0): |
270 |
| - """ Find the periodicity of each signal in a matrix(along axis 0), |
271 |
| - and the associated frequencies of the periods""" |
272 |
| - |
273 |
| - # We're not sure if this is quite correct, but it's what the paper |
274 |
| - # seemed to imply... |
275 |
| - # This could also be made much neater, and optimised. |
276 |
| - |
277 |
| - # Find the power spectrum of the signal (absolute fft squared) |
278 |
| - power = np.abs(np.fft.rfft(X, axis=0))**2 |
279 |
| - |
280 |
| - # Build a list of the actual frequencies corresponding to each fft index, using numpy's rfftfreq |
281 |
| - # n.b. This is where I'm having some trouble. I don't think I'm actually getting the right |
282 |
| - # numbers out for the frequencies of these signals... |
283 |
| - |
284 |
| - real_frequencies = np.fft.rfftfreq( |
285 |
| - power.shape[0], d=(1 / (sample_freq))) |
286 |
| - |
287 |
| - # Find the most powerful non-zero frequency in each signal |
288 |
| - max_indices = np.argmax(power[1:, :], axis=0) + 1 |
289 |
| - |
290 |
| - # The first haromic component of f = f*2 |
291 |
| - harmonic_indices = max_indices * 2 |
292 |
| - |
293 |
| - # Initialise arrays for return values |
294 |
| - periodicities = [] |
295 |
| - frequencies = [] |
296 |
| - i = 0 |
297 |
| - |
298 |
| - # Loop over each signal |
299 |
| - for i1, i2 in zip(max_indices, harmonic_indices): |
300 |
| - # Get the real frequency highest power component |
301 |
| - frequencies.append(real_frequencies[i1]) |
302 |
| - |
303 |
| - # Get the total power of the highest power component and its |
304 |
| - # first harmonic, as a percentage of the total signal power |
305 |
| - period_power = np.sum(power[[i1, i2], i]) |
306 |
| - total_power = np.sum(power[:, i]) |
307 |
| - percentage = period_power / total_power |
308 |
| - |
309 |
| - # That number is (apparently) the signal periodicity |
310 |
| - periodicities.append(percentage) |
311 |
| - i += 1 |
312 |
| - |
313 |
| - return np.array(frequencies), np.array(periodicities) |
314 |
| - |
315 |
| - |
316 |
| -def getpeaks(x, winsize=151): |
317 |
| - """ Return the indices of all points in a signal which are the largest poitns in |
318 |
| - a window centered on themselves """ |
319 |
| - for i, win in enumerate(window(x, winsize, 1)): |
320 |
| - ind = int(winsize / 2) |
321 |
| - if np.argmax(win) == ind: |
322 |
| - yield i + ind |
323 |
| - |
324 | 195 |
|
325 | 196 | def main(incrementalPCA=False):
|
326 | 197 | """ Run the full algorithm on a video """
|
|
0 commit comments