疫情特殊时期, 各企业, 学校纷纷启用远程办公和学习的方式, 在办公期间, 除了要完成日常工作安排, 还要照顾自身的饮食起居, 在高强度的工作节奏和缺少运动锻炼的情况之下, 如何及早发现健康隐患, 快乐办公? 且看鹅厂小哥 bottlejiang 带来的今日分享.
背 景
你, 是否还在为当下的疫情忧心忡忡? 你, 是否还在为每日三餐苦苦思虑? 不端正的坐姿是否让你腰酸背痛? 窄小的电脑屏幕是否让你眼干眼涩?
居家办公期间, 不知不觉间暴露了很多的健康隐患:
第一: 坐姿问题
家里的办公环境相对简陋, 笔记本屏幕高度低, 一天不知不觉的弯腰驼背.
第二: 吃饭问题
不能出门, 不能叫外卖, 自己做饭不好吃, 又累又乏味.
第三: 喝水问题
高度投入工作时总是忘了喝水运动.
第四: 情绪问题
疫情严峻, 待在出租屋担心染病, 情绪低迷.
我命由我不由天, 健康生活赛神仙! 做为一个工程师, 平日里做了无数的需求, 这一次, 何不为自己做一个需求? 用自己的专业能力, 用自己的双手, 用代码, 去开发, 去创造, 去解决以上问题.
对症下药
1. 针对坐姿问题
要避免弯腰驼背, 需要在我坐姿不端正的时候提醒我. 那么需要解决以下 3 个问题:
实时监控我的坐姿
判断我的坐姿是否端正
当我坐姿不端正的时候提醒我
(1)监控
如何监控? 办法是使用电脑摄像头! 笔记本基本自带, 台式机可以通过接入外设的方式支持.
web 想要调用电脑摄像头, 只需要调用一个 API 就能轻松解决: navigator.mediaDevices.getUserMedia
navigator.getUserMedia 已更名为 MediaDevices.getUserMedia. 同时, 由于隐私原因, 该 API 仅在 https 下支持.
navigator.mediaDevices.getUserMedia 返回一个 promise 对象, 支持音视频, 尺寸帧率等设置.
(2)判断
能够实时拍下我的坐姿图像, 那么又该如何判断我的坐姿端正呢? 解决办法是: 借助 tensorflow.JS!
早在半年前, TensorFlow.JS 最开始吸引我的地方正是他能够识别人像的五官, 输入一张图片, 输出人体器官在图片中位置, 包括: 鼻子, 眼睛, 耳朵, 肩膀, 手肘, 手腕, 臀部, 膝盖, 脚踝.
TensorFlow.JS 是一个 JavaScript 库, 用于在浏览器和 Node.JS 训练和部署机器学习模型. 简单来说就是把机器学习搬到 Web 上. 它的应用有很多, 也已经实现的一些有意思的事情.
问题来了, 工作的时候正对着电脑, 但笔记本摄像头最多只能拍到人的头部五官和肩膀啊?
这里可以想象一下, 当坐姿不端正的时候, 其实头也是不端正的.(头部端正而身体七歪八扭恐怕不常见)所以, 判断五官实际上就已经足够了.
实现上, 初始化 (posenet.load) 之后, 通过 estimateSinglePose 方法输入一个图片, 输出得分 (score) 和人体各部位坐标数据:
- { "score": 0.36588028040440645,
- "keypoints": [
- { "score": 0.998099148273468,
- "part": "nose",
- "position": {
- "x": 318.6268163302529,
- "y": 371.8572926799611
- }
- },
- {
- "score": 0.996922492980957,
- "part": "leftEye",
- "position": {
- "x": 260.77240393968873,
- "y": 307.9062803988327
- }
- },
- ...
- ]
- }
posenet.load 的初始化有很多参数: architecture,outputStride,inputResolution,multiplier,quantBytes,modelUrl.
这些参数是对模型的设置, 跟输出的分辨率, 识别精度, 准确性相关, 并直接影响识别效率和性能. 在当前的需求场景里, 可不必关注这些, 默认即可.
estimateSinglePose 有一个参数 flipHorizontal: 是否应水平翻转 / 镜像姿势.
电脑摄像头返回的是一个与现实方向水平相反的图片 (相对于自己的视角). 通过 ccs 水平翻转 180 度(rotateY(180deg)) 可处理.
同样, 模型的输出通过设置 flipHorizontal 为 true 能够得到相应方向的坐标数据. 得到五官坐标之后, 通过 canvas 将相应的点画到图像上即可验证识别是否正确.
如上图所示, 坐姿端正时, 脸部在图像中间, 双眼双耳水平, 鼻子在眼耳高度之间. 坐姿不端正时往往不能满足以上条件. 那么通过判断五官的相对位置和绝对位置就可以检测坐姿了. 比如近大远小, 越靠近屏幕, 拍到的人脸越大, 两眼的间距也越大. 当大到一定程度可以认为人距离屏幕近到一定的程度, 这个程度就是阈值.
超过这个阈值即可认定为: 此时我正在近距离的盯着电脑屏幕看. 此时我正在不健康的工作.
坐姿不端正一般有以下几种场景, 转换到图片上的五官位置判断如下:
弯腰驼背:
此时整个头部在图像下半部分, 判断鼻子的 y 坐标到图像下边沿的距离
单手托下巴:
此时头部是歪的, 判断两眼的 y 坐标差
斜视:
此时头部沿 y 轴转动, 判断左边的眼睛和耳朵的 x 坐标差和右边眼耳 x 坐标差之差
过度仰视(抬头):
此时头部向上仰, 判断鼻子的 y 坐标是否过于接近眼睛的 y 坐标
过度俯视(低头):
此时头部向下弯, 判断鼻子的 y 坐标是否过于接近耳朵的 y 坐标
眼睛离屏幕太近:
此时头部在图像中更大, 判断两眼的 x 坐标差(近大远小)
接下来就是计算的问题了, 算出各种差值之后设置阈值. 这里可以直接对着屏幕扭转头部试试, 自己感受一下坐姿不端正时的参数, 把握判断的严格和宽松, 逐步调参.
为了达到监控的目的, 图片识别逻辑需要跑一个循环. 这里用 setInterval 或者 requestAnimationFrame 都可以.
requestAnimationFrame 可以做到监控画面十分流畅, 观赏效果极佳, 但是 60 帧还是很吃性能的, 每次都要 TensorFlow 识别, canvas 画图和逻辑判断, 着实有些难顶, 短时间还可以, 长时间跑的话 Mac 便突突突的进入煮鸡蛋模式.
一般来说开着页面放着听告警即可, 这个监控不用那么实时, 用 setInterval 每 500 毫秒跑一次足够.
(4)告警
能够实时拍下我的坐姿图像, 能够判断我的坐姿是否端正, 那么在不端正的时候如何提醒我? 当然是播放语音啦!
从网上下载一段几秒的警铃音频即可. 识别判断坐姿不端正的时候播放该音频, 提醒效果就有了. 音频的播放很简单, 获取 audio 对象, play() 一下即可.
但有一个问题, 以上坐姿不端正的场景有 6 种, 听到告警的时候怎么知道是哪种呢, 毕竟知道是哪种才能立马有针对性的纠正坐姿.
有办法! 这里可以借助谷歌翻译, 下载各种提示文字的朗读音频. 当坐姿不端正的时候, 播放对应的语音. 一开始突然放个警铃总是吓一跳, 谷歌翻译魔性的声音明显更人性化!
除此之外要考虑告警毛刺的过滤. 比如我喝杯水或者伸个懒腰, 这个时候头可能是歪的, 这样的告警是不应该发出来的. 考虑到喝水伸懒腰这些动作都是短时间内完成, 假设 3 秒完成, 那么可以加个判断, 持续 3 秒以上的告警才是真正坐姿不端正的告警, 才需要发出来.
实践中还有一个场景, 当我去上厕所或者出去倒个水的时候, 此时人都不在电脑前了, 按照原先的逻辑肯定是告警的.
这时候, 模型输出的得分 (score) 字段就派上用场了. score 是一个 0 到 1 的数值, 数值越大表示输出的结果更准确可靠. 当人不在电脑前, score 分数小于 0.1, 于是把低于 0.1 分的数据直接舍弃.
最后把阈值和一些设置放到页面上支持编辑, 同时加个告警次数统计, 一天下来可以看到自己是哪种不端正坐姿比较突出, 可以有针对性的做一些运动舒展放松.
2. 针对吃饭问题
吃饭这个问题啊! 对于没有做饭经验的人来说真的是灾难. 但当下情况特殊, 也没的办法. 只能随便对付一下, 比如把食材丢到电饭煲里做懒人饭, 或者买一次性碗筷.
1 天 2 顿饭花 3 个钟, 做出来还不好吃! 这就很没意思了. 做饭这个大前提是扳不倒的, 只能提高一下趣味了. 于是, 按照主食, 肉类, 蔬菜, 小吃四大类, 将囤下来的吃食分类, 然后加个随机功能, 每次到饭点的时候, 按一下, 随机搭配.
这样可以解决两个问题:
吃什么
做饭难, 其实面对一堆食材决定吃什么也很难.
增加趣味
可能随机出一些奇奇怪怪的组合. 未知带来好奇, 让人保持兴趣, 未知是人类进步的阶梯. 是不是有点意思!
这里要加多个去重的逻辑, 连续两次随机出来的食物不能一样. 毕竟午餐和晚餐吃一样的东西就没意思了!
3. 针对喝水 & 运动问题
一天下来常常忘了喝水, 直到口渴的时候才被动想起, 这时候你的身体已经缺水了, 这是不健康的! 一天下来常常一屁股下去坐半天, 长期久坐也是不健康的!
针对这个问题可以做个定时提示, 回想平时工作中容易忘记喝水的时间, 早中晚分别 2 个提醒, 同时加 2 个运动提醒.
实现上也比较简单, 跑个 setInterval 实时对比当前时间和设定提醒时间即可. 告警方式同上.
结语
积极乐观, 开心向上有助于提高免疫力.
成年人的生活没有容易二字, 但要始终相信, 办法总比困难多! 写到这里, 想象着 100 岁的自己, 雄壮有力的敲着键盘, 嘴里念到: 健康生活, 长命百岁.
参考资料:
应用体验:
https://www.doverr.com/alarm/index.html
来源: https://www.qcloud.com/developer/article/1598741