Vue2 实现人脸检测与录入功能,基于 tracking.js 实时人脸识别

本文使用 Vue2 + tracking.js 实现前端人脸检测、人脸框标注、人脸截图录入功能,包含摄像头调用、Canvas 绘制、人脸截取完整代码,支持浏览器实时预览,一步到位实现人脸识别前端开发。

  1. 自行去下载tracking.js
1
npm install tracking
  1. 三个canvas,一个显示完整摄像头,一个在摄像头上显示人脸矩形框,一个截取人脸(提醒大家一下,如果你选择localhost运行预览是不会报错的,但是如果选择IP地址运行预览,肯定是会报错的,因为你的浏览器在不是https协议的情况下不允许打开摄像头)
  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
<template>
  <div>
    <div>
      <p>脸部放入红色矩形框</p>
      <video id="video" style="transform: rotateY(180deg)" autoplay preload loop muted></video>
      <canvas id="overlayCanvas" width="200" height="200" style="position: absolute; top: 20; left: 0; transform: rotateY(180deg);"></canvas>
    </div>
    <div>
      <p>检测人脸结果</p>
      <canvas id="fullCanvas" width="200" height="200" style="transform: rotateY(180deg)"></canvas>
      <canvas id="faceCanvas" width="200" height="200" style="transform: rotateY(180deg); display: none;"></canvas>
    </div>
    <div>结果:{{ img }}</div>
  </div>
</template>
 
<script>
//import { userMedia } from '../../utils/utils';
import 'tracking/build/tracking.js';
import 'tracking/build/data/face-min.js';
 
export default {
  data() {
    return {
      img: '',
      videoObj: null,
      trackerTask: null,
      overlayContext: null
    }
  },
 
  mounted() {
    this.getCompetence()
  },
 
  methods: {
    openCamera() {
      this.$nextTick(() => {
        const fullCanvas = document.getElementById('fullCanvas')
        const fullContext = fullCanvas.getContext('2d')
 
        const faceCanvas = document.getElementById('faceCanvas')
        const faceContext = faceCanvas.getContext('2d')
 
        this.videoObj = document.getElementById('video')
 
        const overlayCanvas = document.getElementById('overlayCanvas')
        this.overlayContext = overlayCanvas.getContext('2d')
 
        const tracker = new window.tracking.ObjectTracker('face')
        tracker.setInitialScale(4)
        tracker.setStepSize(2)
        tracker.setEdgesDensity(0.1)
 
        this.trackerTask = window.tracking.track('#video', tracker, { camera: true })
        this.img = this.trackerTask
 
        tracker.on('track', (event) => {
          if (event.data.length !== 0) {
            event.data.forEach((rect) => {
              fullContext.clearRect(0, 0, fullCanvas.width, fullCanvas.height)
              fullContext.drawImage(this.videoObj, 0, 0, fullCanvas.width, fullCanvas.height)
 
              faceCanvas.width = rect.width
              faceCanvas.height = rect.height
              faceContext.clearRect(0, 0, faceCanvas.width, faceCanvas.height)
              faceContext.drawImage(this.videoObj, rect.x, rect.y, rect.width, rect.height, 0, 0, faceCanvas.width, faceCanvas.height)
 
              // 绘制矩形框到 overlayCanvas
              this.overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height)
              this.overlayContext.strokeStyle = 'red'; // 设置矩形框颜色
              this.overlayContext.lineWidth = 2; // 设置矩形框线宽
              this.overlayContext.strokeRect(rect.x, rect.y, rect.width, rect.height)
 
              console.log(faceCanvas.toDataURL())
              this.img = faceCanvas.toDataURL()
            });
          }
        })
      })
    },
 
    getCompetence() {
      let _this = this;
      this.video = document.getElementById("video");
      if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
      }
      if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = function (constraints) {
          var getUserMedia =
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.getUserMedia;
          if (!getUserMedia) {
            return Promise.reject(
              new Error("getUserMedia is not implemented in this browser")
            );
          }
          return new Promise(function (resolve, reject) {
            getUserMedia.call(navigator, constraints, resolve, reject);
          });
        };
      }
      var constraints = {
        video: { width: 200, height: 200, transform: "scaleX(-1)" },
        audio: false,
      };
      navigator.mediaDevices
        .getUserMedia(constraints)
        .then(function (stream) {
          if ("srcObject" in _this.video) {
            _this.video.srcObject = stream;
          } else {
            _this.video.src = window.URL.createObjectURL(stream);
          }
          _this.video.onloadedmetadata = function (e) {
            _this.video.play();
          };
 
          _this.openCamera();
        })
        .catch((err) => {
          console.log(err);
        });
    },
 
    de() {
      this.video.srcObject.getTracks()[0].stop();
      this.trackerTask.stop();
    },
 
    handleCancel() {
      this.videoObj.srcObject.getTracks()[0].stop()
      this.trackerTask.stop()
    },
 
    success(stream) {
      this.videoObj.srcObject = stream
      this.videoObj.play()
    },
 
    error(error) {
      console.log(`访问用户媒体设备失败${error.name}, ${error.message}`)
    }
  },
 
  beforeDestroy() {
    this.handleCancel()
  }
}
</script>

每日更新学习资料、行业资讯、技术干货与疑难解答,免费分享资源下载,助力学习者高效提升。