使用 Python 和 OpenCV 检测人体皮肤颜色变化计算心率

一、引言

心率是反映人体健康状况的重要生理指标之一。传统的心率检测方法通常需要使用专业的医疗设备,如心电图仪、心率带等。而随着计算机视觉技术的发展,我们可以利用摄像头捕捉人体皮肤的颜色变化,通过分析这些变化来计算心率。本文将介绍如何使用 Python 和 OpenCV 实现这一功能。

二、原理概述

当心脏跳动时,血液会在血管中流动,导致皮肤表面的颜色发生微小的变化。这种颜色变化主要体现在皮肤的红色通道上。我们可以通过摄像头持续捕捉面部皮肤区域的图像,提取该区域红色通道的像素值,然后对这些像素值进行处理和分析,从而得到心率信息。

具体步骤如下:

  1. 人脸检测:使用 OpenCV 的人脸检测器定位面部区域。
  2. 皮肤区域提取:在人脸区域中提取皮肤颜色的像素。
  3. 颜色变化分析:分析皮肤区域红色通道像素值随时间的变化。
  4. 心率计算:通过对颜色变化信号进行频谱分析,找到主频对应的频率,将其转换为心率。

三、代码实现

1. 安装必要的库

首先,确保你已经安装了以下 Python 库:

opencv-python
numpy
dlib
scipy

可以使用以下命令进行安装:

pip install opencv-python numpy dlib scipy

2. 代码示例

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")

3. 代码解释

  • 人脸检测:使用 dlib 库的人脸检测器和特征点预测器来定位面部区域和提取脸颊区域。
  • 颜色提取:从脸颊区域提取红色通道的像素值,并计算其平均值。
  • 信号处理:使用 scipy 库的 butter 函数进行带通滤波,去除噪声。
  • 频谱分析:使用 numpy 库的 fft 函数进行快速傅里叶变换,找到主频对应的频率。
  • 心率计算:将主频对应的频率转换为每分钟心跳次数。

四、注意事项

  1. 光照条件:光照条件对皮肤颜色的检测有很大影响,尽量在稳定的光照环境下进行检测。
  2. 运动干扰:头部的运动可能会导致检测结果不准确,尽量保持头部静止。
  3. 设备精度:由于使用摄像头进行检测,结果可能存在一定的误差,不能替代专业的医疗设备。

五、总结

通过使用 Python 和 OpenCV,我们可以实现基于计算机视觉的心率检测。这种方法简单易行,不需要额外的硬件设备,但也存在一定的局限性。在实际应用中,可以根据具体需求进行优化和改进,以提高检测的准确性。

希望本文能帮助你了解如何使用 Python 和 OpenCV 检测人体皮肤颜色变化来计算心率。如果你有任何问题或建议,欢迎在评论区留言。

请注意,上述代码中使用的 shape_predictor_68_face_landmarks.dat 文件可以从 dlib 官方网站 下载,下载后解压缩即可使用

你可能感兴趣的:(python,opencv,开发语言)