基于 Gitee AI数据集实现弹幕不遮挡人像滚动
引言
最近在刷视频的时候不巧发现了一个giteeAI工具,根据内部推荐的数据集,最后找到了一个叫tensorflow.js的github库,能够简单实现对于视频人像的扣取,从而可以为视频生成AI遮罩层,最终实现弹幕不会遮住人像的效果。
效果如下
由于使用的数据集不是很大,所以运行起来的效果可能不如B站的完美,由于数据集是第三方数据集,需要挂梯子才能够有效访问,否则会出现资源加载失败的bug。
弹幕遮罩效果演示录频
实现原理
在实现上,主要是利用了前端的mask-image属性,mask-image支持png格式的图片,然后内容只会出现在png非透明区域(也就是非透明背景色块),从而实现了人像不会被遮罩。关键在于视频每一帧的人像扣取并生成一个对人像的无色色块。具体的实现代码如下(完整代码链接):
<script setup>
import * as bodySegmentation from "@tensorflow-models/body-segmentation";
import { onMounted } from "vue";
const canvas = document.createElement("canvas");
const canvasCtx = canvas.getContext("2d");
let segmenter = null;
const segmenterConfig = {
runtime: 'mediapipe', // or 'tfjs'
solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation',
modelType: 'general'
}
async function setMask() {
const videoElem = document.querySelector("#video");
canvas.width = videoElem.clientWidth;
canvas.height = videoElem.clientHeight;
canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
canvasCtx.drawImage(videoElem, 0, 0, canvas.width, canvas.height);
if (!segmenter) {
segmenter = await bodySegmentation.createSegmenter(bodySegmentation.SupportedModels.MediaPipeSelfieSegmentation, segmenterConfig)
}
const segmentation = await segmenter.segmentPeople(canvas);
const coloredPartImage = await bodySegmentation.toBinaryMask(segmentation);
canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
canvasCtx.putImageData(coloredPartImage, 0, 0);
const base64Data = canvas.toDataURL('image/png');
const danmuEle = document.querySelector(".danmu");
console.log("输出数据:", danmuEle);
danmuEle.style.maskImage = `url(${base64Data})`;
}
onMounted(() => {
function loop() {
requestAnimationFrame(() => {
setMask();
loop();
})
}
loop();
});
</script>
<template>
<div class="danmu-video">
<video id="video" controls="controls" autoplay="true">
<source src="./assets/Output.mp4" type="video/mp4">
</video>
<div class="danmu">
<marquee>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
<p>手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试手动测试</p>
</marquee>
</div>
</div>
</template>
<style scoped>
* {
margin: 0;
padding: 0;
}
.danmu-video {
height: 300px;
width: 300px;
position: relative;
}
#video {
height: 100%;
width: 100%;
position: absolute;
left: 0px;
top: 0px;
}
.danmu {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 1;
pointer-events: none;
}
.danmu p {
font-size: 12px;
}
</style>
但是目前giteeAI不能够自己上传自己的数据集,不然的话可以看到更多的更加细腻的识别数据集:
补充说明
一般来说AI模型的运行应该交给后端,现实上,可以将视频的每一帧获取之后提交给后端,然后生成mask-image之后前端再显示(但是这样好像给前后端带来的流量压力都有些大,如果有做过这方面的大佬希望能够再评论区指点一二),或者继续期待我们GiteeAI提供更多完备的AI数据集和API调用接口,更多功能可以继续去giteeAI尝试哦。