心率是反映人体健康状况的重要生理指标之一。传统的心率检测方法通常需要使用专业的医疗设备,如心电图仪、心率带等。而随着计算机视觉技术的发展,我们可以利用摄像头捕捉人体皮肤的颜色变化,通过分析这些变化来计算心率。本文将介绍如何使用 Python 和 OpenCV 实现这一功能。
当心脏跳动时,血液会在血管中流动,导致皮肤表面的颜色发生微小的变化。这种颜色变化主要体现在皮肤的红色通道上。我们可以通过摄像头持续捕捉面部皮肤区域的图像,提取该区域红色通道的像素值,然后对这些像素值进行处理和分析,从而得到心率信息。
具体步骤如下:
首先,确保你已经安装了以下 Python 库:
opencv-python
numpy
dlib
scipy
可以使用以下命令进行安装:
pip install opencv-python numpy dlib scipy
import cv2
import numpy as np
import dlib
from scipy import signal
import time
# 初始化人脸检测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 打开摄像头
cap = cv2.VideoCapture(0)
# 存储红色通道值的列表
red_values = []
times = []
# 开始时间
start_time = time.time()
while True:
ret, frame = cap.read()
if not ret:
break
# 转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = detector(gray)
for face in faces:
# 获取面部特征点
landmarks = predictor(gray, face)
# 提取脸颊区域(这里简单选择部分区域作为示例)
left_cheek = (landmarks.part(1).x, landmarks.part(29).y)
right_cheek = (landmarks.part(15).x, landmarks.part(29).y)
top = (landmarks.part(29).x, landmarks.part(29).y - 20)
bottom = (landmarks.part(29).x, landmarks.part(29).y + 20)
# 提取脸颊区域的图像
cheek_roi = frame[top[1]:bottom[1], left_cheek[0]:right_cheek[0]]
# 提取红色通道
red_channel = cheek_roi[:, :, 2]
# 计算红色通道的平均值
red_mean = np.mean(red_channel)
red_values.append(red_mean)
# 记录时间
current_time = time.time() - start_time
times.append(current_time)
# 绘制人脸矩形和脸颊区域
cv2.rectangle(frame, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 2)
cv2.rectangle(frame, (left_cheek[0], top[1]), (right_cheek[0], bottom[1]), (0, 0, 255), 2)
# 显示帧
cv2.imshow('Heart Rate Detection', frame)
# 按 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头并关闭窗口
cap.release()
cv2.destroyAllWindows()
# 对红色通道值进行滤波处理
b, a = signal.butter(3, [0.7, 3.0], btype='band', fs=10)
filtered_red_values = signal.filtfilt(b, a, red_values)
# 进行快速傅里叶变换
fft = np.fft.fft(filtered_red_values)
frequencies = np.fft.fftfreq(len(filtered_red_values), 1/10)
# 找到正频率部分
positive_frequencies = frequencies[frequencies >= 0]
positive_fft = 2.0/len(filtered_red_values) * np.abs(fft[frequencies >= 0])
# 找到主频对应的频率
dominant_frequency = positive_frequencies[np.argmax(positive_fft)]
# 计算心率(每分钟心跳次数)
heart_rate = dominant_frequency * 60
print(f"Estimated Heart Rate: {heart_rate:.2f} beats per minute")
dlib
库的人脸检测器和特征点预测器来定位面部区域和提取脸颊区域。scipy
库的 butter
函数进行带通滤波,去除噪声。numpy
库的 fft
函数进行快速傅里叶变换,找到主频对应的频率。通过使用 Python 和 OpenCV,我们可以实现基于计算机视觉的心率检测。这种方法简单易行,不需要额外的硬件设备,但也存在一定的局限性。在实际应用中,可以根据具体需求进行优化和改进,以提高检测的准确性。
希望本文能帮助你了解如何使用 Python 和 OpenCV 检测人体皮肤颜色变化来计算心率。如果你有任何问题或建议,欢迎在评论区留言。
请注意,上述代码中使用的 shape_predictor_68_face_landmarks.dat
文件可以从 dlib 官方网站 下载,下载后解压缩即可使用