You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求基于Tracking.js的纯JavaScript眨眼检测实现方案(兼容其他JS库)

嘿,我来帮你搞定这个眨眼检测的问题!既然你已经能用Tracking.js拿到眼睛的矩形框了,接下来的核心就是通过眼睛的高度变化来判断是否眨眼——毕竟眨眼时眼睛会快速闭合再张开,垂直高度会明显缩水。下面是具体的实现方案,准确率基本能达到你要的70%-80%,还可以通过小技巧进一步优化:

基于Tracking.js的眨眼检测实现方案

核心逻辑

眨眼的本质是眼睛垂直高度在短时间内急剧下降,然后快速恢复。我们可以通过持续记录眼睛矩形的高度,对比基准高度(正常睁眼时的高度)的比值,再结合连续帧的判断,来避免误判,最终检测出眨眼动作。

具体步骤实现

1. 先初始化必要的变量

我们需要存储基准高度、采样帧计数、眨眼判定的阈值等,用来处理每帧数据:

// 存储眼睛基准高度(取前N帧的平均值,避免初始帧的误差)
let eyeBaseHeight = 0;
// 记录已采样的帧数,用来计算基准高度
let sampleFrames = 0;
// 采样阈值:比如前10帧用来初始化基准高度,确保数据稳定
const SAMPLE_THRESHOLD = 10;
// 眨眼判定阈值:当当前高度低于基准的45%左右时,认为接近闭眼状态
const BLINK_RATIO_THRESHOLD = 0.45;
// 连续低帧计数:需要连续2-3帧都低于阈值才判定为眨眼,避免偶然波动的误判
let lowHeightFrameCount = 0;
// 眨眼触发标记,防止短时间内重复触发
let blinkDetected = false;

2. 在track回调中加入眨眼判断逻辑

把下面的代码整合到你已有的track事件回调里,替换或补充你原有的处理逻辑:

tracker.on('track', function(event) {
  // 如果没检测到眼睛,重置计数(比如用户转头、遮挡了)
  if (event.data.length === 0) {
    lowHeightFrameCount = 0;
    return;
  }

  event.data.forEach(function(rect) {
    // 保留你原有的绘制矩形逻辑
    window.plot(rect.x, rect.y, rect.width, rect.height);

    const currentEyeHeight = rect.height;
    // 第一步:初始化基准高度,取前10帧的平均值
    if (sampleFrames < SAMPLE_THRESHOLD) {
      eyeBaseHeight += currentEyeHeight;
      sampleFrames++;
      // 采样完成后计算平均值
      if (sampleFrames === SAMPLE_THRESHOLD) {
        eyeBaseHeight = eyeBaseHeight / SAMPLE_THRESHOLD;
        console.log('基准眼睛高度初始化完成:', eyeBaseHeight);
      }
      return;
    }

    // 第二步:计算当前高度和基准高度的比值
    const heightRatio = currentEyeHeight / eyeBaseHeight;

    // 第三步:判断是否是眨眼动作
    if (heightRatio < BLINK_RATIO_THRESHOLD) {
      lowHeightFrameCount++;
      // 连续2帧以上低于阈值,且还没触发过眨眼,判定为有效眨眼
      if (lowHeightFrameCount >= 2 && !blinkDetected) {
        blinkDetected = true;
        console.log('眨眼检测到了!');
        // 这里可以添加你的自定义逻辑,比如触发事件、更新页面UI等
        // 例如:document.dispatchEvent(new CustomEvent('blinkDetected'));
      }
    } else {
      // 恢复正常高度,重置计数和标记
      lowHeightFrameCount = 0;
      blinkDetected = false;
    }
  });
});

3. 几个提升准确率的小技巧

  • 动态更新基准高度:如果用户使用过程中调整了姿势(比如凑近屏幕),眼睛高度会变化,可以每隔300帧重新计算一次基准,或者当连续20帧的高度都高于当前基准的1.2倍时,自动更新基准值。
  • 过滤异常值:如果某帧的眼睛高度突然变得极小(比如1-2px),大概率是检测错误,直接忽略这帧的数据。
  • 双眼协同判断:如果Tracking.js同时检测到左右眼,取两者高度的平均值来计算比值,这样比单眼判断更稳定,减少误判概率。

替代方案(如果Tracking.js稳定性不够)

要是Tracking.js的眼睛检测偶尔会飘,推荐试试face-api.js——它基于TensorFlow.js,能精准检测人脸关键点(包括上下眼睑的位置),计算眼睛的**眼宽眼高比(EAR)**来判断眨眼,准确率会更高。核心逻辑大概是这样:

// 先加载模型(可以本地部署模型文件,或者用公开的CDN)
await faceapi.loadFaceLandmarkModel('/models');

// 检测人脸关键点
const detections = await faceapi.detectFaceLandmarks(document.getElementById('img'));
const leftEye = detections.landmarks.getLeftEye();
const rightEye = detections.landmarks.getRightEye();

// 计算单眼的眼宽眼高比
function calculateEyeAspectRatio(eye) {
  // 计算垂直方向的两个距离
  const vertical1 = faceapi.euclideanDistance(eye[1], eye[5]);
  const vertical2 = faceapi.euclideanDistance(eye[2], eye[4]);
  // 计算水平方向的距离
  const horizontal = faceapi.euclideanDistance(eye[0], eye[3]);
  // 计算比值:(垂直距离平均值)/水平距离
  return (vertical1 + vertical2) / (2 * horizontal);
}

const leftEAR = calculateEyeAspectRatio(leftEye);
const rightEAR = calculateEyeAspectRatio(rightEye);
const avgEAR = (leftEAR + rightEAR) / 2;

// 一般来说,EAR低于0.25时就可以判定为眨眼
if (avgEAR < 0.25) {
  console.log('眨眼检测到了!');
  // 你的自定义逻辑
}

内容的提问来源于stack exchange,提问作者Ganesh K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:12:24