Commit a113197b authored by Guillaume HEUSCH's avatar Guillaume HEUSCH

rppg-pad: up to pulse

parent 63607465
Pipeline #25126 passed with stage
in 1 minute and 3 seconds
This diff is collapsed.
#!/usr/bin/env python
# encoding: utf-8
import numpy
from matplotlib import pyplot
import bob.io.base
import bob.io.image
import bob.ip.facedetect
import bob.ip.dlib
from bob.rppg.base.utils import crop_face
from bob.rppg.base.utils import build_bandpass_filter
from bob.rppg.cvpr14.extract_utils import kp66_to_mask
from bob.rppg.cvpr14.extract_utils import compute_average_colors_mask
from bob.rppg.cvpr14.filter_utils import detrend
from bob.rppg.cvpr14.filter_utils import average
def load_and_plot_frame(image):
bob.io.image.imshow(image)
def detect_and_plot_face(image):
bbox, quality = bob.ip.facedetect.detect_single_face(image)
face = crop_face(image, bbox, bbox.size[1])
bob.io.image.imshow(face)
return face
def build_and_plot_mask(face):
# get the dlib keypoints
detector = bob.ip.dlib.DlibLandmarkExtraction()
ldms = detector(face)
# image with all keypoints
display_ldms = numpy.copy(face)
for p in ldms:
bob.ip.draw.plus(display_ldms, p, radius=3, color=(255, 0, 0))
# get the mask
ldms = numpy.array(ldms)
mask_points, mask = kp66_to_mask(face, ldms, 10, False)
# image with mask keypoints and lines
face_mask = numpy.copy(face)
for k in list(range(len(mask_points))):
bob.ip.draw.cross(face_mask, (int(mask_points[k][0]), int(mask_points[k][1])), 4, (255,0,0))
for k in list(range(len(mask_points)-1)):
bob.ip.draw.line(face_mask, (mask_points[k][0], mask_points[k][1]), (mask_points[k+1][0], mask_points[k+1][1]), (0,255,0))
bob.ip.draw.line(face_mask, (mask_points[0][0], mask_points[0][1]), (mask_points[8][0], mask_points[8][1]), (0,255,0))
# display
f, (ax1, ax2) = pyplot.subplots(1, 2, sharey=True)
ax1.imshow(numpy.rollaxis(numpy.rollaxis(display_ldms, 2),2))
ax2.imshow(numpy.rollaxis(numpy.rollaxis(face_mask, 2),2))
pyplot.show()
def process_one_sequence(video):
nb_frames = video.shape[0]
face_color = numpy.zeros((nb_frames, 3), dtype='float64')
bandpass_filter = build_bandpass_filter(30, 32, plot=False)
detector = bob.ip.dlib.DlibLandmarkExtraction()
for i, frame in enumerate(video):
ldms = detector(frame)
ldms = numpy.array(ldms)
mask_points, mask = kp66_to_mask(frame, ldms, 10, False)
face_color[i] = compute_average_colors_mask(frame, mask, False)
pulse = numpy.zeros((nb_frames, 3), dtype='float64')
for i in range(3):
detrended = detrend(face_color[:, i], 300)
averaged = average(detrended, 5)
from scipy.signal import filtfilt
pulse[:, i] = filtfilt(bandpass_filter, numpy.array([1]), averaged)
colors = ['r', 'g', 'b']
for i in range(3):
f, ax = pyplot.subplots(1, 2, figsize=(20, 5))
ax[0].plot(range(face_color.shape[0]), face_color[:, i], colors[i])
ax[0].set_title('Original color signal')
ax[1].plot(range(face_color.shape[0]), pulse[:, i], colors[i])
ax[1].set_title('Pulse signal')
pyplot.show()
return pulse
def get_ltss(signal):
from scipy.fftpack import rfft
window_size = 30
nfft = 128
window_stride = int(window_size / 2)
# log-magnitude of DFT coefficients
log_mags = []
# go through windows
for w in range(0, (signal.shape[0] - window_size), window_stride):
# n is even, as a consequence the fft is as follows [y(0), Re(y(1)), Im(y(1)), ..., Re(y(n/2))]
# i.e. each coefficient, except first and last, is represented by two numbers (real + imaginary)
fft = rfft(signal[w:w+window_size], n=nfft)
print(fft)
print(fft.shape)
# the magnitude is the norm of the complex numbers, so its size is n/2 + 1
mags = numpy.zeros((int(nfft/2) + 1), dtype=numpy.float64)
# first coeff is real
if abs(fft[0]) < 1:
mags[0] = 1
else:
mags[0] = abs(fft[0])
# go through coeffs 2 to n/2
index = 1
for i in range(1, (fft.shape[0]-1), 2):
mags[index] = numpy.sqrt(fft[i]**2 + fft[i+1]**2)
if mags[index] < 1:
mags[index] = 1
index += 1
# last coeff is real too
if abs(fft[-1]) < 1:
mags[index] = 1
else:
mags[index] = abs(fft[-1])
log_mags.append(numpy.log(mags))
# build final feature
log_mags = numpy.array(log_mags)
mean = numpy.mean(log_mags, axis=0)
print(mean)
#std = numpy.std(log_mags, axis=0)
#ltss = numpy.concatenate([mean, std])
#return ltss
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment