浏览器中的图像识别 API

时间: 2017-12-29阅读: 1758标签: api

前言

在这几年的前端发展中,Web 应用不断朝着 Native APP 的体验发展,比如在今年被谈及最多的 PWA,就连 Apple 都逐渐在自家浏览器 safari 中集成 Service Worker。在各大浏览器厂商的支持下,Web 逐渐拥有了更多的能力,同时随着硬件的一代代升级,前端应用中的体验也在逐渐提升。

然而很多时候,对于硬件底层的调用以及复杂运算上仍然需要 Native APP 的支持,在 Webview 环境中以 jsBridge 的形式提供给前端应用调用。这使得很许多前端应用只能依托于 Native APP 定制的 Webview。当然,浏览厂商也在不断跟进,把许多底层的硬件接口和系统层面的接口直接提供给 Web 使用,比如 Web Bluetooth API 、Web Share API、Shape Detection API 等等。

在本篇文章中,将介绍 Chrome 中集成的图形识别 API (Shape Detection API)。


图形识别

照片和图像是互联网构成中最大的部分,其中相当一部分包含了可识别的特征,比如人脸,二维码或者文本。可想而之,识别这些特征的计算开销非常大,但有些很有趣场景,比如在照片中自动标记人脸,或者根据图像中的 URL 进行重定向。
硬件厂商从很久以前就已经开始支持这些特性,但 Web 应用迟迟未能很好地利用上这些硬件特性,必须借助一些难用的程序库才能达到目的。  

由于图像识别需要系统层面的资源与计算能力,因此只有原生的底层 API 能够驾驭的住。在目前的 Web 应用中,涉及到图像识别的功能时,一般是将图片上传至服务器或者在 Webview 中通过 jsBridge 传给 Native APP ,在其计算出结果之后返回到 Web 中继续处理。对于 Web 来说,其能力则显得单薄,必须依托于服务端的处理或者是 JSBridge ,而如果对图像的处理能够成为 Web 的一个标准 API,那么其体验将会得到很大程度的提升。

在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。

而在 Web 应用中为何就不能有一套标准的 js API 来调用系统底层的能力呢?

Chrome 团队在 16 年就尝试在浏览器中集成了直接提供给 Web 开发调用的 Shape Detection API 。目前图形识别 API 在 WICG 中还处于孵化和实验阶段,如果想开启该功能,需要下载 Canary 版本的 Chrome 浏览器( https://www.google.com/chrome/browser/canary.html),然后在地址栏输入 chrome://flags/#enable-experimental-web-platform-features ,在 Experimental Web Platform features 这一项点击 “启用” 来开启该实验性的功能。

接下来验证一下浏览器是否支持了该 API ,在 Console 中输入:

window.FaceDetector
window.BarcodeDetector
window.TextDetector

如果 LOG 出:

ƒ FaceDetector() { [native code] }
ƒ BarcodeDetector() { [native code] }
ƒ TextDetector() { [native code] }

则说明你已经可以在浏览器中调用 Shape Detection API 了。

虽然目前来说该 API 还处于实验阶段(实验阶段的功能是不稳定的,其最终并不一定会正式集成),但是作为新时代的前端开发者,我们还是愿意尝尝鲜的。

TIP:以下例子都需要下载 Canary 版本的 Chrome 浏览器,并且开启 Experimental Web Platform features 实验性功能。


API 能力

Shape Detection API 提供了三个接口可以调用:

  • FaceDetector: 人脸识别;
  • BarcodeDetector: 二维码/条形码 识别;
  • TextDetector: 文本识别;

1. 人脸识别

FaceDetector 是一个针对图像中的人脸进行识别的底层加速平台组件类,它接受一个配置参数 FaceDetectorOptions ,我们直接创造一个 FaceDetector 实例:

const faceDetector = new FaceDetector({
fastMode: true,
maxDetectedFaces: 10
});

FaceDetectorOptions 中的参数:

  • fastMode: [Boolean] ,表示是否开启速度优先(于精确度)模式,将通过更小的比例尺(更靠近目标图形)或寻找更大的目标图形的办法进行识别;
  • maxDetectedFaces: [Number] ,当前场景中已识别的人脸数的最大值;

FaceDetector 类有一个方法 detect ,接受一个图片的 Image 或者 Blob 对象,用来检测该图片中的人脸,同时返回一个 Promise 对象:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Shape Detection API Demo</title>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<img
id="face-image"
src="//opsqe9du9.bkt.clouddn.com/1.jpeg" alt="image"
crossorigin="anonymous"
style="width: 100%;"
/>
<script type="text/JavaScript">
window.onload = main();
function main () {
const faceDetector = new FaceDetector({fastMode: true, maxDetectedFaces: 10});

const image = document.getElementById('face-image');

faceDetector.detect(image)
.then(detectedFaces => {
console.log(detectedFaces);
})
.catch((e) => {
console.error("Face Detection failed, boo.", e);
});
}
</script>
</body>
</html>

以上例子中:在 HTML 中创建了一个 img 标签(这里需要注意一点,如果图片来自跨域,那么需要设置crossorigin="anonymous"),之后获取到 Image 对象,调用 faceDetector.detect 来检测图片中的人脸,在识别成功后打印出 detectedFaces 得到:

(5) [DetectedFace, DetectedFace, DetectedFace, DetectedFace, DetectedFace]
0: DetectedFace
boundingBox: DOMRect
bottom: 275
height: 44
left: 710
right: 754
top: 231
width: 44
x: 710
y: 231
landmarks: Array(3)
0:
location: {x: 729, y: 246}
type: "eye"
1: {location: {…}, type: "eye"}
2: {location: {…}, type: "mouth"}
length: 3
1: DetectedFace {boundingBox: DOMRect, landmarks: Array(3)}
2: DetectedFace {boundingBox: DOMRect, landmarks: Array(3)}
3: DetectedFace {boundingBox: DOMRect, landmarks: Array(3)}
4: DetectedFace {boundingBox: DOMRect, landmarks: Array(3)}
length: 5

可以看到,这里识别到了 5 个人脸,返回了一个 length === 5 的数组,每个数组元素都是一个 DetectedFace 对象,包含了两个属性:

  • boundingBox: DOMRect 对象,包含了该识别区域的位置(bottom、top、left、right、x、y)、大小信息(width、height);
  • landmarks: 为一个数组,包含了其脸部的一些特性信息,比如眼睛(eye)、嘴巴(mouth),及其位置信息(x、y);

完整 Demo: https://tongchengqiu.github.io/mixin-demo/demo-shape-detection/1.html

2. 二维码/条形码识别

BarcodeDetector 是一个针对图像中的二维码或条形码进行识别的底层加速平台组件类,我们直接创建其实例:

const barcodeDetector = new BarcodeDetector();

和 FaceDetector 一样,使用 detect 函数来检测图片,该方法同样接受一个图片的 Image 或者 Blob 对象,同时返回一个 Promise 对象:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Shape Detection API Demo</title>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
</style>
</head>
<body>

<img id="qrcode-image" crossorigin="anonymous" src="//opsqe9du9.bkt.clouddn.com/img-2.png" alt="QRCODE">

<script type="text/JavaScript">
window.onload = main;

function main () {
const barcodeDetector = new BarcodeDetector();

const image = document.getElementById('qrcode-image');

barcodeDetector.detect(image)
.then(detectedCodes => {
console.log(detectedCodes);
})
.catch((e) => {
console.error("Barcode Detection failed, boo.", e);
})
}
</script>
</body>
</html>

和上述例子一样,打印出检测获取到的 detectedCodes:

[DetectedBarcode]
0: DetectedBarcode
boundingBox: DOMRect
bottom: 375.4765348434448
height: 362.06744384765625
left: 9.409090042114258
right: 371.47656440734863
top: 13.409090995788574
width: 362.0674743652344
x: 9.409090042114258
y: 13.409090995788574
cornerPoints: Array(4)
0: {x: 9.52997875213623, y: 13.529980659484863}
1: {x: 370.59088134765625, y: 13.409090995788574}
2: {x: 371.4765625, y: 375.4765319824219}
3: {x: 9.409090042114258, y: 374.5908508300781}
length: 4
rawValue: "https://qiutc.me/"
length: 1

获取到的数组中每个元素是一个识别到的二维码的 DetectedBarcode 对象,包含了三个属性:

  • DetectedBarcode: 二维码的位置信息;
  • cornerPoints: 一串已识别条形码的顶点序列;
  • rawValue: 该二维码表示的真实值,是一个 String 值;

完整 Demo: https://tongchengqiu.github.io/mixin-demo/demo-shape-detection/2.html

3. 文字识别

TextDetector 是一个针对图像中的文本进行识别的底层加速平台组件,我们直接创建其实例:

const textDetector = new TextDetector();

和 FaceDetector 一样,使用 detect 函数来检测图片,该方法同样接受一个图片的 Image 或者 Blob 对象,同时返回一个 Promise 对象:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Shape Detection API Demo</title>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<img id="text-image" crossorigin="anonymous" src="//opsqe9du9.bkt.clouddn.com/img-3.png" alt="TEXT">
<script type="text/javascript">
window.onload = main;
function main () {
const textDetector = new TextDetector();
const image = document.getElementById('text-image');
textDetector.detect(image)
.then(detectedTexts => {
console.log(detectedTexts);
})
.catch((e) => {
console.error("Text Detection failed, boo.", e);
})
}
</script>
</body>
</html>

和上述例子一样,打印出检测获取到的 detectedTexts:

(12) [DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText, DetectedText]
0: DetectedText
boundingBox: DOMRect {x: 190.78125, y: 42.1875, width: 1527.984375, height: 31.21875, top: 42.1875, …}
cornerPoints: (4) [{…}, {…}, {…}, {…}]
rawValue: ""
1: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
2: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
3: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
4: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
5: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
6: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
7: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
8: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
9: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
10: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
11: DetectedText {rawValue: "", boundingBox: DOMRect, cornerPoints: Array(4)}
length: 12

获取到的数组中每个元素是一个识别到的文字的 DetectedText 对象,包含了三个属性:

  • DetectedBarcode: 文字的位置信息;
  • cornerPoints: 顶点位置信息;
  • rawValue: 文字真实值,从 demo 中我们发现这里为空,应该是该功能还未被实现完全;

完整 Demo: https://tongchengqiu.github.io/mixin-demo/demo-shape-detection/3.html



总结

从目前来看,Shape Detection API 还处于测试实验阶段,其功能也不尽完善,但是相信在未来的几年,该功能会逐渐被完善并且应用于生产环境。

有了 Shape Detection API ,在很多场景下都可以很大程度地降低应用的复杂性,并且使得 Web 应用更加具有独立性。

  • 应用人脸识别,我们能在用户处理图片的时候更精确的标识出人脸,给予更精确的建议;
  • 应用 二维码/条形码 识别,配合摄像头的调用,可以直接在前端层面获取扫描信息,进行支付、跳转、添加好友等操作;
  • 应用文字识别,我们能够直接在用户端实现 OCR 的功能;

从目前来看,越来越多的底层 API 可以直接在浏览器环境中使用,前端应用能够直接使用更多的系统资源,调用更多的硬件接口。这也是未来的一个趋势,当浏览器赋予了 Web 更多的能力,Web 也将可以提供给用户更优秀的体验。

参考

来源:http://www.itboth.com/d/rQ3ABz/api

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/296

Vue3 Composition API 如何替换Vue Mixins

想在你的Vue组件之间共享代码?如果你熟悉 Vue 2 则可能知道使用 mixin ,但是新的 Composition API 提供了更好的解决方案。在本文中,我们将研究mixins的缺点,并了解Composition API如何克服它们

scrollIntoView 与 scrollIntoViewIfNeeded API 介绍

Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。而Element.scrollIntoViewIfNeeded()方法也是用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。但如果该元素已经在浏览器窗口的可见区域内

Composition API

Composition API的主要思想是,我们将它们定义为从新的 setup 函数返回的JavaScript变量,而不是将组件的功能(例如state、method、computed等)定义为对象属性。

认识 Fetch API

Fetch API 已经作为现代浏览器中异步网络请求的标准方法,其使用 Promise 作为基本构造要素。Fetch 在主流浏览器中都有很好的支持,除了IE。

使用 JS 来动态操作 css ,你知道几种方法?

JavaScript 可以说是交互之王,它作为脚本语言加上许多 Web Api 进一步扩展了它的特性集,更加丰富界面交互的可操作性。这类 API 的例子包括WebGL API、Canvas API、DOM API,还有一组不太为人所知的 CSS API

超赞的腾讯短网址(微信url.cn短链接)生成api接口

腾讯短网址的应用场景很广,譬如短信营销、邮件推广、微信营销、QQ营销、自媒体推广、渠道推广等,都会用到短网址。究其原因是在于短网址可以降低推广成本、用户记忆成本,提高用户点击率;在特定的场景下推广还能规避关键词,防止域名被拦截

如何更好的设计 RESTful API

当您的数据模型已开始稳定,您可以为您的网络应用程序创建公共API。 你意识到,很难对你的API进行重大更改,一旦它发布,并希望尽可能得到尽可能多的前面。 现在,互联网对API设计的意见有很多。

vue之按钮权限及优雅请求API

系统开发中按钮级权限控制也是非常重要的功能之一,可以严格控制不同角色用户所拥有的功能权限。首先可以通过vue的自定义指令来控制按钮(div,link也阔以)等的显示与否以及是否禁用状态。

Moment.js常用API速查

日常开发经常会用Moment.js来处理时间,现对频繁使用的几个API做下整理,以便日后查阅。

在原生 React Native 应用中使用 Expo API

你可以在任何 React Native 应用程序中使用尽可能少或尽可能多的 Expo SDK。 我们已经花了很多时间构建和维护这些包含原生应用特性的跨平台 API,我们很高兴最终实现了向整个 React Native 生态共享这些 API

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!