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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
| import numpy as np import cv2 from dataclasses import dataclass from typing import Dict, Tuple, Optional
@dataclass class FacialTemperature: """面部温度数据""" forehead_temp: float nose_temp: float left_cheek_temp: float right_cheek_temp: float eye_area_temp: float mean_temp: float temp_variance: float
class ThermalFaceAnalyzer: """热成像面部温度分析器""" def __init__(self): self.landmark_detector = None self.fever_threshold = 37.5 self.impairment_temp_diff = 2.0 def analyze(self, thermal_image: np.ndarray, facial_landmarks: Optional[Dict] = None) -> FacialTemperature: """分析面部温度 Args: thermal_image: 热成像图像(温度矩阵) facial_landmarks: 人脸关键点(可选) Returns: FacialTemperature: 面部温度数据 """ if facial_landmarks is None: facial_landmarks = self._estimate_landmarks(thermal_image) forehead_temp = self._extract_region_temp( thermal_image, facial_landmarks, 'forehead' ) nose_temp = self._extract_region_temp( thermal_image, facial_landmarks, 'nose' ) left_cheek_temp = self._extract_region_temp( thermal_image, facial_landmarks, 'left_cheek' ) right_cheek_temp = self._extract_region_temp( thermal_image, facial_landmarks, 'right_cheek' ) eye_area_temp = self._extract_region_temp( thermal_image, facial_landmarks, 'eye_area' ) temps = [ forehead_temp, nose_temp, left_cheek_temp, right_cheek_temp, eye_area_temp ] mean_temp = np.mean(temps) temp_variance = np.var(temps) return FacialTemperature( forehead_temp=forehead_temp, nose_temp=nose_temp, left_cheek_temp=left_cheek_temp, right_cheek_temp=right_cheek_temp, eye_area_temp=eye_area_temp, mean_temp=mean_temp, temp_variance=temp_variance ) def _estimate_landmarks(self, thermal_image: np.ndarray) -> dict: """估计人脸关键点(简化)""" h, w = thermal_image.shape center_x = w // 2 center_y = h // 2 face_width = w // 3 face_height = h // 2 return { 'forehead': (center_x, center_y - face_height // 4, face_width // 2, face_height // 8), 'nose': (center_x, center_y, face_width // 6, face_height // 6), 'left_cheek': (center_x - face_width // 3, center_y, face_width // 4, face_height // 4), 'right_cheek': (center_x + face_width // 3, center_y, face_width // 4, face_height // 4), 'eye_area': (center_x, center_y - face_height // 6, face_width // 2, face_height // 8), } def _extract_region_temp(self, image: np.ndarray, landmarks: dict, region: str) -> float: """提取区域平均温度""" x, y, w, h = landmarks[region] x = max(0, x - w // 2) y = max(0, y - h // 2) w = min(w, image.shape[1] - x) h = min(h, image.shape[0] - y) roi = image[y:y+h, x:x+w] return np.mean(roi)
class ThermalHealthMonitor: """热成像健康监控器""" def __init__(self): self.face_analyzer = ThermalFaceAnalyzer() self.temp_history = [] self.history_window = 60 def update(self, thermal_image: np.ndarray) -> dict: """更新监控状态 Returns: { 'temperature': FacialTemperature, 'is_fever': bool, 'impairment_indicators': dict, 'health_alert': str } """ temp_data = self.face_analyzer.analyze(thermal_image) self.temp_history.append(temp_data) if len(self.temp_history) > self.history_window: self.temp_history.pop(0) is_fever = temp_data.mean_temp > self.face_analyzer.fever_threshold impairment_indicators = self._detect_impairment(temp_data) health_alert = self._generate_alert(is_fever, impairment_indicators) return { 'temperature': temp_data, 'is_fever': is_fever, 'impairment_indicators': impairment_indicators, 'health_alert': health_alert } def _detect_impairment(self, temp_data: FacialTemperature) -> dict: """检测损伤指标""" temp_diff = temp_data.forehead_temp - temp_data.nose_temp fatigue_indicator = temp_data.temp_variance > 1.0 alcohol_indicator = temp_diff > self.face_analyzer.impairment_temp_diff illness_indicator = temp_data.mean_temp > 37.5 return { 'temp_diff': temp_diff, 'fatigue_indicator': fatigue_indicator, 'alcohol_indicator': alcohol_indicator, 'illness_indicator': illness_indicator, 'temp_variance': temp_data.temp_variance } def _generate_alert(self, is_fever: bool, indicators: dict) -> str: """生成健康警告""" if is_fever: return "⚠️ 发烧检测:体温异常升高,建议休息" if indicators.get('alcohol_indicator'): return "🚫 损伤检测:疑似酒精影响,禁止驾驶" if indicators.get('fatigue_indicator'): return "😴 疲劳检测:面部温度波动异常,建议休息" return "✅ 健康状态正常"
|