> ## Content Index
> Fetch the complete content index at: https://iiong.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 前端捕获人脸识别实践
- URL: https://iiong.com/front-end-capture-face-recognition-practice/
- Published: 2021-07-02T00:26:00.000Z
- Updated: 2026-06-22T15:31:28.000Z
- Description: 公司有个项目涉及人脸识别，需要前端能力支持，需要用户进入摄像头后识别人脸进行截图，然后上传后端进行数据交换。不过目前主流摄像头支持调用，开源社区有个 trackingjs 类库问题解决计算机视觉解决方案。
- Author: 淮城一只猫
- Tags: 奇技淫巧, Web 前端

### 前言

公司有个项目涉及人脸识别，需要前端能力支持，需要用户进入摄像头后识别人脸进行截图，然后上传后端进行数据交换。不过目前主流摄像头支持调用，开源社区有个 `trackingjs` 类库问题解决计算机视觉解决方案。

### 实践

`trackingjs` 很多工作量帮你做好，只需要引入他的库就可以用了：

```html
<div class="app-container">
      <video ref="videoRef" class="video-wrapper" preload autoplay loop muted />
      <canvas ref="captureFaceRef" width="600" height="560" class="capture-face-wrapper" />
    </div>
    <div class="result-wrapper">
      <h3>捕获到人脸数据：</h3>
      <canvas ref="shortCutRef" class="short-cut-wrapper" />
    </div>

```

想实现功能至少需要 `videoRef` 和 `shortCutRef` 节点，`videoRef` 主要是调用摄像头获取流媒体进行播放，而 `shortCutRef` 节点就是人脸截图，你可以拿到里面的图片进行提交，至于图片转 `base64` 数据流根据需求定吧。上面多一个 `captureFaceRef` 主要是捕获人脸的状态圈，告知用户捕获状态，而这个状态 `trackingjs` 事件回调里包含其中。

本项目是 `vue3` 项目，所以先初始化相关的业务：

```javascript
const videoRef = ref(null)
const captureFaceRef = ref(null)
const shortCutRef = ref(null)

// 捕捉人脸坐标对象
const saveArray = {}
let captureFaceCanvas = null
let captureFaceContext = null
let shortCutRefCanvas = null
let shortCutRefContext = null
// tracking 实例化对象
let tracker = null

```

然后在 `mounted` 生命周期拿到 `dom` 节点信息和初始化 `trackingjs`：

```javascript
onMounted(() => {
  captureFaceCanvas = captureFaceRef.value
  shortCutRefCanvas = shortCutRef.value
  captureFaceContext = captureFaceCanvas.getContext('2d')
  shortCutRefContext = shortCutRefCanvas.getContext('2d')

  initTracker()
  captureFacePhoto(shortCutRefCanvas)
 })

```

`initTracker` 方法要注意下声明 `face` 的模块，因为 `trackingjs` 机器学习模型很多，我这边只用到人脸，所以声明该模型：

```javascript
const initTracker = () => {
  // 实例化 face 模块
  tracker = new window.tracking.ObjectTracker('face')
  // 初始化抓取人脸边框配置
  tracker.setInitialScale(4)
  tracker.setStepSize(2)
  tracker.setEdgesDensity(0.1)
	// 摄像头开启
  window.tracking.track(videoRef.value, tracker, {
      camera: true
  })
  // 追踪事件回调
  tracker.on('track', event => {
      captureFaceContext.clearRect(0, 0, captureFaceCanvas.width, captureFaceCanvas.height)
      event.data.forEach(function (rect) {
          captureFaceContext.strokeStyle = 'red'
          captureFaceContext.strokeRect(rect.x, rect.y, rect.width, rect.height)
          captureFaceContext.fillStyle = 'red'
          saveArray.x = rect.x
          saveArray.y = rect.y
          saveArray.width = rect.width
          saveArray.height = rect.height
      })
  })
}

```

上面就是根据配置进行个性化配置，具体可以查阅官方文档。

然后制作截图功能：

```javascript
const captureFacePhoto = canvas => {
  // 将video对象内指定的区域捕捉绘制到画布上指定的区域，实现拍照
  shortCutRefContext.drawImage(videoRef.value, 140, 70, 340, 340, 0, 0, 140, 140)
  const getImage = canvas.toDataURL('image/png')
  console.log(getImage)
}

```

### 优化

至此为止基本功能已经实现了，不过在人脸识别过程中，却发现人脸识别经常失误，比如识别到侧边脸以及截图文件不完整。

```javascript
const bestCaptureTimer = () => {
  if (saveArray.x > 130 &&
    saveArray.x + saveArray.width < 460 &&
    saveArray.y > 58 &&
    saveArray.y + saveArray.height < 388 &&
    saveArray.width < 330 &&
    saveArray.height < 330) {
    captureFacePhoto(shortCutRefCanvas)
    for (const key in saveArray) {
      delete saveArray[key]
    }
  }
}

```

这个定时器让用户在画布中央进行截图，提高人脸识别率。

对于需要检验摄像头设备完全可以用浏览器的 api 实现：

```javascript
if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {}
}
// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
// 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = constraints => {

    // 首先，如果有getUserMedia的话，就获得它
    const getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia

    // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
    if (!getUserMedia) {
      return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
    }

    // 否则，为老的navigator.getUserMedia方法包裹一个Promise
    return new Promise((resolve, reject) => {
      getUserMedia.call(navigator, constraints, resolve, reject)
    })
  }
}

navigator.mediaDevices.getUserMedia({ video: true }).then(() => {
  // 人脸识别业务初始化
  const tracker = new window.tracking.ObjectTracker('face')
  // 一些业务...
}).catch(err => {
  console.warn(err.name + ": " + err.message)
  ElMessage.error({
    message: '没有检验到摄像头，请插入摄像头设备！',
    showClose: true,
    duration: 0
  })
})

```

[demo 如下，记得授权摄像头访问](https://7e55o.csb.app/?ref=iiong.com)