使用 TensorFlow.js 和 OffscreenCanvas 实现实时防挡脸弹幕

首先,要理解我们的目标,我们将实时获取视频中的面部区域并将其周围的内容转为不透明以制造出弹幕的“遮挡效应”。

步骤一:环境准备

我们将使用 TensorFlow.js 的 Body-segmentation 库来完成面部识别部分,并使用 OffscreenCanvas 来绘制更新后的图像。

安装相关库:

npm install @tensorflow-models/body-segmentation

步骤二:使用 body-segmentation 检测脸部

首先,我们需要导入所需的库并配置我们的模型。

import { createSegmenter, SupportedModels } from "@tensorflow-models/body-segmentation";
import type { Ref } from "vue";

const model = SupportedModels.MediaPipeSelfieSegmentation;
const segmenterConfig = {
  runtime: "mediapipe",
  solutionPath: "https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation",
  modelType: "general"
}
const segmenter = await createSegmenter(model, segmenterConfig);

接下来,我们会定期从视频流中获取图像,然后使用 segmenter.segmentPeople(videoEl) 对其进行处理。

步骤三:使用 OffscreenCanvas 进行绘制

我们接下来要创建一个 worker,并将画布对象和 mask 图像传给它。在 worker 端,我们会从 mask 图像中剔除人脸部分,然后在这部分绘制白色,产生弹幕的“遮挡效应”。 注意转移权移动给worker。

const worker = new Worker("/src/assets/pull/worker.ts");
let offscreen;
export async function detect(videoEl: HTMLVideoElement, canvas: Ref<HTMLCanvasElement>) {
  if (!offscreen) {
    offscreen = canvas.value.transferControlToOffscreen();
  }
  const segmentation = await segmenter.segmentPeople(videoEl);
  const mask = await segmentation[0].mask.toCanvasImageSource();
  worker.postMessage({ canvas: offscreen, mask: mask }, [offscreen]);
  window.setTimeout(() => detect(videoEl, canvas), 66);
}

步骤四:Worker中绘制图像

在 worker 中,我们需要接收主线程传来的信息,并进行绘制。然后我们将绘制后的结果发送回主线程。

self.onmessage = function (event) {
  const offscreen = event.data.canvas;
  const mask = event.data.mask;
  const context = offscreen.getContext('2d');
  const reader = new FileReaderSync();
  
  // ... 清空画布,并绘制图像操作
  
  offscreen
    .convertToBlob({type: 'image/png', quality: 0 })
    .then((blob: Blob) => {
      const dataURL = reader.readAsDataURL(blob);
      self.postMessage({ msgType: 'mask', val: dataURL });
    })
    .catch(console.error);
};

经过以上步骤,我们成功制造了弹幕的“遮挡效应”。

最近更新

  1. TCP协议是安全的吗?

    2024-05-13 03:12:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-13 03:12:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-13 03:12:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-13 03:12:03       18 阅读

热门阅读

  1. C++中合成的默认构造函数的访问权限

    2024-05-13 03:12:03       10 阅读
  2. 王者荣耀铭文说明

    2024-05-13 03:12:03       10 阅读
  3. Spring Boot的工作原理

    2024-05-13 03:12:03       9 阅读
  4. HTTP协议

    2024-05-13 03:12:03       11 阅读
  5. mybatis 模糊查询的几种方式

    2024-05-13 03:12:03       10 阅读
  6. Python 自动化脚本系列:第3集

    2024-05-13 03:12:03       13 阅读
  7. 拼接图片路径不显示:vue

    2024-05-13 03:12:03       10 阅读
  8. 力扣 516. 最长回文子序列 python AC

    2024-05-13 03:12:03       15 阅读
  9. 【linux软件基础知识】-cdev_alloc

    2024-05-13 03:12:03       11 阅读
  10. halcon学习之形状匹配

    2024-05-13 03:12:03       6 阅读
  11. logback 日志脱敏

    2024-05-13 03:12:03       7 阅读
  12. Google Gemma 2B 微调实战(IT科技新闻标题生成)

    2024-05-13 03:12:03       12 阅读
  13. 生成ssh来连接git

    2024-05-13 03:12:03       11 阅读
  14. 旋转木马案例

    2024-05-13 03:12:03       8 阅读
  15. HTTP 结构概述

    2024-05-13 03:12:03       11 阅读
  16. Android app通过jcifs-ng实现Samba连接共享文件夹

    2024-05-13 03:12:03       10 阅读