今年夏天,四位时间紧迫的工程师,没有先前的 WebAssembly 经验,开始了实验。经过六周的探索,他们创造了 WebSight:一个基于 OpenCV 的实时人脸检测演示。
通过将 OpenCV 编译为 WebAssembly,该团队能够直接在浏览器中重用经过充分测试的 C/C++ 库,并实现比类似 JavaScript 库快一个数量级的性能。
我请团队成员——Brian Feldman、Debra Do、Yervant Bastikian 和 Mark Romano——撰写他们的经验。
注意: 以下报告由上述团队成员撰写。
WebAssembly(“wasm”)今年凭借其 MVP 版本 引起轰动,我们迫切希望参与其中,着手构建一个利用这项新技术的应用程序。
我们看到了像 WebDSP 这样的项目将自己的 C++ 视频过滤器编译为 WebAssembly,这是一个 JavaScript 在历史上因某些算法的计算需求而举步维艰的领域。这也让我们对突破 wasm 的极限产生了兴趣。我们想要使用一个现有的、专门的、经过时间考验的 C++ 库,经过深思熟虑,我们选择了 OpenCV,这是一个流行的开源计算机视觉库。
计算机视觉对 CPU 的要求很高,因此非常适合 wasm。借鉴了 UC Irvine SysArch 小组和 Github 用户 njor 所做的出色工作,我们能够更新 OpenCV 过时的 asm.js 版本,使其与现代版本的 Emscripten 兼容,在 JavaScript 可调用格式中公开 OpenCV 的大部分核心功能。
使用这些 Emscripten 版本的过程与我们的预期大相径庭。作为 Web 开发人员,我们习惯于编写代码并能够非常快速地迭代和测试。引入一个构建时间为 10-15 分钟的大型 C++ 库是一种陌生的体验,尤其是在我们的正常工作环境是 Webpack、Nodemon 和无处不在的热重载的情况下。编译完成后,我们以黑盒的方式处理 wasm 构建:模块从一个不可变的庞大对象开始,虽然我们在整个过程中对它越来越了解,但它从未变得“透明”。
用于编译 wasm 文件,然后将其整合到我们的 JavaScript 中的努力是值得的:它轻松地超越了 JavaScript,并且比 WebAssembly 的前身 asm.js 快得多。
我们通过使用人脸检测算法比较了这些格式。驱动这些算法的功能的体系结构相同,唯一的区别是每种算法的实现语言。使用 Web Workers,我们将视频流数据传递给算法,算法返回一个矩形的坐标,该矩形将框住图像中的任何面部,并计算一个 FPS 度量。虽然 FPS 的范围取决于用户的机器和所使用的浏览器(Firefox 占据主导地位!),但我们注意到 wasm 驱动的算法的 FPS 始终是 asm.js 实现的 FPS 的两倍,并且是 JS 实现的 FPS 的 20 倍,这巩固了 WebAssembly 的优势。
构建尖端技术可能很痛苦,但回报值得暂时的痛苦。能够在浏览器中使用本机、可移植的 C/C++ 代码,无需第三方插件,这是一个突破。我们的项目 WebSight 成功展示了将 OpenCV 作为 WebAssembly 模块用于人脸和眼睛检测。我们对 WebAssembly 的未来感到非常兴奋,尤其是最终添加垃圾收集,这将使在浏览器中高效运行其他高级语言变得更加容易。
您可以在 github.com/Web-Sight/WebSight 上查看演示的 GitHub 存储库。
关于 Dan Callahan
Mozilla 开发者关系工程师,前 Mozilla Persona 开发人员。
5 条评论