前端人脸检测

2,334 阅读1分钟

前言

最近负责的项目需要做一个前端的人脸检测,问过老大告诉我,人脸检测一般都需要很多资源包这些资源包呢一般都是几M起步,所以放在前端做不现实。但是对于好奇心强烈的我呢,没接触过的东西,只有两个想法,能实现或者不能实现。接下来进入正题。

寻找可用的js库

经过一番搜索,找到了两个可实现的库,一个是tracking.js还有一个是face-api.js(当然可能还有其他的我没有找到)。github地址:tracking.jsface-api.js

效果对比

face-api.js: face-api效果图 tracking.js:tracking效果图 可以看到二者都是可以实现的但是 tracking.js与face-api 相比的话有点差强人意,也许是我的使用方式不正确(doge),从实际体验来说 tracking.js 会出现不稳定检测人脸现象,该现象在face-api.js也有只不过相比而言比较偶现。 接下来启动摄像头对人脸进行测试,也得出face-api.js对比tracking.js的想过更为理想,但是对角度光线等等环境因素也有一定的要求。感兴趣的可以自己尝试一下。

实现

face-api.js:

  <script src="./face-api.min.js"></script>
  <script src="./utils.js"></script>
  <script async>
    const video = $("#myVideo"), canvas = $("#myCanvas"), text = $("#text");
    const MODEL_URL = '/models';
    
    // 打开摄像头
    // openCamera(video);


    const detection = async () => {
      // await faceapi.loadTinyFaceDetectorModel(MODEL_URL)
      // common sizes are 128, 160, 224, 320, 416, 512, 608, for face tracking via webcam I would recommend using smaller sizes
      // scoreThreshold?: number minimum confidence threshold default: 0.5
      const options = new faceapi.TinyFaceDetectorOptions({ inputSize: 512 })
      const fullFaceDescriptions = faceapi.detectSingleFace(video, options)
      // withAgeAndGender
      const dims = faceapi.matchDimensions(canvas, video, true)
      try {
        const resizedResults = await faceapi.resizeResults(fullFaceDescriptions, dims)
        console.table(resizedResults)
        if (resizedResults) {
          text.innerText = "检测到有人"
          // draw
          faceapi.draw.drawDetections(canvas, resizedResults)
        }
        else {
          text.innerText = "没有检测到人"
        }
      } catch(e) {
        console.log(e)
      }
    }
    (async () => {
      await faceapi.loadTinyFaceDetectorModel(MODEL_URL)

      text.innerText = "初始化完成"
    })()
    video.onplay = () => {
      setInterval(detection, 200);
    };
  </script>

MODEL_URL是所需的资源包路径 所有的资源包都在该仓库中 资源包地址

tracking.js:

  <script src="https://cdn.bootcdn.net/ajax/libs/tracking.js/1.1.3/tracking-min.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/tracking.js/1.1.3/data/face.js"></script>
  <script src="./utils.js"></script>
  <script>
    const canvasEl = $("#canvasEl"), videoEl = $("#videoEl"), text = $("#text");
    const context = canvasEl.getContext("2d");

    var objects = new tracking.ObjectTracker(['face']);

    const drawTime = 300;
    let prevNow = Date.now();

    objects.on('track', function(event) {
      
      if (event.data.length === 0) {
        // No objects were detected in this frame.
        context.clearRect(0, 0, canvasEl.width, canvasEl.height);
        text.innerText = "没有检测到人"
      } else {
        text.innerText = "检测到有人"
        event.data.forEach(function(rect) {
          // draw
          // rect.x, rect.y, rect.height, rect.width
          const now = Date.now();
          const usageTime = now - prevNow;
          if (usageTime < drawTime) return;
          prevNow = now;

          context.strokeStyle = "#6eff00";
          context.lineWidth = 1;
          context.clearRect(0, 0, canvasEl.width, canvasEl.height);
          context.strokeRect(rect.x, rect.y, rect.width, rect.height);
        });
      }
    });
    tracking.track('#videoEl', objects);
    // openCamera(videoEl);
  </script>

🥱前端萌新初来乍到,第一次发文,写得不好,望见谅,如有错误望指出!