当家里小神兽睡醒乱爬导致摔下床后,我决定做点啥
去年 3 月底的时候小麦子来到了我家,到今天已经 1 岁 1 个月多了,现在这个小家伙已经能熟练爬,也能扶墙走几步了。
前些天,小麦子一个人睡觉,大人们都在忙事情,结果这家伙自己醒了并且悄悄摸摸爬起来,结果不小心摔下了床。
于是我在思考,是否可以利用相关的识别技术来帮助自动监控小麦子睡觉情况呢?现在有大量成熟的案例,虽然不是搞 python 的,但是相信应该也问题不大,毕竟网上相关的教程和例子太多了。
需求
希望利用家里的老旧手机作为无线监控设备,能够自动识别小麦子睡醒状态并发出报警响铃。
方案
前端由于不熟悉 Android 和 iOS 的开发,并且从跨平台考虑,希望能够通过 H5 来实现。
基于 H5,通信协议选择了音视频实时性相对较高的 webRTC 协议。WebRTC 名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的 API。
后端选择 python,提供 Https 服务并且处理 webRTC 相关信令和流数据。具体使用了一个第三方库 aiohttp 和 aiortc 来提供服务。最后也是最核心的部分就是姿势和运动识别。
实现
1. 准备工作
环境
我使用的是 MacBook Pro (13-inch, M1, 2020),提前安装了 python 版本 3.8.9,pip 安装了依赖库 opencv-python 4.5.5.64、aiohttp 3.8.1、aiortc 1.3.1、av 9.1.1 等。
自签名 https 证书由于 chrome 安全限制使用 webRTC 时需通过 https 协议,所以我们提前生成自签名证书,参考下面的脚本
2.代码
启动类 bootstrap.py 主要获取启动参数并启动一个 https 服务。可以手动指定启动 ip 和端口,也可以指定 ssl 相关参数。最后路由相关 http 请求到 service.py
service.py 主要处理相关 request 请求,其中 offer 主要处理 webRTC 的握手协议 sdp 信息并建立 rtc 连接。
rtc.py 实际处理 webRTC 建连的逻辑,通过创建 PeerConnection 并绑定相关回调函数,并给创建的 PeerConnection 绑定 VideoTransformTrack,还可以绑定 datachannel 作为处理一般数据的通道,可以实现一般消息的接收和推送,后面的报警消息就是通过 datachannel 下发的。
当连接建立后,视频流会通过 PeerConnection 上传到服务端,并会通过 VideoTransformTrack,在 recv 方法中实现了视频流中图像检测和报警发出。
检测方法依赖于一个 digits_svm.pkl 文件,这个文件是用 sklearn 的 svm 训练的模型。训练过程在 train.py 中,主要逻辑是加载 trains 文件夹下面的不同子文件夹中的图片,并以子文件夹名字作为对应图片的标签,通过 svm 进行模型训练及测试,最后保存生成的模型。
最后就是前端的逻辑,webRTC 是通过 navigator.getUserMedia 或 navigator.mediaDevices.getUserMedia 获取打开摄像头,可以设置是否要 audio 和 video,且 video 也可以设置 facingMode 来设置是否使用后置摄像头。在获取到摄像头的权限后,将对应的 stream 注册到创建 PeerConnection 中,并在网页上展示播放 video。negotiate 方法则主要是跟服务器发送和接收信令并建立连接。在 createPeerConnection 中为 PeerConnection 创建了一个 DataChannel 并监听了消息,如果服务端返回 alert,则播放报警声音和展示报警动画。
效果检验和优化
一切就绪,找到了闲置了很久的一个平板,安装到了小麦子房间里。首先我录下了他睡觉的一段视频。通过区分睡觉的时候姿势和睡醒的爬或站立的姿势,截取了一系列图片,并将这些图片作为训练集和测试集来训练识别模型。
实验结果比较差强人意:
模型由于训练数据比较少,比较难做到精确的识别,于是我开始转换思路,如果检测到视频里的物体运动则报警。运动物体检测的原理就是将动态的前景从静态的背景中分离出来。将当前画面与假设是静态背景进行比较发现有明显的变化的区域,就可以认为该区域出现移动的物体。opencv 中提供了多种背景减除的算法,其中基于高斯混合模型(GMM)和基于贝叶斯模型的(GMG)最为常用。测试使用 GMG 检测方法,发现检查效果不错,最终 video_transform_track.py 代码如下。
优化后,再次测试效果,先在电脑上用手模拟小麦睡醒后爬动,效果满足预期:在手连续动一段时间后开始报警。最后实际测试报警有效率也达到了 100%。
写在最后
图像识别、行为识别等技术发展到今天,已经非常成熟且易用,普通人也能做出比较炫酷的应用。到今天小麦子头上的包也基本要散了,希望以后这个小家伙再也不会摔下床了。代码已经分享到了 github 上https://github.com/aiortc/aiortc,有兴趣可以下载,欢迎⭐️star。
参考
https://www.bbsmax.com/A/amd0O7y25g/
https://github.com/aiortc/aiortc
版权声明: 本文为 InfoQ 作者【BUG侦探】的原创文章。
原文链接:【http://xie.infoq.cn/article/c337d73d3de4d2aa6ad16e335】。文章转载请联系作者。
评论