前言:
百度的手势识别目前能做到21种手势的识别,以及能做到手部关键点识别(手部关键关节点的位置坐标)。
但是目前百度手势识别的输入只能是图片文件,或者是图片的byte数据。
百度官方手势识别文档:
https://cloud.baidu.com/doc/BODY/s/4k3cpywrv
https://cloud.baidu.com/doc/BODY/s/Kk3cpyxeu
要实现隔空手势,必须做到基于视频流识别手势,并转换成Android系统的触屏手势操作,如左滑,右滑,放大,缩小等。
本文基于baidu 手势识别的API 实现了左滑,右滑的手势。其他的手势原理是一样的,可以自己设计算法开发。
接入百度sdk
- 首先需要注册百度云账号:https://cloud.baidu.com/product/body/gesture
-
创建一个新应用,名字随便写可以不和实际项目的名字对应。
创建完成后,在应用列表可以看到生成的应用信息,这里面的三个参数Appid, API key, Secret Key需要保存下来,之后的app接入sdk开发时会用到
3.下载sdk
手势检测demo
笔者的需求是基于摄像头的视频流检测手势,而百度手势识别sdk的输入只能是图片文件或者是图片的byte数据。输出是手的坐标点或手势的名称,所以这里面临着两个问题。
1.如何将视频流数据转换成图片二进制流,然后调用百度的云AI 完成手势检测
2.如何根据坐标点转换成手势
第一个问题很好解决,主要是截取摄像头帧数据,然后转换层图片的byte数据。核心代码如下:
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
Bitmap bp = textureView.getBitmap();
bp = Bitmap.createBitmap(bp, 0, 0, bp.getWidth(), bp.getHeight(), textureView.getTransform(null), true);
if (System.currentTimeMillis() - lastTime > 1000) {
CameraThread cameraThread = new CameraThread(bp);
cameraThread.start();
lastTime = System.currentTimeMillis();
}
}
这里是将Texture的视频流数据转换成bitmap, 然后开启一个线程将bitmap压缩成jpg格式的图片数据
对于第二个问题,我这边采取的算法是:
取视频流前后2帧的数据(间隔1秒,baidu的API有调用的时间间隔限制),发送给baidu API进行手势识别,根据手势识别的结果,取相同的一个关节坐标点(这里我取的是下图中0点的坐标,即手腕的中心点。),第一帧的数据为初始点坐标,第二帧的数据为终点坐标,然后根据手势中同一坐标点的变化来判断左移还是右移。
Demo效果:
Demo 地址:
https://download.csdn.net/download/wxkly2020/20815557