HRV睡眠剥夺驾驶员警觉性分类:受控实验验证机器学习可行性

HRV睡眠剥夺驾驶员警觉性分类:受控实验验证机器学习可行性

论文信息

项目 内容
标题 Tracking Vigilance While Driving: Pilot Study of Heart Rate Variability Classification Under a Controlled Sleep-Deprivation Protocol
作者 (详见原文)
期刊 Sensors 2026, 26(19), 6104 (MDPI)
发布 2026年9月25日
链接 https://www.mdpi.com/1424-8220/26/19/6104

核心创新

首次在高度受控睡眠剥夺协议下,结合模拟驾驶和机器学习,验证HRV(心率变异性)可以可靠分类”休息充分”与”疲劳”状态。实验严格控制光照、姿势和饮食三个关键干扰变量,为DMS中HRV辅助检测提供了方法学基准。

实验设计

受控协议

控制变量 传统研究 本研究
光照暴露 未控制 ✅ 固定
姿势变化 未控制 ✅ 固定坐姿
饮食摄入 未控制 ✅ 统一
睡眠剥夺 自我报告 ✅ 实验室监督
验证指标 单一(KSS) ✅ 三重(KSS+VAS+PVT)

实验流程

graph LR
    A[充分睡眠8h] --> B[基线驾驶1: 休息状态]
    B --> C[PVT测试 + KSS/VAS评分]
    C --> D[睡眠剥夺24h]
    D --> E[驾驶2: 疲劳状态]
    E --> F[PVT测试 + KSS/VAS评分]
    F --> G[HRV数据对比分析]

验证指标体系

指标 类型 测量时机 作用
KSS (Karolinska Sleepiness Scale) 主观 驾驶后 自我报告困倦
VAS (Visual Analog Scale) 主观 驾驶后 困倦视觉评估
PVT (Psychomotor Vigilance Task) 客观 驾驶前 反应时间基线
HRV (Heart Rate Variability) 客观 驾驶中 自主神经系统活动

HRV特征工程

时域特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
from scipy.stats import skew, kurtosis

def compute_time_domain_hrv(rr_intervals):
"""
计算时域HRV特征

Args:
rr_intervals: RR间期序列(秒), shape=(N,)

Returns:
features: 时域特征字典
"""
rr = np.array(rr_intervals)
diff_rr = np.diff(rr) * 1000 # 转换为ms

features = {
# 1. 基本统计
"mean_rr": np.mean(rr), # 平均RR间期
"sdrr": np.std(rr), # RR间期标准差
"cv_rr": np.std(rr) / np.mean(rr), # 变异系数

# 2. 差异统计
"rmssd": np.sqrt(np.mean(diff_rr**2)), # 相邻RR差值均方根
"sdsd": np.std(diff_rr), # 相邻RR差值标准差
"nn50": np.sum(np.abs(diff_rr) > 50), # 差值>50ms的数量
"pnn50": np.sum(np.abs(diff_rr) > 50) / len(diff_rr) * 100, # pNN50百分比
"nn20": np.sum(np.abs(diff_rr) > 20), # 差值>20ms
"pnn20": np.sum(np.abs(diff_rr) > 20) / len(diff_rr) * 100,

# 3. 分布特征
"skew_rr": skew(rr), # 偏度
"kurt_rr": kurtosis(rr), # 峰度
}

return features


# 模拟休息态 vs 疲劳态RR间期
np.random.seed(42)

# 休息态: 高HRV(副交感主导)
rr_rested = np.random.normal(0.85, 0.08, 1800) # mean=850ms, std=80ms

# 疲劳态: 低HRV(交感主导)
rr_tired = np.random.normal(0.75, 0.04, 1800) # mean=750ms, std=40ms

feat_rested = compute_time_domain_hrv(rr_rested)
feat_tired = compute_time_domain_hrv(rr_tired)

print("=== 时域HRV对比 ===")
print(f"{'指标':<15} {'休息态':>10} {'疲劳态':>10} {'变化':>10}")
print("-" * 50)
for key in feat_rested:
change = (feat_tired[key] - feat_rested[key]) / feat_rested[key] * 100
print(f"{key:<15} {feat_rested[key]:>10.3f} {feat_tired[key]:>10.3f} {change:>+9.1f}%")

频域特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from scipy.signal import welch

def compute_frequency_domain_hrv(rr_intervals, fs=4.0):
"""
计算频域HRV特征

频段定义:
- VLF (极低频): 0.003-0.04 Hz - 体温调节
- LF (低频): 0.04-0.15 Hz - 交感+副交感
- HF (高频): 0.15-0.40 Hz - 副交感(呼吸性)
- LF/HF: 交感-副交感平衡指数

Args:
rr_intervals: RR间期序列
fs: 重采样频率 (4 Hz标准)
"""
# 重采样为等间隔信号
rr = np.array(rr_intervals)
t = np.cumsum(rr)
t_uniform = np.arange(t[0], t[-1], 1/fs)
rr_resampled = np.interp(t_uniform, t, rr)

# Welch功率谱密度
freqs, psd = welch(rr_resampled, fs=fs, nperseg=256)

# 频段功率
vlf_mask = (freqs >= 0.003) & (freqs < 0.04)
lf_mask = (freqs >= 0.04) & (freqs < 0.15)
hf_mask = (freqs >= 0.15) & (freqs < 0.40)

vlf_power = np.trapz(psd[vlf_mask], freqs[vlf_mask])
lf_power = np.trapz(psd[lf_mask], freqs[lf_mask])
hf_power = np.trapz(psd[hf_mask], freqs[hf_mask])
total_power = vlf_power + lf_power + hf_power

features = {
"total_power": total_power,
"vlf_power": vlf_power,
"lf_power": lf_power,
"hf_power": hf_power,
"lf_hf_ratio": lf_power / (hf_power + 1e-10),
"lf_nu": lf_power / (lf_power + hf_power) * 100, # 标准化LF
"hf_nu": hf_power / (lf_power + hf_power) * 100, # 标准化HF
}

return features


feat_rested_freq = compute_frequency_domain_hrv(rr_rested)
feat_tired_freq = compute_frequency_domain_hrv(rr_tired)

print("\n=== 频域HRV对比 ===")
print(f"{'指标':<15} {'休息态':>12} {'疲劳态':>12} {'变化':>10}")
print("-" * 55)
for key in feat_rested_freq:
change = (feat_tired_freq[key] - feat_rested_freq[key]) / feat_rested_freq[key] * 100
print(f"{key:<15} {feat_rested_freq[key]:>12.3f} {feat_tired_freq[key]:>12.3f} {change:>+9.1f}%")

关键HRV指标预期变化

指标 休息态 疲劳态 变化方向 生理含义
SDRR 高(60-100ms) 低(20-50ms) ↓ 总体变异降低
RMSSD 高(30-80ms) 低(10-30ms) ↓ 副交感减弱
pNN50 高(15-40%) 低(0-10%) ↓ 副交感减弱
LF/HF 低(0.5-2.0) 高(2.0-6.0) ↑ 交感优势
HF power 高 低 ↓ 呼吸性HRV减弱
Total Power 高 低 ↓ 自主神经系统总活动降低

机器学习分类器

分类管道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

class HRVDriverStateClassifier:
"""
HRV驾驶员状态分类器

支持三种分类器:
1. Random Forest
2. Gradient Boosting
3. SVM (RBF核)

二分类: Rested vs Tired
"""

def __init__(self, classifier="rf"):
self.scaler = StandardScaler()

if classifier == "rf":
self.model = RandomForestClassifier(
n_estimators=100, max_depth=8, random_state=42
)
elif classifier == "gb":
self.model = GradientBoostingClassifier(
n_estimators=100, max_depth=4, random_state=42
)
elif classifier == "svm":
self.model = SVC(kernel="rbf", C=1.0, gamma="scale")

self.pipeline = Pipeline([
("scaler", self.scaler),
("classifier", self.model)
])

def extract_features(self, rr_intervals):
"""提取完整HRV特征集"""
time_features = compute_time_domain_hrv(rr_intervals)
freq_features = compute_frequency_domain_hrv(rr_intervals)
return {**time_features, **freq_features}

def train(self, rr_samples, labels):
"""
训练分类器

Args:
rr_samples: RR间期列表, 每个元素是一段RR序列
labels: 0=休息, 1=疲劳
"""
# 特征提取
feature_matrix = []
for rr in rr_samples:
features = self.extract_features(rr)
feature_matrix.append(list(features.values()))

X = np.array(feature_matrix)
y = np.array(labels)

# 交叉验证
scores = cross_val_score(self.pipeline, X, y, cv=5, scoring="accuracy")
print(f"交叉验证准确率: {scores.mean():.3f} ± {scores.std():.3f}")

# 训练
self.pipeline.fit(X, y)
return scores


# 生成模拟训练数据
np.random.seed(42)
n_samples = 200 # 每类100个样本

# 休息态样本
rested_samples = []
for _ in range(n_samples // 2):
rr = np.random.normal(0.85, np.random.uniform(0.06, 0.10), 1800)
rested_samples.append(rr)

# 疲劳态样本
tired_samples = []
for _ in range(n_samples // 2):
rr = np.random.normal(0.75, np.random.uniform(0.03, 0.05), 1800)
tired_samples.append(rr)

all_samples = rested_samples + tired_samples
all_labels = [0] * (n_samples // 2) + [1] * (n_samples // 2)

# 训练三个分类器
for clf_name in ["rf", "gb", "svm"]:
print(f"\n=== {clf_name.upper()} 分类器 ===")
classifier = HRVDriverStateClassifier(classifier=clf_name)
scores = classifier.train(all_samples, all_labels)

在DMS中的集成方案

多模态融合:HRV + 摄像头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class MultimodalDrowsinessDetector:
"""
多模态疲劳检测: 摄像头PERCLOS + HRV

HRV提供:
- 比摄像头早5-10分钟预警(自主神经变化先于行为变化)
- 在黑暗/遮挡场景下作为备选

摄像头提供:
- 直接行为证据(闭眼/点头)
- 高时间分辨率
"""

def __init__(self):
self.hrv_classifier = HRVDriverStateClassifier(classifier="rf")
self.camera_detector = None # 已有摄像头DMS
self.alert_threshold = 0.6

def detect(self, camera_data, hrv_data):
"""
多模态疲劳检测

Args:
camera_data: 摄像头DMS输出 {perclos, blink_rate, head_pose}
hrv_data: HRV数据 {rr_intervals, hrv_features}

Returns:
alert: 警报决策
"""
# 摄像头检测结果
camera_drowsy = camera_data.get("perclos", 0) > 0.15

# HRV检测结果
hrv_features = self.hrv_classifier.extract_features(
hrv_data["rr_intervals"]
)
feature_vector = np.array(list(hrv_features.values())).reshape(1, -1)
hrv_drowsy = self.hrv_classifier.pipeline.predict(feature_vector)[0]
hrv_confidence = self.hrv_classifier.pipeline.predict_proba(
feature_vector
)[0, 1]

# 融合决策
if camera_drowsy and hrv_drowsy:
alert_level = "CRITICAL"
confidence = 0.95
elif camera_drowsy and not hrv_drowsy:
alert_level = "WARNING" # 可能短暂闭眼
confidence = 0.70
elif not camera_drowsy and hrv_drowsy:
alert_level = "EARLY_WARNING" # HRV提前预警
confidence = hrv_confidence
else:
alert_level = "NORMAL"
confidence = 0.90

return {
"alert_level": alert_level,
"confidence": confidence,
"camera_drowsy": camera_drowsy,
"hrv_drowsy": bool(hrv_drowsy),
"hrv_confidence": float(hrv_confidence)
}

早期预警时间优势

检测方法 检测时刻 预警提前
摄像头PERCLOS 闭眼趋势持续30-60s后 基准
摄像头点头 头部下垂发生后 +0-2s
HRV特征变化 自主神经系统变化 +5-10分钟

硬件部署方案

方案1: 方向盘电极ECG

组件 规格 成本
方向盘电极 银氯化银薄膜电极 $2
ECG AFE MAX30003 $5
MCU 已有(QCS8255) $0
总计 — $7

方案2: 座椅PPG

组件 规格 成本
PPG传感器 MAX30102 (绿光+IR) $3
信号调理 运放+滤波 $1
总计 — $4

方案3: 智能手表/手环

来源 HRV精度 延迟 集成度
Oura Ring 5 高 5-10s 蓝牙
Apple Watch 高 5s 蓝牙
Garmin 高 5s 蓝牙

IMS开发启示

1. HRV在DMS中的定位

角色 主要检测 预警时间 精度
HRV: 早期预警 自主神经系统疲劳积累 提前5-10分钟 中(75-85%)
摄像头: 行为确认 闭眼/点头/分心 实时 高(90%+)
融合: 最佳方案 双模态验证 早期+实时 最高(95%)

2. 实施优先级

阶段 方案 预期效果 时间
PoC 方向盘电极ECG 验证HRV-疲劳关联 2026 Q4
原型 座椅PPG+摄像头融合 早期预警系统 2027 Q1
验证 100车内部署测试 量化预警提前时间 2027 Q2
量产 集成QCS8255 软件定义HRV检测 2027 Q3

3. 与统一EEG方案的协同

graph LR
    A[HRV: 5-10分钟预警] --> B{疲劳确认?}
    B -->|是| C[EEG: 30-60秒精确分类]
    B -->|否| D[继续监测]
    C --> E{疲劳等级?}
    E -->|微睡眠| F[摄像头: 实时行为确认]
    E -->|深度疲劳| G[立即警报]
    F --> H[多模态决策]
    G --> H

结论

核心贡献

  1. 受控实验设计 — 首次严格控制光照/姿势/饮食干扰,提高HRV-疲劳因果关联可信度
  2. 三重验证 — KSS+VAS+PVT联合验证,比单一主观评分更可靠
  3. 机器学习可行 — HRV特征可有效分类休息/疲劳状态,为DMS辅助检测提供基础

局限性

  1. 样本量小 — 试点研究,需扩大验证
  2. 模拟驾驶 — 非真实道路,需实车测试
  3. 个体差异 — HRV基线因人而异,需个性化标定
  4. 信号质量 — 车内电磁干扰可能影响ECG质量

论文: Sensors 2026, 26(19), 6104, MDPI


HRV睡眠剥夺驾驶员警觉性分类:受控实验验证机器学习可行性
https://dapalm.com/2026/09/30/2026-09-30-06-hrv-sleep-deprivation-driver-vigilance-ml-ims/
作者
Mars
发布于
2026年9月30日
许可协议