使用 face-api.js 进行人脸检测后,有啥方法可以自动裁剪人脸?

Posted

技术标签:

【中文标题】使用 face-api.js 进行人脸检测后,有啥方法可以自动裁剪人脸?【英文标题】:Is there any way to auto crop the face after doing face detection with face-api.js?使用 face-api.js 进行人脸检测后,有什么方法可以自动裁剪人脸? 【发布时间】:2021-08-05 04:46:33 【问题描述】:

我已经在我的 react 项目中实现了 face-API,它从图片中检测到带有 detectSingleFace 的单个人脸。

现在我想更进一步。我希望 face-api 在检测后自动裁剪人脸。所以,我可以将它存储在一些服务器、状态或本地存储中。有什么办法吗?

在这里你可以看到我想要实现的截图示例 一侧是图片另一侧是自动裁剪的脸(我想要实现)。

这是我在代码框中的实时代码link

下面是我的face-api代码模块

PhotoFaceDetection.js

import React,  useState, useEffect, useRef  from "react";
import * as faceapi from "face-api.js";
import Img from "./assets/mFace.jpg";
import "./styles.css";

const PhotoFaceDetection = () => 
  const [initializing, setInitializing] = useState(false);
  const [image, setImage] = useState(Img);
  const canvasRef = useRef();
  const imageRef = useRef();

  // I want to store cropped image in this state
  const [pic, setPic] = useState();

  useEffect(() => 
    const loadModels = async () => 
      setInitializing(true);
      Promise.all([
        // models getting from public/model directory
        faceapi.nets.tinyFaceDetector.load("/models"),
        faceapi.nets.faceLandmark68Net.load("/models"),
        faceapi.nets.faceRecognitionNet.load("/models"),
        faceapi.nets.faceExpressionNet.load("/models")
      ])
        .then(console.log("success", "/models"))
        .then(handleImageClick)
        .catch((e) => console.error(e));
    ;
    loadModels();
  , []);

  const handleImageClick = async () => 
    if (initializing) 
      setInitializing(false);
    
    canvasRef.current.innerhtml = faceapi.createCanvasFromMedia(
      imageRef.current
    );
    const displaySize = 
      width: 500,
      height: 350
    ;
    faceapi.matchDimensions(canvasRef.current, displaySize);
    const detections = await faceapi.detectSingleFace(
      imageRef.current,
      new faceapi.TinyFaceDetectorOptions()
    );
    const resizeDetections = faceapi.resizeResults(detections, displaySize);
    canvasRef.current
      .getContext("2d")
      .clearRect(0, 0, displaySize.width, displaySize.height);
    faceapi.draw.drawDetections(canvasRef.current, resizeDetections);
    console.log(
      `Width $detections.box._width and Height $detections.box._height`
    );
    setPic(detections);
    console.log(detections);
  ;

  return (
    <div className="App">
      <span>initializing ? "Initializing" : "Ready"</span>
      <div className="display-flex justify-content-center">
        <img ref=imageRef src=image  crossorigin="anonymous" />
        <canvas ref=canvasRef className="position-absolute" />
      </div>
    </div>
  );
;

export default PhotoFaceDetection;

【问题讨论】:

刚刚查看了您的沙箱,似乎您已经开始工作了,对吗?您可以将其发布为答案。 @BasvanderLinden 确定 【参考方案1】:

在做了很多研发之后,我想通了。对于可能面临问题的未来读者,这里是指南。 我创建了另一个函数,它将获取原始图像参考和有界框尺寸,即宽度和高度。之后,我使用 faceapi 方法提取人脸,然后在 toDataURL 方法的帮助下,我将其实际转换为 base64 文件,该文件可以呈现到任何图像 src 或可以存储在任何地方。 这是我上面解释的功能

async function extractFaceFromBox(imageRef, box) 
    const regionsToExtract = [
      new faceapi.Rect(box.x, box.y, box.width, box.height)
    ];
    let faceImages = await faceapi.extractFaces(imageRef, regionsToExtract);

    if (faceImages.length === 0) 
      console.log("No face found");
     else 
      const outputImage = "";
      faceImages.forEach((cnv) => 
        outputImage.src = cnv.toDataURL();
        setPic(cnv.toDataURL());
      );
      // setPic(faceImages.toDataUrl);
      console.log("face found ");
      console.log(pic);
    
  

然后我在使用 faceapi 人脸检测微型模型的主函数中调用上述函数。 extractFaceFromBox(imageRef.current, detections.box);

您也可以访问实时代码here 以检查完整的实现

【讨论】:

以上是关于使用 face-api.js 进行人脸检测后,有啥方法可以自动裁剪人脸?的主要内容,如果未能解决你的问题,请参考以下文章

教程 | face-api.js:在浏览器中进行人脸识别的JavaScript接口

如何在用户开心并使用 face-api 检测到人脸时拍摄图像

如何将库导入 React.js 中的网络工作者?

face-api.js with Vue.js and Electron

仅捕获检测到的人脸正方形 JS

前端人脸识别--两张脸相似度