基于图形检测API(shape detection API)的人脸检测

原文:https://paul.kinlan.me/face-detection/

在 Google 开发者峰会中,谷歌成员 Miguel Casas-Sanchez 跟我说:“嘿 Paul,我给你看一个 demo”。看完之后我必须对它进行研究。

Shape Detection API(图形检测API)目前在 WICG 中尚处于孵化和实验阶段,这对于平台来说是一个很好的渐进过程。

Shape Detection API 有意思的地方在于,它是基于用户设备的一些基础硬件功能上创建标准接口的,为 web 平台开启了一组新功能。

在 web 中使用图形检测已有一段很长的时间。有很多的库能够实现边缘检测,面部检测,条形码和二维码检测(我甚至编写过一个具有该功能的 web app)。

Shape Detection API 目前集成在 Chrome Canary(M57)中,能够检测面部、条形码(和二维码),由于 API 还处于实验阶段,你必须开启 chrome://flags/#enable-experimental-web-platform-features。

该 API 使用相当简单,最简单的面部检测是使用图像调用该 API,获取面部列表。

var faceDetector = new FaceDetector();
faceDetector.detect(image)
.then(faces => faces.forEach(face => console.log(face)))
.catch(e => {
console.error("Boo, Face Detection failed: " + e);
});

这里需要一个图像对象(可以是CanvasImageSource,Blob,ImageData 或者一个 <img> 元素),将它传递给系统底层 API,系统将会返回一组 DetectedFace 对象,该对象实际上是包含图像上每一个面部区域的 DetectedObject。

Miguel 写了一个完整的 demo(是我偷来放在 JSBin 的),加载一个图像,传递给检测 API ,然后在图像上绘制出每一个 DetectedFace 的面部矩形区域。(注意:目前仅适用于 Android 的 Chrome,桌面端的很快就能够支持该 API)。

var image = document.getElementById('image');
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d');
var scale = 1; image.onload = function() {
ctx.drawImage(image,
0, 0, image.width, image.height,
0, 0, canvas.width, canvas.height); scale = canvas.width / image.width;
}; function detect() {
if (window.FaceDetector == undefined) {
console.error('Face Detection not supported');
return;
} var faceDetector = new FaceDetector();
faceDetector.detect(image)
.then(faces => {
// Draw the faces on the <canvas>.
var ctx = canvas.getContext('2d');
ctx.lineWidth = 2;
ctx.strokeStyle = 'red';
for(let face of faces) {
ctx.rect(Math.floor(face.x * scale),
Math.floor(face.y * scale),
Math.floor(face.width * scale),
Math.floor(face.height * scale));
ctx.stroke();
}
})
.catch((e) => {
console.error("Boo, Face Detection failed: " + e);
});
}

这有什么用呢?

启用更多的面部检测 API 有许多不同的使用情况,例如你能够:

  检测面部时能够有更好的体验——我们使用该 API 有很大的灵活性,它允许我们在 Service 或者 Web Worker 中进行处理。

  局部图片剪裁——找到图片中的脸后能够自动剪裁图片。

  能够快速标记——快速的找到场景中所有的人脸,创建一个用户界面,使您能够快速标记他们。

  优化面部识别——一旦你有了人脸图像,你就能够将这些区域传递给面部识别工具。

目前这些都能在浏览器上实现吗?是的,但你需要有渐进性的方案。

渐进性方案

很显然这是一个纯 JS API,需要访问底层硬件的 API,但能够“轻松的”(呵呵)渐进式的建立应用,确保使用低版本 Chrome 的用户依然能够访问。

我的想法是遵循相关规范达到渐进增强:服务器 -> JS(+ 也许是 Web ASM)-> Web API,但我会更深入的研究,因为我看到了许多的挑战。

服务器

我们可以创建一个简单的包含 <input type='file'> 的表单,将图像上传到服务器,可以在服务端完成图像检测,然后将结果返回给客户端。

JS

如果我们使用了 JS,我们能够在浏览器上的页面上下文中使用任意一个客户端库完成面部检测。

Web Assembly:

这种方式进行图像识别,甚至是以高性能的方式进行目标检测,是令人难以置信的(至少在我看来)。“原生平台”早已有许多的库(如 Open CV),主要是用 C 写的,能够应用到浏览器上,利用丰富的生态系统,也能够达到相同的性能。

如果有人实现了多边形检测 API ,这将是非常有用的功能。

Web API

现在它可以使用底层系统 API 时,我们就能够在所有的平台上普及。

我觉得这是一个很有趣的 API,它的确为平台开启了很多的可能性,特别是对我,使用底层系统相对于使用纯 javascript ,极大的提高了在 web 上的目标检测性能,这是我期待条形码检测 API 的原因,它将增强二维码扫描器 Web 应用性能的同事,降低其复杂性。

上一篇:C++中的抽象基类示例


下一篇:一个C++bug引入的许多知识