浅析Python + OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估

  

使用摄像头追踪人脸由于血液流动引起的面部色素的微小变化实现实时脉搏评估。

  

效果如下(演示视频):

  

浅析Python + OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估

  

浅析Python + OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估

  

,由于这是通过比较面部色素的变化评估脉搏所以光线,人体移动,不同角度,不同电脑摄像头等因素均会影响评估效果,实验原理是面部色素对比,识别效果存在一定误差,各位小伙伴且当娱乐,代码如下:

        进口cv2   进口numpy np   进口dlib   导入的时间   从scipy导入信号   #常量   WINDOW_TITLE='脉冲观察者'   BUFFER_MAX_SIZE=500 #的数量最近ROI平均值来存储   MAX_VALUES_TO_GRAPH=50 #的最近的ROI平均值显示脉搏图   MIN_HZ=0.83 # 50 BPM -允许的最低心率   MAX_HZ=3.33 # 200 BPM -最大允许心率   MIN_FRAMES=100 #最低心率计算之前所需的帧数。高值低,但是   #更准确。   DEBUG_MODE=False   #创建指定的巴特沃斯滤波器,并应用它。   def butterworth_filter(数据,低,高,sample_rate,订单=5):   nyquist_rate=sample_rate * 0.5   低/=nyquist_rate   高/=nyquist_rate   b, a=信号。黄油(顺序,低,高,btype=袄侄印?   返回信号。lfilter (b, a,数据)   #获取感兴趣的区域的额头。   def get_forehead_roi (face_points):   # Numpy数组中存储点我们可以很容易地得到x和y的min和max通过切片   点=np.zeros ((len (face_points.parts ()), 2))   对于我,在列举一部分(face_points.parts ()):   点[我]=(部分。x, part.y)   0]min_x=int(点(21日)   min_y=int (min(点[21日1],分[22日1]))   0]max_x=int(点(22日)   max_y=int (max(点[21日1],分[22日1]))   左=min_x   正确的=max_x   顶级=min_y - (max_x - min_x)   底=max_y * 0.98   int返回int(左)(右),int(上),int(底部)   #获取感兴趣的区域的鼻子。   def get_nose_roi (face_points):   点=np.zeros ((len (face_points.parts ()), 2))   对于我,在列举一部分(face_points.parts ()):   点[我]=(部分。x, part.y)   #鼻子和脸颊   min_x=int(点(36岁,0))   min_y=int[28日1](点)   max_x=int[45 0](点)   max_y=int[33岁,1](点)   左=min_x   正确的=max_x   顶级=min_y + (min_y * 0.02)   底=max_y + (max_y * 0.02)   int返回int(左)(右),int(上),int(底部)   #得到感兴趣的区域,包括额头,眼睛,鼻子。   #注意:额头和鼻子性能更好的结合。这可能是因为这个ROI包括眼睛,   #和眼睛闪烁噪声补充道。   def get_full_roi (face_points):   点=np.zeros ((len (face_points.parts ()), 2))   对于我,在列举一部分(face_points.parts ()):   点[我]=(部分。x, part.y)   #只保留点对应的内部特征脸(如:嘴、鼻子、眼睛、眉毛)。   #点概述下巴被丢弃。   min_x=int (np。最小值(点(17:47 0)))   min_y=int (np。最小值(点(17:47 1)))   max_x=int (np。马克斯(点(17:47 0)))   max_y=int (np。马克斯(点(17:47 1)))   center_x=min_x + (max_x - min_x)/2   左=min_x + int ((center_x - min_x) * 0.15)   正确的=max_x - int ((max_x - center_x) * 0.15)   顶级=int (min_y * 0.88)   底=max_y   int返回int(左)(右),int(上),int(底部)   def sliding_window_demean (signal_values num_windows):   window_size=int(圆(len (signal_values)/num_windows))   贬低=np.zeros (signal_values.shape)   因为我在范围(0,len (signal_values) window_size):   如果我+ window_size比;len (signal_values):   window_size=len (signal_values)——我   curr_slice=signal_values[我+ window_size]   如果DEBUG_MODE和curr_slice。大?=0:   打印(“空片:大?{0},我={1},window_size={2} ' .format (signal_values。大小,我window_size))   打印(curr_slice)   激怒了[我+ window_size]=curr_slice - np.mean (curr_slice)   返回贬低   #平均像素的绿色两个数组的值   def get_avg (roi1 roi2):   roi1_green=roi1 (:: 1)   roi2_green=roi2 (:: 1)   avg=(np.mean (roi1_green) + np.mean (roi2_green))/2.0   返回avg   #返回从列表中最大绝对值   def get_max_abs (lst):   返回马克斯(max (lst)、min (lst))   #将心率在GUI窗口图。   def draw_graph (signal_values graph_width graph_height):   图=np。0 ((np.uint8 graph_height graph_width 3))   scale_factor_x=(graph_width)/MAX_VALUES_TO_GRAPH浮动   #自动重新调节垂直基于绝对值最大的价值   max_abs=get_max_abs (signal_values)   scale_factor_y=(浮动(graph_height)/2.0)/max_abs   midpoint_y=graph_height/2   因为我在范围(0,len (signal_values) - 1):   我* scale_factor_x curr_x=int ()   curr_y=int (midpoint_y + signal_values[我]* scale_factor_y)   next_x=int ((i + 1) * scale_factor_x)   next_y=int (midpoint_y + signal_values (i + 1) * scale_factor_y)   cv2。线(图(curr_x curr_y), (next_x next_y),颜色=(0 255 0),厚度=1)   返回图   #了心率的文本在GUI窗口(BPM)。   def draw_bpm (bpm_str bpm_width bpm_height):   bpm_display=np。0 ((np.uint8 bpm_height bpm_width 3))   bpm_text_size bpm_text_base=cv2。getTextSize (bpm_str fontFace=cv2。FONT_HERSHEY_DUPLEX fontScale=2.7,   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

浅析Python + OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估