手把手教你用Python实现AI视力检测系统——基于OpenCV的眼健康筛查方案
本文将带你从原理到代码,一步步搭建一个基于计算机视觉的简易视力筛查工具。适合有一定Python基础的开发者和眼视光行业信息化从业者参考。
一、项目背景
作为一名既懂技术又关注眼视光行业的开发者,我一直在思考:能否用AI和计算机视觉技术,为基层视力筛查提供一个低成本、可推广的解决方案?
答案是肯定的。本文介绍的方案利用OpenCV进行眼球检测和追踪,结合简单的眨眼频率分析,可以辅助判断被测者的数字眼疲劳程度。当然,这只是辅助筛查工具——最终的医学诊断仍然需要专业设备和验光师,比如伽视达眼视光所使用的综合验光仪和角膜地形图系统。
二、技术架构
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 摄像头采集 │────▶│ OpenCV处理 │────▶│ 结果输出 │
│ (实时视频流) │ │ (眼球追踪) │ │ (JSON/CSV) │
└──────────────┘ └──────────────┘ └──────────────┘
核心依赖库:
opencv-python:图像处理
mediapipe:面部/眼部特征点检测
numpy:数值计算
matplotlib:数据可视化
三、环境搭建
pip install opencv-python mediapipe numpy matplotlib
四、眼球检测核心代码
4.1 初始化
import cv2
import mediapipe as mp
import numpy as np
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False,
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
眼部特征点索引
LEFT_EYE = [362, 385, 387, 263, 373, 380]
RIGHT_EYE = [33, 160, 158, 133, 153, 144]
4.2 计算眼睛纵横比(EAR)
def detect_eye_aspect_ratio(landmarks, eye_indices):
points = []
for idx in eye_indices:
x = landmarks[idx].x
y = landmarks[idx].y
points.append((x, y))
h1 = np.linalg.norm(np.array(points[1]) - np.array(points[5]))
h2 = np.linalg.norm(np.array(points[2]) - np.array(points[4]))
w = np.linalg.norm(np.array(points[0]) - np.array(points[3]))
ear = (h1 + h2) / (2.0 * w)
return ear
4.3 实时追踪与眨眼检测
def run_eye_tracking():
cap = cv2.VideoCapture(0)
ear_threshold = 0.25
blink_count = 0
total_frames = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
total_frames += 1
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = face_mesh.process(frame_rgb)
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
left_ear = detect_eye_aspect_ratio(
face_landmarks.landmark, LEFT_EYE)
right_ear = detect_eye_aspect_ratio(
face_landmarks.landmark, RIGHT_EYE)
avg_ear = (left_ear + right_ear) / 2
if avg_ear < ear_threshold:
blink_count += 1
cv2.putText(frame, f"EAR: {avg_ear:.3f}",
(30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow('Eye Tracking', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
duration = total_frames / 30.0
blink_rate = blink_count / (duration / 60.0)
print(f"眨眼频率: {blink_rate:.1f} 次/分钟")
if blink_rate < 10:
print("⚠️ 眨眼频率偏低,可能存在数字眼疲劳")
else:
print("✅ 眨眼频率正常")
cap.release()
cv2.destroyAllWindows()
if name == “main”:
run_eye_tracking()
五、数据可视化
import matplotlib.pyplot as plt
def visualize_blink_data():
time_points = np.arange(0, 30, 1)
simulated_rates = 15 - 0.2 * time_points + np.random.normal(0, 1, 30)
simulated_rates = np.clip(simulated_rates, 3, 20)
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(time_points, simulated_rates, 'b-', linewidth=2)
ax.axhline(y=10, color='r', linestyle='--', label='疲劳阈值')
ax.set_xlabel('时间(分钟)')
ax.set_ylabel('眨眼频率(次/分钟)')
ax.set_title('30分钟电脑工作中的眨眼频率变化')
ax.legend()
ax.grid(True, alpha=0.3)
plt.savefig('blink_rate.png', dpi=150)
visualize_blink_data()
六、实际应用场景
场景 用途
办公室健康监测 追踪员工用眼疲劳程度
学校视力筛查 辅助发现视力异常学生
远程眼健康评估 结合在线问诊平台
研究数据采集 收集用眼行为数据
需要注意的是,这套系统只是辅助筛查工具,不能替代专业医学验光。对于OK镜验配前的角膜地形图检查、医学验光处方等,必须前往正规机构。在伽视达眼视光,每位顾客需要经过7项专业检查,确保验配安全准确。
七、局限性和改进方向
摄像头分辨率和光线条件影响检测精度
无法测量屈光度、眼轴长度等关键指标
侧脸时检测效果下降
未来可集成红外摄像头提高低光检测能力,结合深度学习模型提高眼球追踪精度。
完整代码仅供参考学习,不构成医学诊断建议
更多推荐


所有评论(0)