视频解析人脸实时追加框,框出人脸video-rect-images,face-api.js
video-rect-images
采集视频中的人脸并框出
- 本
Demo是通过face-api实现的。具体内容可前往Github:face-api - 注: 返回大部分使用的都是
base64 Demo地址放在了码云上:video-rect-images
目录结构
video-rect-images/
├── face-api.js-master/
│ ├── weights/ 模型
│ │ └── ...
├── js/ 脚本
│ └── ...
└── index.html
最后的效果图

一起来看看AI生成的文档
视频人脸检测项目说明

一、项目概述
该项目实现了一个在网页上对视频进行人脸检测的功能,通过使用 face-api.js 库,能够检测视频中的人脸,并在视频上绘制人脸检测框,同时将检测到的人脸区域截取并以图片形式展示在页面上。
二、HTML 结构
页面标题与样式
在 <head> 部分,设置页面标题为 “视频人脸检测”。
定义了一些 CSS 样式,包括:
视频容器 #videoContainer 的样式,设置为相对定位;
视频 #video 和画布 #canvas 的样式,设置为绝对定位,并且 #canvas 禁止指针事件;
播放按钮 #playBtn 的样式;
展示截取人脸图片的区域 #show-people 中图片的样式。
页面内容
在 <body> 部分:
有一个播放按钮 <button id="playBtn">点击播放并开始检测</button>。
视频容器 <div id="videoContainer"> 内包含:
一个 <video> 元素,用于播放视频,视频源为 ./2025419-450082.mp4,并提供了不支持视频标签时的提示信息;
一个 <canvas> 元素,用于绘制人脸检测框;
一个 <div id="show-people"></div> 用于展示截取的人脸图片。
三、JavaScript 代码功能
获取 DOM 元素
使用 document.getElementById 获取页面上的视频元素 video、画布元素 canvas 和播放按钮元素 playBtn。
**截取人脸图片函数 **getImage
该函数接受一个表示人脸检测框的 box 对象作为参数,具体步骤如下:
创建一个新的画布 newCanvas 和其 2D 上下文 newCtx;
根据 box 的尺寸设置新画布的宽度和高度;
从原始视频中绘制人脸区域到新画布上;
将新画布的内容导出为 Base64 编码的图像数据;
创建一个新的 <img> 元素,设置其 src 为 Base64 数据,并将其添加到 #show-people 元素中展示。
**初始化函数 **init
使用 await faceapi.nets.tinyFaceDetector.loadFromUri("./face-api.js-master/weights") 加载人脸检测模型;
设置画布的高度和宽度与视频的高度和宽度一致。
**开始检测函数 **startDetection
获取画布的 2D 上下文 ctx;
使用 requestAnimationFrame 实现流畅的检测循环;
在每一帧中,检测视频中的所有人脸,得到 detections;
清空画布,然后遍历 detections,为每个人脸绘制检测框,并调用 getImage 函数截取人脸图片。
播放按钮点击事件处理
当点击播放按钮时:
尝试播放视频,并调用 startDetection 开始检测;
如果播放失败,弹出错误提示;
同时隐藏播放按钮。
页面加载时初始化
使用 window.onload = init; 在页面加载完成后调用 init 函数进行初始化操作。
四、依赖项
face-api.js** 库**:通过 <script src="./js/face-api.min.js"></script> 引入,用于实现人脸检测功能。
人脸检测模型文件:位于 ./face-api.js-master/weights 目录下,由 faceapi.nets.tinyFaceDetector.loadFromUri 加载。
五、注意事项
确保视频文件 ./2025419-450082.mp4 存在且路径正确。
确保 face-api.js 库和人脸检测模型文件的路径正确,否则可能导致人脸检测功能无法正常工作。
部分浏览器可能对视频自动播放有限制,若视频无法自动播放,可能需要用户手动交互(如点击页面)来触发播放。
最终代码片段
<!DOCTYPE html>
<html>
<head>
<title>视频人脸检测</title>
<style>
#videoContainer {
position: relative;
/* max-width: 800px; */
}
#video,
#canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
}
#canvas {
pointer-events: none;
}
/* 添加播放按钮样式 */
#playBtn {
padding: 12px 24px;
background: #4caf50;
color: white;
border: none;
cursor: pointer;
margin: 10px;
}
#show-people img {
display: inline-block;
}
</style>
</head>
<body>
<button id="playBtn">点击播放并开始检测</button>
<div id="videoContainer">
<video id="video" controls muted>
<source src="./2025419-450082.mp4" type="video/mp4" />
您的浏览器不支持视频标签
</video>
<canvas id="canvas"></canvas>
<hr />
<div id="show-people"></div>
</div>
<!-- 引入face-api.js -->
<script src="./js/face-api.min.js"></script>
<script>
const video = document.getElementById("video");
const canvas = document.getElementById("canvas");
const playBtn = document.getElementById("playBtn");
function getImage(box) {
// 创建新的画布
const newCanvas = document.createElement("canvas");
const newCtx = newCanvas.getContext("2d");
// 设置新画布的尺寸为截取区域的大小
newCanvas.width = box.width;
newCanvas.height = box.height;
// 从原始画布上绘制截取区域到新画布
newCtx.drawImage(
video,
box.x,
box.y,
box.width,
box.height,
0,
0,
box.width,
box.height
);
// 导出为 Base64 编码的图像数据
const base64Data = newCanvas.toDataURL("image/png");
// 在图像元素中显示截取的图像
// outputImage.src = base64Data;
let showPeople = document.getElementById("show-people");
let img = document.createElement("img");
img.src = base64Data;
showPeople.append(img);
// console.log("Base64 数据:", base64Data);
}
// 初始化函数
async function init() {
// 加载人脸检测模型
await faceapi.nets.tinyFaceDetector.loadFromUri(
"./face-api.js-master/weights"
);
// 设置视频尺寸同步到canvas
canvas.height = video.videoHeight;
canvas.width = video.videoWidth;
}
// 开始检测
async function startDetection() {
const ctx = canvas.getContext("2d");
// 使用requestAnimationFrame实现流畅检测
const detectFrame = async () => {
if (!video.paused && !video.ended) {
// 检测人脸
const detections = await faceapi.detectAllFaces(
video,
new faceapi.TinyFaceDetectorOptions()
);
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// console.log(detections)
// 绘制检测框
detections.forEach((detection) => {
const box = detection.box;
// console.log(box);
ctx.save(); // 保存当前上下文状态
ctx.beginPath();
ctx.rect(box.x, box.y, box.width, box.height);
ctx.strokeStyle = "#ff0000";
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore(); // 恢复之前保存的上下文状态
getImage(box);
});
}
requestAnimationFrame(detectFrame);
};
detectFrame();
}
// 播放按钮点击事件
playBtn.addEventListener("click", async () => {
try {
await video.play();
startDetection();
playBtn.style.display = "none"; // 隐藏按钮
} catch (err) {
alert("视频播放失败: " + err.message);
}
});
// 初始化
window.onload = init;
</script>
</body>
</html>

浙公网安备 33010602011771号