Javascript 在使用face-api.js进行人脸检测后,有没有办法自动裁剪人脸?

Javascript 在使用face-api.js进行人脸检测后,有没有办法自动裁剪人脸?,javascript,reactjs,react-hooks,face-recognition,face-api,Javascript,Reactjs,React Hooks,Face Recognition,Face Api,我在react项目中实现了face API,该项目使用图片中的detectSingleFace检测单个人脸 现在我想更进一步。我希望人脸api在检测后自动裁剪人脸。因此,我可以将其存储在服务器、州或本地存储中。有什么办法吗 在这里你可以看到一个截图例子,我想实现的一面是图片,另一面是自动裁剪的脸(我想实现)。 这是我在codesandbox中的实时代码 下面是我的FaceAPI代码模块 PhotoFaceDetection.js import React, { useState, useEff

我在react项目中实现了face API,该项目使用图片中的
detectSingleFace
检测单个人脸

现在我想更进一步。我希望人脸api在检测后自动裁剪人脸。因此,我可以将其存储在服务器、州或本地存储中。有什么办法吗

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

这是我在codesandbox中的实时代码

下面是我的FaceAPI代码模块

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} alt="face" crossorigin="anonymous" />
        <canvas ref={canvasRef} className="position-absolute" />
      </div>
    </div>
  );
};

export default PhotoFaceDetection;

import React,{useState,useffect,useRef}来自“React”;
从“face api.js”导入*作为faceapi;
从“/assets/mFace.jpg”导入Img;
导入“/styles.css”;
常量PhotoFaceDetection=()=>{
const[initializing,setInitializing]=useState(false);
const[image,setImage]=使用状态(Img);
const canvasRef=useRef();
const imageRef=useRef();
//我想在此状态下存储裁剪后的图像
const[pic,setPic]=useState();
useffect(()=>{
const loadModels=async()=>{
setInitializing(true);
我保证([
//从public/model目录获取模型
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”))
。然后(点击)
.catch((e)=>console.error(e));
};
loadModels();
}, []);
常量handleImageClick=async()=>{
如果(初始化){
设置初始化(假);
}
canvasRef.current.innerHTML=faceapi.createCanvasFromMedia(
imageRef.current
);
常量显示大小={
宽度:500,
身高:350
};
faceapi.matchDimensions(canvasRef.current,displaySize);
const detections=wait faceapi.detectSingleFace(
imageRef.current,
新的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(
`宽度${detections.box.\u宽度}和高度${detections.box.\u高度}`
);
setPic(检测);
控制台日志(检测);
};
返回(
{正在初始化?“正在初始化”:“准备就绪”}
);
};
导出默认的PhotoFaceDetection;

在做了大量的研发工作后,我发现了这一点。对于未来可能面临问题的读者,这里是指南。 我创建了另一个函数,该函数将获取原始图像参考和有界框尺寸,即宽度和高度。之后,我使用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)


您还可以访问实时代码来检查完整的实现

只需查看您的沙箱,就好像您已经让它工作了,对吗?“你可以把它作为答案张贴出来。”巴斯范德林登:当然可以