OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库。
准备
首先我们要下载 opencv.js,这里使用的版本是 3.4.14
官网没有直接提供下载地址,这里我们可以从使用文档里下载
还有一个utils.js也要下载
人脸识别模型文件
haarcascade_frontalface_default.xml
然后新建一个index.html
- 展示一张图片
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>人脸识别</title>
</head>
<body>
<div>
<input type="file" id="file" />
<p><canvas id="dist" /></p>
</div>
<script src="opencv.js"></script>
<script src="utils.js"></script>
<script>
const fileElement = document.getElementById("file");
fileElement.addEventListener("change", (e) => {
const img = new Image();
img.onload = function () {
// 读取图片
let src = cv.imread(img);
// 展示图片
cv.imshow("dist", src);
// 释放
src.delete();
};
img.src = URL.createObjectURL(e.target.files[0]);
});
</script>
</body>
</html>
- 在图片上画一个矩形
<script>
const fileElement = document.getElementById("file");
fileElement.addEventListener("change", (e) => {
const img = new Image();
img.onload = function () {
// 读取图片
let src = cv.imread(img);
let point1 = new cv.Point(img.width * 0.1, img.height * 0.1);
let point2 = new cv.Point(img.width * 0.9, img.height * 0.9);
cv.rectangle(src, point1, point2, [255, 0, 0, 255]);
// 展示图片
cv.imshow("dist", src);
// 释放
src.delete();
};
img.src = URL.createObjectURL(e.target.files[0]);
});
</script>
- 人脸检测
<script>
// 这里需要使用utils异步下载模型
let utils = new Utils();
// 模型的路径
let faceCascadeFile = "haarcascade_frontalface_default.xml";
utils.createFileFromUrl(faceCascadeFile, faceCascadeFile, () => {
const fileElement = document.getElementById("file");
fileElement.addEventListener("change", (e) => {
const img = new Image();
img.onload = function () {
// 读取图片
let src = cv.imread(img);
// 创建用于目标检测的级联分类器
let faceCascade = new cv.CascadeClassifier();
// 读取模型
faceCascade.load(faceCascadeFile);
// 矩形向量,用于存放检测到的对象
let faces = new cv.RectVector();
// 对象检测。检测到的对象以矩形列表的形式返回。
faceCascade.detectMultiScale(src, faces);
// 一张图中可能存在多个人脸
for (let i = 0; i < faces.size(); ++i) {
// 矩形左上角坐标
let point1 = new cv.Point(faces.get(i).x, faces.get(i).y);
// 矩形右下角坐标
let point2 = new cv.Point(faces.get(i).x + faces.get(i).width, faces.get(i).y + faces.get(i).height);
// 用红色标出人脸矩形框
cv.rectangle(src, point1, point2, [255, 0, 0, 255]);
}
// 展示图片
cv.imshow("dist", src);
// 释放资源
src.delete();
faceCascade.delete();
faces.delete();
};
img.src = URL.createObjectURL(e.target.files[0]);
});
});
</script>
这里发现有识别错误的地方,可以尝试调整faceCascade.detectMultiScale的参数
| 参数 | 说明 |
|---|---|
| image | CV_8U类型的矩阵,包含检测到对象的图像。 |
| objects | 矩形向量,其中每个矩形包含检测到的对象,矩形可能部分在原始图像之外。 |
| scaleFactor | 指定图像大小在每个图像比例下缩小多少的参数。 |
| minNeighbors | 参数,指定每个候选矩形应该有多少个neighbors来保留它。 |
| flags | 参数,与函数cvHaarDetectObjects中旧级联的含义相同。它不用于新的级联。 |
| minSize | 可能的最小对象大小。小于该值的对象将被忽略。 |
| maxSize | 可能的最大对象大小。大于该值的对象将被忽略。如果maxSize == minSize模型将在固定尺度上进行检测。 |
尝试把scaleFactor调整为1.2,faceCascade.detectMultiScale(src, faces, 1.2)