1. 简介
照片和图像构成了网页中最大的部分,许多图像包含可识别的特征,比如人脸或者条形码/二维码。检测这些特征需要大量计算,但可以实现有趣的用例,例如人脸标记或网页URL重定向。虽然硬件制造商很早就已经支持这些特性,但网页应用目前还无法访问这些硬件能力,因此需要使用计算开销巨大的库。
文本检测虽然是一个有趣的领域,但在不同计算平台和字符集之间的稳定性还不足以在本规范背景下进行标准化。相关的补充说明请参阅[TEXT-DETECTION-API]。
1.1. 形状检测用例
请参见仓库内的Readme/说明文档。
2. 形状检测 API
各个浏览器可以提供 Detector,指示可用的硬件加速操作能力。
对图像中的特征检测是异步进行的,可能与与硬件加速进行独立通信。完成事件会使用形状检测任务来源。
2.1. 用于检测的图像来源
本节内容参考自HTML Canvas 2D Context § image-sources-for-2d-rendering-contexts。
ImageBitmapSource
允许实现了多个接口的对象作为检测过程的图像来源。
-
当
ImageBitmapSource对象代表HTMLImageElement时,应使用其图像作为源图像。具体来说,如果ImageBitmapSource对象代表HTMLImageElement中的动画图像,用户代理应使用动画的默认图像(即动画不支持或被禁用时格式定义应使用的那个),如果没有,则使用动画的第一帧。 -
当
ImageBitmapSource对象代表HTMLVideoElement时,调用方法时位于当前播放位置的帧应作为源图像,并且源图像的尺寸应为媒体资源的固有尺寸(即经过任何宽高比校正后的尺寸)。 -
当
ImageBitmapSource对象代表HTMLCanvasElement时,应使用其位图作为源图像。
当 UA 需要将指定类型的ImageBitmapSource
作为指定 detector 的detect()方法输入参数时,必须执行以下步骤:
-
如果有任何
ImageBitmapSource的有效脚本来源(origin)不等于文档的有效脚本来源,则 Promise 被 reject,并抛出新的DOMException,其 name 为SecurityError。 -
如果
ImageBitmapSource为处于Broken(HTML Standard §img-error)状态的HTMLImageElement对象,则 Promise 被 reject,并抛出新的DOMException,其 name 为InvalidStateError,并终止后续步骤。 -
如果
ImageBitmapSource为无法完全解码的HTMLImageElement对象,则 Promise 被 reject,并抛出新的DOMException,其 name 为InvalidStateError,并终止后续步骤 -
如果
ImageBitmapSource为其readyState属性为HAVE_NOTHING或HAVE_METADATA的HTMLVideoElement对象,则 Promise 被 reject,并抛出新的DOMException,其 name 为InvalidStateError,并终止后续步骤。 -
如果作为参数的
ImageBitmapSource是其位图origin-clean(HTML Standard §concept-canvas-origin-clean)标志为 false 的HTMLCanvasElement,则 Promise 被 reject,并抛出新的DOMException,其 name 为SecurityError,并终止后续步骤。
注意如果ImageBitmapSource
是水平方向或垂直方向的尺寸任一为零的对象,则 Promise 会直接以空的检测对象序列 resolve。
2.2. 人脸检测 API
FaceDetector
代表底层加速平台检测图像中人脸的组件。可使用可选的FaceDetectorOptions
字典创建。它提供了一个在ImageBitmapSource上操作的detect()
方法,返回 Promise。该方法必须在§ 2.1 用于检测的图像来源中所述情况下 reject
Promise,否则可以利用系统/平台资源排队任务,resolve 为DetectedFace序列,
每个对象主要包含由boundingBox
限定的区域。
[Exposed =(Window ,Worker ),SecureContext ]interface {FaceDetector constructor (optional FaceDetectorOptions = {});faceDetectorOptions Promise <sequence <DetectedFace >>detect (ImageBitmapSource ); };image
FaceDetector(optional FaceDetectorOptions faceDetectorOptions)-
构造一个新的
FaceDetector,可带可选参数faceDetectorOptions。Detector 可能会分配和持有大量资源。尽量多次检测时复用同一个FaceDetector。 detect(ImageBitmapSource image)- 尝试在
ImageBitmapSourceimage中检测人脸。检测到的人脸以DetectedFace序列返回。
2.2.1.
FaceDetectorOptions
dictionary {FaceDetectorOptions unsigned short maxDetectedFaces ;boolean fastMode ; };
maxDetectedFaces, 类型为 unsigned short- 提示 UA 尽量将场景中检测到的人脸数限制为该最大值。
fastMode, 类型为 boolean- 提示 UA 优先考虑速度而不是准确性,比如用缩小比例或者查找较大的特征来加速。
2.2.2. DetectedFace
dictionary {DetectedFace required DOMRectReadOnly boundingBox ;required sequence <Landmark >?landmarks ; };
boundingBox, 类型为 DOMRectReadOnly- 指明检测特征位置和范围的矩形区域,与图像轴对齐。
landmarks, 类型为 sequence<Landmark>, 可为 null- 与检测出的特征相关的重要部位点的序列。
dictionary {Landmark required sequence <Point2D >locations ;LandmarkType type ; };
locations, 类型为 sequence<Point2D>- 为检测到的关键点中心,或定义该关键点外围简单多边形各顶点(顺时针或逆时针方向)的点序列。
type, 类型为 LandmarkType- 关键点类型(若可知)。
enum {LandmarkType "mouth" ,"eye" ,"nose" };
mouth- 该关键点被识别为人类嘴巴。
eye- 该关键点被识别为人类眼睛。
nose- 该关键点被识别为人类鼻子。
[SameObject] readonly attribute unsigned long id;
之类属性到DetectedFace。
2.3. 条形码检测 API
BarcodeDetector
代表底层加速平台检测图像中一维或二维条码的组件。它提供一个操作于ImageBitmapSource的detect()
方法,返回 Promise。该方法必须在§ 2.1 用于检测的图像来源所述情况下 reject
Promise,否则可以利用系统/平台资源排队任务,resolve 为DetectedBarcode序列,
每个对象主要包含boundingBox
和一系列Point2D,
还可能包含解码后的rawValue
的DOMString。
[Exposed =(Window ,Worker ),SecureContext ]interface {BarcodeDetector constructor (optional BarcodeDetectorOptions = {});barcodeDetectorOptions static Promise <sequence <BarcodeFormat >>getSupportedFormats ();Promise <sequence <DetectedBarcode >>detect (ImageBitmapSource ); };image
BarcodeDetector(optional BarcodeDetectorOptions barcodeDetectorOptions)-
构造一个新的
BarcodeDetector,带参数barcodeDetectorOptions。Detector 可能会分配和持有大量资源。尽量多次检测时复用同一个BarcodeDetector。 getSupportedFormats()-
调用后必须返回一个新
Promisepromise,并按如下步骤并行执行: detect(ImageBitmapSource image)- 尝试在
ImageBitmapSourceimage中检测条形码。
2.3.1.
BarcodeDetectorOptions
dictionary {BarcodeDetectorOptions sequence <BarcodeFormat >formats ; };
formats, 类型为 sequence<BarcodeFormat>-
在后续
detect()调用中要搜索的一系列BarcodeFormat。如果未提供,则用户代理应搜索所有支持的格式。仅在部分支持的格式范围内进行搜索更可能带来更好的性能。
2.3.2.
DetectedBarcode
dictionary {DetectedBarcode required DOMRectReadOnly boundingBox ;required DOMString rawValue ;required BarcodeFormat format ;required sequence <Point2D >cornerPoints ; };
boundingBox, 类型为 DOMRectReadOnly- 用于指示检测到的特征在图像中的位置和范围的矩形
rawValue, 类型为 DOMString- 从条码解码出来的字符串。该值可以为多行。
format, 类型为 BarcodeFormat- 检测到的
BarcodeFormat。 cornerPoints, 类型为 sequence<Point2D>- 检测到条码的角点序列,按顺时针方向,并从左上角开始。由于可能存在透视变形,所以不一定是正方形。
2.3.3.
BarcodeFormat
enum {BarcodeFormat "aztec" ,"code_128" ,"code_39" ,"code_93" ,"codabar" ,"data_matrix" ,"ean_13" ,"ean_8" ,"itf" ,"pdf417" ,"qr_code" ,"unknown" ,"upc_a" ,"upc_e" };
aztec- 此项表示一种方形的二维矩阵,遵循[iso24778] ,中心有方形靶标图案,因此类似阿兹特克金字塔。无需外围空白区域。
code_128- Code 128 是一种线性(一维)、双向可解码、自检的条码,遵循 [iso15417] 标准,能编码全部 128 个 ASCII 字符(因此得名)。
code_39- 此处指 Code 39 条码。它是一种离散、可变长度的条码类型。 [iso16388]
code_93- Code 93 是一种线性、连续、可变长度的符号体系,遵循[bc5]。它的信息密度大于 Code 128 和形似的 Code 39。Code 93 主要被加拿大邮政用于编码补充投递信息。
codabar- Codabar 是 Pitney Bowes 公司于 1972 年开发的线性条码符号体系。
data_matrix- Data Matrix 是一种不受方向影响的二维条码,由黑白单元按方形或矩形排列,遵循[iso16022]。
ean_13- EAN-13 是一种基于 UPC-A 标准的线性条码, 定义见 [iso15420]。 最初由欧洲国际物品编号协会(EAN)开发,作为最早美国 12 位通用产品代码(UPC)系统的超集(UPC-A 作为首位为 0 的 EAN-13 表示)。
ean_8- EAN-8 是[iso15420] 中定义的线性条码,由 EAN-13 演变而来。
itf- ITF14 条码是 GS1 对“交错式二五条码”的实现,用于编码全球贸易项目号。它是连续、自校验、双向可解码且编码为固定 14 位数字。曾被用于快递行业,后被 Code 128 取代。 [bc2]
pdf417- PDF417 为连续型二维条码格式,具多行多列,双向可解码,遵照 [iso15438] 标准。
qr_code- 二维码(QR Code)是遵循标准 [iso18004] 的二维条码。可编码文本、URL 或其他数据。
unknown- 此值由平台用于指示其未知或未指定被检测/支持的条码类型。
upc_a- UPC-A 是美国最常见的线性条码之一,广泛应用于零售。定义见 [iso15420] ,用条和空的组合表示数字,每位数字用一个独特的 2 条 2 空宽度唯一组合表示。UPC-A 可编码 12 位唯一商品编号,技术上是EAN-13 的子集(UPC-A 代码在 EAN-13 表示时首位为 0)。
upc_e- UPC-E 条码是 UPC-A 的一种变体,定义见 [iso15420] ,通过去除多余的零实现更紧凑的条码。
3. 安全与隐私注意事项
本节为非规范性内容。
该接口会暴露图像源内容的信息。实现时务必确保不能用于绕过其他原本保护图像源不被读取的机制。§ 2.1 用于检测的图像源说明了相关算法。
通过为本地设备上的图像分析提供高性能的形状检测能力,本接口比将任务转交远程系统更有隐私优势。开发者应将该接口返回结果视为与原始图像等同的隐私敏感内容。
4. 示例
本节为非规范部分。
这些示例的部分修改或扩展版(以及更多案例)可在例如 这个 codepen 集合中找到。
4.1. 检测器的可用性平台检查
if ( window. FaceDetector== undefined ) { console. error( 'Face Detection not supported on this platform' ); } if ( window. BarcodeDetector== undefined ) { console. error( 'Barcode Detection not supported on this platform' ); }
4.2. 人脸检测
let faceDetector= new FaceDetector({ fastMode: true , maxDetectedFaces: 1 }); // Assuming |theImage| is e.g. a <img> content, or a Blob. faceDetector. detect( theImage) . then( detectedFaces=> { for ( const faceof detectedFaces) { console. log( ' Face @ (${face.boundingBox.x}, ${face.boundingBox.y}),' + ' size ${face.boundingBox.width}x${face.boundingBox.height}' ); } }). catch (() => { console. error( "Face Detection failed, boo." ); })
4.3. 条码检测
let barcodeDetector= new BarcodeDetector(); // Assuming |theImage| is e.g. a <img> content, or a Blob. barcodeDetector. detect( theImage) . then( detectedCodes=> { for ( const barcodeof detectedCodes) { console. log( ' Barcode ${barcode.rawValue}' + ' @ (${barcode.boundingBox.x}, ${barcode.boundingBox.y}) with size' + ' ${barcode.boundingBox.width}x${barcode.boundingBox.height}' ); } }). catch (() => { console. error( "Barcode Detection failed, boo." ); })