TensorFlow
一、认识
面部识别 的实现分为三部分
-
视频录制时, 实时获取视频帧图像
-
在
Worker
环境中, 处理图像数据的机器学习任务 -
在
canvas
中绘制预测结果, 包括脸型、眼型、嘴型、手势
1.1 视频录制时, 实时获取视频帧图像
根据 机器学习模型 的输入标准, 需要指定视频帧图像的大小, 一般为 320 * 320
, 以左上角顶点为基准, 并填充空白部分。同时, 为了保持模型预测与结果绘制的一致性, 需要将获取的视频帧图像进行水平翻转。随后通过 context.drawImage
将视频元素中的图像绘制到 canvas
上, 最后通过 context.getImageData
获取 canvas
的像素数据。
1.2 在 Worker
环境中, 处理图像数据的机器学习任务
在 Web Worker
环境中, 通过 importScripts
语句导入 TensorFlow.js
库。加载成功后, 通过 tf.loadGraphModel
加载 model.json
的图像面部识别机器学习模型。处理 Worker
Message
事件, 当 Worker
收到消息时,会接收到录制视频时实时获取的视频帧图像数据, 数据类型为 Uint8ClampedArray
。基于图像数据, 开始进行图片面部识别预测和定位。预测定位过程如下所示:
-
图像像素数据预处理: 获取的视频帧图像是一个包含
RGBA
像素数据的一维Uint8ClampedArray
, 由于机器学习模型只需要RGB
三个颜色通道, 所以需要将每个像素的A
透明度通道过滤出去。 过滤方案:if (index % 4 !== 3) { data.push(val) }
, 透明度通道的索引是每个像素的第4
个值,也就是RGBA
中的A
值。 -
基于预处理后的数据, 创建一个
Tensor
张量, 并管理GPU
内存使用: 基于第一步预处理完后的数据, 通过tf.tensor
创建Tensor
张量, 并reshape
为一个4维数组以匹配模型的输入格式。通过tf.tidy
管理GPU
内存的使用,它将在回调函数执行完毕后自动清理中间张量。通过tf.tidy
会回收函数内部创建的所有张量的内存,但不会回收返回的张量的内存。 -
异步运行模型预测, 等待预测结果: 通过
model.executeAsync(张量)
来异步预测结果 -
清理输入数据的张量以节省内存: 通过
tf.dispose
清空输入数据的张量inputData
, -
转换预测结果, 并管理
GPU
内存使用: 循环遍历预测结果, 将人脸、手势、微笑等分离开来,分别放入各自的数组并返回。因此, 转换后会获得包含所有人脸和手部信息的对象。通过tf.tidy
管理GPU
内存的使用,它将在回调函数执行完毕后自动清理中间张量。通过tf.tidy
会回收函数内部创建的所有张量的内存,但不会回收返回的张量的内存。 -
将预测结果告知给主线程: 通过
postMessage
将面部识别模型的预测结果发送给主线程。 -
清理用于预测的张量以节省内存: 通过
tf.dispose
清理用于预测的张量以节省内存
1.3 根据预测结果, 绘制脸型、眼型、嘴型、手势
预测结果中包含 hands
手势、faces
面部位置信息, 其中 faces
中还有 eyes
、mouth
位置信息。位置信息格式为: x1,y1,x2,y2
, 根据位置信息, 绘制各自的矩形框(需要做好尺寸转换后的位置映射关系计算和绘制)。