找回密码
 立即注册
首页 业界区 业界 视频解析图片识别人脸采集并切图video-clip-images,fac ...

视频解析图片识别人脸采集并切图video-clip-images,face-api.js

柏雅云 2025-6-6 09:51:47
video-clip-images

采集视频中的人脸并截取


  • 本Demo是通过face-api实现的。具体内容可前往Github:face-api
  • 注: 返回大部分使用的都是base64
  • Demo地址放在了码云上:video-clip-images
目录结构
  1. video-clip-images/
  2. ├── face-api.js-master/
  3. │   ├── weights/ 模型
  4. │   │   └── ...
  5. ├── js/ 脚本
  6. │   └── ...
  7. └── index.html
复制代码
第一步加载模型
  1. await faceapi.nets.tinyFaceDetector.loadFromUri(
  2.     "./face-api.js-master/weights"
  3. );
复制代码
第二步 通过传入的url 获取每一秒的图片
  1.   async getVideoFace(url) {
  2.     const video = document.createElement("video");
  3.     const canvas = document.createElement("canvas");
  4.     video.src = url;
  5.     await new Promise((resolve) => {
  6.       video.addEventListener("loadedmetadata", () => {
  7.         resolve();
  8.       });
  9.     });
  10.     const duration = video.duration;
  11.     const ctx = canvas.getContext("2d");
  12.     canvas.width = video.videoWidth;
  13.     canvas.height = video.videoHeight;
  14.     const frameData = [];
  15.     for (let i = 0; i < duration; i++) {
  16.       video.currentTime = i;
  17.       await new Promise((resolve) => {
  18.         video.addEventListener("seeked", function handler() {
  19.           video.removeEventListener("seeked", handler);
  20.           ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  21.           const base64 = canvas.toDataURL("image/jpeg");
  22.           frameData.push({
  23.             base64,
  24.             second: i,
  25.           });
  26.           resolve();
  27.         });
  28.       });
  29.     }
  30.     return frameData;
  31.   }
复制代码
第三步 处理每一秒的图片并裁剪


  • detectFrame获取人物在图中的位置
  • getClipImage获取裁剪后的图片
    1.   getClipImage(box, image) {
    2.   const newCanvas = document.createElement("canvas");
    3.   const newCtx = newCanvas.getContext("2d");
    4.   newCanvas.width = box.width;
    5.   newCanvas.height = box.height;
    6.   newCtx.drawImage(
    7.     image,
    8.     box.x,
    9.     box.y,
    10.     box.width,
    11.     box.height,
    12.     0,
    13.     0,
    14.     box.width,
    15.     box.height
    16.   );
    17.   const base64Data = newCanvas.toDataURL("image/png");
    18.   let img = document.createElement("img");
    19.   img.src = base64Data;
    20.   return base64Data;
    21. }
    复制代码
  • 通过第二步获取的data使用detectFrame获取box
  • 通过filter过滤box为空也就是没有获取到人脸。
  • 最后使用getClipImage获取到裁剪后的图片
  1.   async install(url) {
  2.     let data = await this.getVideoFace(url);
  3.     const detectFrame = async (img) => {
  4.       let box;
  5.       const detections = await faceapi.detectAllFaces(
  6.         img,
  7.         new faceapi.TinyFaceDetectorOptions()
  8.       );
  9.       detections.forEach((detection) => {
  10.         box = detection.box;
  11.       });
  12.       return box;
  13.     };
  14.     data = data.map((item) => {
  15.       return new Promise((resolve, reject) => {
  16.         let img = new Image();
  17.         img.onload = async () => {
  18.           item.box = await detectFrame(img);
  19.           item.img = img;
  20.           resolve(item);
  21.         };
  22.         img.src = item.base64;
  23.       });
  24.     });
  25.     data = await Promise.all(data);
  26.     console.log(`本次处理耗时:${this.numb}秒`);
  27.     clearInterval(this.time);
  28.     return data
  29.       .filter((i) => Boolean(i.box))
  30.       .map((item) => {
  31.         item.clipImage = this.getClipImage(item.box, item.img);
  32.         return item;
  33.       });
  34.   }
复制代码
报告!菜坤后端要Blob


  • 把它工资分我一份!!!!!
  • 处理裁剪好的base64base64ToBlob(item.clipImage)
    1.   new ClipImages("./2025419-450082.mp4").then((data) => {
    2.       data.forEach((item) => {
    3.         let img = document.createElement("img");
    4.         img.src = item.clipImage;
    5.         document.body.appendChild(img);
    6.         item.clipImageBlob = base64ToBlob(item.clipImage)
    7.       });
    8.       console.log(data);
    9.   });
    复制代码
  • base64ToBlob代码片段
    1. function base64ToBlob(base64, contentType = "image/png") {
    2.   // 去掉 Base64 编码字符串的前缀
    3.   const sliceIndex = base64.indexOf(",") + 1;
    4.   const base64Data = base64.slice(sliceIndex);
    5.   // 解码 Base64 数据
    6.   const binary = atob(base64Data);
    7.   const length = binary.length;
    8.   const buffer = new ArrayBuffer(length);
    9.   const view = new Uint8Array(buffer);
    10.   // 将二进制字符串转换为 Uint8Array
    11.   for (let i = 0; i < length; i++) {
    12.       view[i] = binary.charCodeAt(i);
    13.   }
    14.   // 创建 Blob 对象
    15.   return new Blob([view], { type: contentType });
    16. }
    复制代码
效果图

1.jpeg


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册