# print("buffer length: " + str(L)) if L > BUFFER_SIZE: data_buffer = data_buffer[-BUFFER_SIZE:] times = times[-BUFFER_SIZE:] #bpms = bpms[-BUFFER_SIZE//2:] L = BUFFER_SIZE #print(times) if L==100: fps = float(L) / (times[-1] - times[0]) cv2.putText(frame, "fps: {0:.2f}".format(fps), (30,int(frame.shape[0]*0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0), 2) # detrended_data = sp.signal_detrending(data_buffer) #print(len(detrended_data)) #print(len(times)) interpolated_data = sp.interpolation(detrended_data, times) normalized_data = sp.normalization(interpolated_data) fft_of_interest, freqs_of_interest = sp.fft(normalized_data, fps) max_arg = np.argmax(fft_of_interest) bpm = freqs_of_interest[max_arg] cv2.putText(frame, "HR: {0:.2f}".format(bpm), (int(frame.shape[1]*0.8),int(frame.shape[0]*0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0), 2) #print(detrended_data) filtered_data = sp.butter_bandpass_filter(interpolated_data, (bpm-20)/60, (bpm+20)/60, fps, order = 3) #print(fps) #filtered_data = sp.butter_bandpass_filter(interpolated_data, 0.8, 3, fps, order = 3) #write to txt file # with open("a.txt",mode = "a+") as f:
def __init__(self, heartrate, *args, **kwargs): cap = cv2.VideoCapture(path) fu = Face_utilities() sp = Signal_processing() i = 0 last_rects = None last_shape = None last_age = None last_gender = None face_detect_on = False age_gender_on = False t = time.time() #for signal_processing BUFFER_SIZE = 100 fps = 0 #for real time capture video_fps = cap.get(cv2.CAP_PROP_FPS) # for video capture print(video_fps) times = [] data_buffer = [] # data for plotting filtered_data = [] fft_of_interest = [] freqs_of_interest = [] bpm = 0 #plotting app = QtGui.QApplication([]) win = pg.GraphicsWindow(title="plotting") p1 = win.addPlot(title="FFT") p2 = win.addPlot(title="Signal") win.resize(1200, 600) def update(): p1.clear() p1.plot(np.column_stack((freqs_of_interest, fft_of_interest)), pen='g') p2.clear() p2.plot(filtered_data[20:], pen='g') app.processEvents() timer = QtCore.QTimer() timer.timeout.connect(update) timer.start(300) while True: # grab a frame -> face detection -> crop the face -> 68 facial landmarks -> get mask from those landmarks # calculate time for each loop t0 = time.time() if (i % 1 == 0): face_detect_on = True if (i % 10 == 0): age_gender_on = True else: age_gender_on = False else: face_detect_on = False ret, frame = cap.read() #frame_copy = frame.copy() if frame is None: print("End of video") cv2.destroyAllWindows() timer.stop() #sys.exit() break #display_frame, aligned_face = flow_process(frame) ret_process = fu.no_age_gender_face_process(frame, "68") if ret_process is None: cv2.putText(frame, "No face detected", (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow("frame", frame) print(time.time() - t0) cv2.destroyWindow("face") if cv2.waitKey(1) & 0xFF == ord('q'): cv2.destroyAllWindows() timer.stop() #sys.exit() break continue rects, face, shape, aligned_face, aligned_shape = ret_process (x, y, w, h) = face_utils.rect_to_bb(rects[0]) cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) #overlay_text = "%s, %s" % (gender, age) #cv2.putText(frame, overlay_text ,(x,y-15), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,0,0),2,cv2.LINE_AA) if (len(aligned_shape) == 68): cv2.rectangle( aligned_face, (aligned_shape[54][0], aligned_shape[29][1] ), #draw rectangle on right and left cheeks (aligned_shape[12][0], aligned_shape[33][1]), (0, 255, 0), 0) cv2.rectangle(aligned_face, (aligned_shape[4][0], aligned_shape[29][1]), (aligned_shape[48][0], aligned_shape[33][1]), (0, 255, 0), 0) else: #print(shape[4][1]) #print(shape[2][1]) #print(int((shape[4][1] - shape[2][1]))) cv2.rectangle( aligned_face, (aligned_shape[0][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[1][0], aligned_shape[4][1]), (0, 255, 0), 0) cv2.rectangle( aligned_face, (aligned_shape[2][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[3][0], aligned_shape[4][1]), (0, 255, 0), 0) for (x, y) in aligned_shape: cv2.circle(aligned_face, (x, y), 1, (0, 0, 255), -1) #for signal_processing ROIs = fu.ROI_extraction(aligned_face, aligned_shape) green_val = sp.extract_color(ROIs) print(green_val) data_buffer.append(green_val) times.append(time.time() - t) L = len(data_buffer) #print("buffer length: " + str(L)) if L > BUFFER_SIZE: data_buffer = data_buffer[-BUFFER_SIZE:] times = times[-BUFFER_SIZE:] #bpms = bpms[-BUFFER_SIZE//2:] L = BUFFER_SIZE #print(times) if L == 100: fps = float(L) / (times[-1] - times[0]) cv2.putText(frame, "fps: {0:.2f}".format(fps), (30, int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) # detrended_data = sp.signal_detrending(data_buffer) #print(len(detrended_data)) #print(len(times)) interpolated_data = sp.interpolation(detrended_data, times) normalized_data = sp.normalization(interpolated_data) fft_of_interest, freqs_of_interest = sp.fft( normalized_data, fps) max_arg = np.argmax(fft_of_interest) bpm = freqs_of_interest[max_arg] cv2.putText( frame, "HR: {0:.2f}".format(bpm), (int(frame.shape[1] * 0.8), int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) #print(detrended_data) filtered_data = sp.butter_bandpass_filter(interpolated_data, (bpm - 20) / 60, (bpm + 20) / 60, fps, order=3) #print(fps) #filtered_data = sp.butter_bandpass_filter(interpolated_data, 0.8, 3, fps, order = 3) #write to txt file with open("dbalt_hr_output.txt", mode="a+") as f: f.write("time: {0:.4f} ".format(times[-1]) + ", HR: {0:.2f} ".format(bpm) + "\n") # display cv2.imshow("frame", frame) cv2.imshow("face", aligned_face) #cv2.imshow("mask",mask) i = i + 1 print("time of the loop number " + str(i) + " : " + str(time.time() - t0)) # waitKey to show the frame and break loop whenever 'q' is pressed if cv2.waitKey(1) & 0xFF == ord('q'): cv2.destroyAllWindows() timer.stop() #sys.exit() break cap.release() cv2.destroyAllWindows() print("total running time: " + str(time.time() - t)) output_conv = pd.read_csv("dbalt_hr_output.txt") output_conv.to_csv('dbalt_hr_output.csv', index=None)
def bpmrpm(): count = 0 rates = [] video = True if video == False: cap = cv2.VideoCapture(0) else: cap = cv2.VideoCapture("video.webm") fu = Face_utilities() sp = Signal_processing() i = 0 last_rects = None last_shape = None last_age = None last_gender = None face_detect_on = False age_gender_on = False t = time.time() #for signal_processing BUFFER_SIZE = 100 fps = 0 #for real time capture video_fps = cap.get(cv2.CAP_PROP_FPS) # for video capture #print(video_fps) times = [] data_buffer = [] # data for plotting filtered_data = [] fft_of_interest = [] freqs_of_interest = [] bpm = 0 def update(): p1.clear() p1.plot(np.column_stack((freqs_of_interest, fft_of_interest)), pen='g') p2.clear() p2.plot(filtered_data[20:], pen='g') app.processEvents() timer = QtCore.QTimer() timer.timeout.connect(update) timer.start(300) while True: # grab a frame -> face detection -> crop the face -> 68 facial landmarks -> get mask from those landmarks # calculate time for each loop t0 = time.time() if (i % 1 == 0): face_detect_on = True if (i % 10 == 0): age_gender_on = True else: age_gender_on = False else: face_detect_on = False ret, frame = cap.read() #frame_copy = frame.copy() if frame is None: #print("End of video") cv2.destroyAllWindows() timer.stop() #sys.exit() break #display_frame, aligned_face = flow_process(frame) ret_process = fu.no_age_gender_face_process(frame, "68") if ret_process is None: cv2.putText(frame, "No face detected", (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow("frame", frame) #print(time.time()-t0) cv2.destroyWindow("face") if cv2.waitKey(1) & 0xFF == ord('q'): cv2.destroyAllWindows() timer.stop() #sys.exit() break continue rects, face, shape, aligned_face, aligned_shape = ret_process (x, y, w, h) = face_utils.rect_to_bb(rects[0]) cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) #overlay_text = "%s, %s" % (gender, age) #cv2.putText(frame, overlay_text ,(x,y-15), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,0,0),2,cv2.LINE_AA) if (len(aligned_shape) == 68): cv2.rectangle( aligned_face, (aligned_shape[54][0], aligned_shape[29][1] ), #draw rectangle on right and left cheeks (aligned_shape[12][0], aligned_shape[33][1]), (0, 255, 0), 0) cv2.rectangle(aligned_face, (aligned_shape[4][0], aligned_shape[29][1]), (aligned_shape[48][0], aligned_shape[33][1]), (0, 255, 0), 0) else: #print(shape[4][1]) #print(shape[2][1]) #print(int((shape[4][1] - shape[2][1]))) cv2.rectangle( aligned_face, (aligned_shape[0][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[1][0], aligned_shape[4][1]), (0, 255, 0), 0) cv2.rectangle( aligned_face, (aligned_shape[2][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[3][0], aligned_shape[4][1]), (0, 255, 0), 0) for (x, y) in aligned_shape: cv2.circle(aligned_face, (x, y), 1, (0, 0, 255), -1) #for signal_processing ROIs = fu.ROI_extraction(aligned_face, aligned_shape) green_val = sp.extract_color(ROIs) #print(green_val) data_buffer.append(green_val) if (video == False): times.append(time.time() - t) else: times.append((1.0 / video_fps) * i) L = len(data_buffer) #print("buffer length: " + str(L)) if L > BUFFER_SIZE: data_buffer = data_buffer[-BUFFER_SIZE:] times = times[-BUFFER_SIZE:] #bpms = bpms[-BUFFER_SIZE//2:] L = BUFFER_SIZE #print(times) if L == 100: fps = float(L) / (times[-1] - times[0]) cv2.putText(frame, "fps: {0:.2f}".format(fps), (30, int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) # detrended_data = sp.signal_detrending(data_buffer) #print(len(detrended_data)) #print(len(times)) interpolated_data = sp.interpolation(detrended_data, times) normalized_data = sp.normalization(interpolated_data) fft_of_interest, freqs_of_interest = sp.fft(normalized_data, fps) max_arg = np.argmax(fft_of_interest) bpm = freqs_of_interest[max_arg] cv2.putText( frame, "HR: {0:.2f}".format(bpm), (int(frame.shape[1] * 0.8), int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) #print(detrended_data) filtered_data = sp.butter_bandpass_filter(interpolated_data, (bpm - 20) / 60, (bpm + 20) / 60, fps, order=3) #print(fps) #filtered_data = sp.butter_bandpass_filter(interpolated_data, 0.8, 3, fps, order = 3) #write to txt file with open("a.txt", mode="a+") as f: rates.append(bpm) f.write("time: {0:.4f} ".format(times[-1]) + ", HR: {0:.2f} ".format(bpm) + "\n") # display #cv2.imshow("mask",mask) i = i + 1 #print("time of the loop number "+ str(i) +" : " + str(time.time()-t0)) count = count + 1 rates = [i for i in rates if i != 0] #print(rates) avg = sum(rates) / len(rates) resp = avg / 4.5 print("Heart Rate: ", avg) print("Respiratory Rate: ", resp) l = [] l.append(avg) l.append(resp) return l
def run(self): i = 0 last_rects = None last_shape = None last_age = None last_gender = None face_detect_on = False age_gender_on = False times = [] data_buffer = [] fft_of_interest = [] freqs_of_interest = [] valori = [] bpm = 0 # Cattura ed apertura del video path = self.record() cap = cv2.VideoCapture(path) # Se cap e' nullo vuol dire che il video non e' stato aperto correttamente if cap is None: print "Errore nell'apertura del video" return fu = Face_utilities() sp = Signal_processing() t = time.time() BUFFER_SIZE = 100 fps = 0 video_fps = cap.get(cv2.CAP_PROP_FPS) ''' Loop infinito. Ogni ciclo equivale alla lettura di un frame del video. ''' while True: t0 = time.time() if i % 1 == 0: face_detect_on = True if i % 10 == 0: age_gender_on = True else: age_gender_on = False else: face_detect_on = False # Lettura del frame ret, frame = cap.read() # Se frame e' nullo vuol dire che il video e' finito. Stop al programma. if frame is None: print "Video terminato - Nessun frame disponibile" cv2.destroyAllWindows() break # Face detection con i 68 landmarks. ret_process = fu.no_age_gender_face_process(frame, u"68") # Se ret_process e' nullo vuol dire che i landmarks non sono stati applicati correttamente # quindi nessun volto e' stato rilevato. # Controllo inutile se non si guarda il pc durante l'esecuzione dell'algoritmo. if ret_process is None: cv2.putText(frame, u"Nessun volto rilevato", (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow(u"Frequenza Cardiaca", frame) print time.time() - t0 if cv2.waitKey(1) & 0xFF == ord(u'q'): cv2.destroyAllWindows() break continue rects, face, shape, aligned_face, aligned_shape = ret_process (x, y, w, h) = face_utils.rect_to_bb(rects[0]) cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) # Disegno dei rettangoli su guancia destra e sinistra if len(aligned_shape) == 68: cv2.rectangle(aligned_face, (aligned_shape[54][0], aligned_shape[29][1]), (aligned_shape[12][0], aligned_shape[33][1]), (0, 255, 0), 0) cv2.rectangle(aligned_face, (aligned_shape[4][0], aligned_shape[29][1]), (aligned_shape[48][0], aligned_shape[33][1]), (0, 255, 0), 0) else: cv2.rectangle( aligned_face, (aligned_shape[0][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[1][0], aligned_shape[4][1]), (0, 255, 0), 0) cv2.rectangle( aligned_face, (aligned_shape[2][0], int((aligned_shape[4][1] + aligned_shape[2][1]) / 2)), (aligned_shape[3][0], aligned_shape[4][1]), (0, 255, 0), 0) for (x, y) in aligned_shape: cv2.circle(aligned_face, (x, y), 1, (0, 0, 255), -1) # Estrazione delle caratteristiche ROIs = fu.ROI_extraction(aligned_face, aligned_shape) # Estrazione del valore di verde dalle ROI green_val = sp.extract_color(ROIs) # Inserimento del valore di verde in un data buffer data_buffer.append(green_val) times.append((1.0 / video_fps) * i) L = len(data_buffer) if L > BUFFER_SIZE: data_buffer = data_buffer[-BUFFER_SIZE:] times = times[-BUFFER_SIZE:] # bpms = bpms[-BUFFER_SIZE//2:] L = BUFFER_SIZE # Non appena il buffer e' stato riempito con almeno 100 valori si inizia a stampare il battito cardiaco # Quindi dopo il passaggio di 100 frames. if L == 100: fps = float(L) / (times[-1] - times[0]) cv2.putText(frame, u"fps: {0:.2f}".format(fps), (30, int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) detrended_data = sp.signal_detrending(data_buffer) interpolated_data = sp.interpolation(detrended_data, times) normalized_data = sp.normalization(interpolated_data) fft_of_interest, freqs_of_interest = sp.fft( normalized_data, fps) max_arg = np.argmax(fft_of_interest) bpm = freqs_of_interest[max_arg] cv2.putText( frame, u"HR: {0:.2f}".format(bpm), (int(frame.shape[1] * 0.8), int(frame.shape[0] * 0.95)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) filtered_data = sp.butter_bandpass_filter(interpolated_data, (bpm - 20) / 60, (bpm + 20) / 60, fps, order=3) # Apertura (o creazione) del file result.txt e scrittura del valore del battito with open(u"result.txt", mode=u"a+") as f: f.write(u"time: {0:.4f} ".format(times[-1]) + u", HR: {0:.2f} ".format(bpm) + u"\n") # Se il battito e' significativo quindi maggiore di 70, si inserisce il valore in un array che servira' # per calcolare la media del battito finale if bpm > 65: valori.append(bpm) i = i + 1 # Allo scorrere dei frame viene stampato il numero del frame corrente print u"Frame numero " + unicode(i) + u" : " + unicode( time.time() - t0) if cv2.waitKey(1) & 0xFF == ord(u'q'): cv2.destroyAllWindows() break cap.release() cv2.destroyAllWindows() # Pepper dice la media dei valori del battito cardiaco self.tts.say("Your heart rate is " + format(np.mean(valori))) print u"Tempo totale impiegato: " + unicode(time.time() - t)