全栈人脸识别:使用 OpenCV 和 face-api.js

人脸识别技术已广泛应用于安全、娱乐和个性化服务等领域。本文将介绍如何结合 OpenCV 和 face-api.js 创建一个全栈人脸识别应用,从而实现高效、实时的人脸检测和识别功能。

1. 概述

本文将涵盖以下内容:

  • 环境配置与安装
  • 基于 OpenCV 的后端人脸检测
  • 基于 face-api.js 的前端人脸识别
  • 全栈应用的集成与实现

2. 环境配置与安装

2.1 安装 OpenCV

在后端使用 Python 和 OpenCV 进行人脸检测。首先,安装所需的 Python 库:

pip install opencv-python flask

2.2 安装 face-api.js

在前端使用 face-api.js 进行人脸识别。可以通过 CDN 或 npm 安装:

使用 CDN 引入

在 HTML 文件中添加以下脚本标签:

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/face-api.js"></script>
使用 npm 安装

如果你使用 npm,可以在项目中安装 face-api.js:

npm install @tensorflow/tfjs @vladmandic/face-api

然后在你的 JavaScript 文件中引入:

import * as faceapi from '@vladmandic/face-api';

3. 后端:基于 OpenCV 的人脸检测

后端将使用 Flask 提供 API 服务,并通过 OpenCV 进行人脸检测。

3.1 创建 Flask 应用

创建一个新的 Flask 项目:

from flask import Flask, request, jsonify
import cv2
import numpy as np

app = Flask(__name__)

@app.route('/detect', methods=['POST'])
def detect():
    file = request.files['image'].read()
    npimg = np.frombuffer(file, np.uint8)
    img = cv2.imdecode(npimg, cv2.IMREAD_COLOR)

    # 使用 OpenCV 进行人脸检测
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.1, 4)

    response = []
    for (x, y, w, h) in faces:
        response.append({"x": int(x), "y": int(y), "w": int(w), "h": int(h)})

    return jsonify(response)

if __name__ == '__main__':
    app.run(debug=True)

3.2 启动 Flask 服务器

在终端中运行以下命令启动 Flask 服务器:

python app.py

4. 前端:基于 face-api.js 的人脸识别

前端将使用 face-api.js 进行人脸识别,并调用后端 API 获取人脸检测结果。

4.1 HTML 页面结构

创建一个简单的 HTML 页面,包含视频元素和脚本:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Face Recognition</title>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
  <script src="https://cdn.jsdelivr.net/npm/face-api.js"></script>
</head>
<body>
  <video id="video" width="720" height="560" autoplay muted></video>
  <script src="script.js"></script>
</body>
</html>

4.2 初始化视频流

在 script.js 文件中初始化视频流并加载 face-api.js 模型:

async function setupCamera() {
  const video = document.getElementById('video');
  const stream = await navigator.mediaDevices.getUserMedia({ video: {} });
  video.srcObject = stream;
}

async function loadModels() {
  const MODEL_URL = '/models';
  await faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL);
  await faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL);
  await faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL);
}

async function init() {
  await setupCamera();
  await loadModels();
}

init();

4.3 实时人脸检测与识别

通过视频流实时检测人脸并识别:

video.addEventListener('play', () => {
  const canvas = faceapi.createCanvasFromMedia(video);
  document.body.append(canvas);
  const displaySize = { width: video.width, height: video.height };
  faceapi.matchDimensions(canvas, displaySize);

  setInterval(async () => {
    const detections = await faceapi.detectAllFaces(video).withFaceLandmarks().withFaceDescriptors();
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceLandmarks(canvas, resizedDetections);
  }, 100);
});

4.4 调用后端 API

将视频帧发送到后端进行人脸检测,并在前端显示检测结果:

async function detectFaces(image) {
  const formData = new FormData();
  formData.append('image', image);

  const response = await fetch('/detect', {
    method: 'POST',
    body: formData
  });

  return response.json();
}

video.addEventListener('play', async () => {
  const canvas = faceapi.createCanvasFromMedia(video);
  document.body.append(canvas);
  const displaySize = { width: video.width, height: video.height };
  faceapi.matchDimensions(canvas, displaySize);

  setInterval(async () => {
    const detections = await faceapi.detectAllFaces(video).withFaceLandmarks().withFaceDescriptors();
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceLandmarks(canvas, resizedDetections);

    const img = new Image();
    img.src = canvas.toDataURL('image/jpeg');
    const faces = await detectFaces(img);

    faces.forEach(face => {
      const { x, y, w, h } = face;
      const box = { x, y, width: w, height: h };
      faceapi.draw.drawBox(canvas, box, { label: 'Face' });
    });
  }, 1000);
});

5. 总结

通过结合 OpenCV 和 face-api.js,我们创建了一个全栈人脸识别应用。后端使用 OpenCV 进行高效的人脸检测,前端使用 face-api.js 进行实时人脸识别。这种组合不仅利用了 OpenCV 的强大功能,还充分发挥了 face-api.js 在浏览器中运行的便利性。

希望本文能帮助你了解如何构建一个完整的人脸识别应用,并激发你在这个领域进一步探索的兴趣。Happy coding!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌南竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值