侧边栏壁纸
博主头像
钱学超博主等级

火星人,1万小时法则的忠实拥趸。技术宅,象棋和羽毛球爱好者,马拉松PB成绩:4小时零8分。坚持认为算法是计算机的灵魂。喜欢解决问题,喜欢手工,喜欢与朋友们聊天喝酒吹牛X。

  • 累计撰写 87 篇文章
  • 累计创建 472 个标签
  • 累计收到 97 条评论
标签搜索

目 录CONTENT

文章目录

Flutter开发,怎样优雅的实现使用手势控制App操作

钱学超
2022-06-07 / 0 评论 / 1 点赞 / 1,338 阅读 / 1,851 字 / 正在检测是否收录...
  1. 注意这个手势不是GestureDetector,而是机器学习,视觉识别,识别出手势,从而进行不同的响应。

  2. 想到机器学习,就想到tensorflow,pytouch,那么适合移动端使用的,pytouch有TorchVision移动版、Mobile Interpreter,tensorflow可以使用TensorFlow Lite。

  3. 都是可以的,查了一下,google的开源项目比较多,文档和资源也比较丰富。所以采用了tflite。

  4. 下面开始整个过程:

  5. 查询google的开源项目,发现一个有意思的机器学习工具组件:MediaPipe。
    这是它的官方介绍,一句话说的挺大啊

    MediaPipe offers open source cross-platform, customizable ML solutions for live and streaming media.
    
  6. 查看详细资料,不得了啊,支持的内容相当丰富呐。
    image-1654526356082
    人脸识别,面部动作捕捉,虹膜,手势识别,人体姿势识别等等,简直丰富极了。
    因为之前使用过tf的ObjectDetection,整个过程充满了python、算法、参数、编译、高性能计算机等等,让人头大的厉害,这么多功能集成到一起,这个组件是不是得相当庞大啊!

  7. 往下看,有各种移动端的实现,看样子不应该那么复杂啊。
    因为移动端一般性能不太高,开发过程也相对SDK化,看它支持这么多,应该可以了解一下!
    image-1654526737002

  8. 找到手势识别这一章节,发现google果然是google啊,使用方式那叫一个简单!解释的那叫一个清楚!甚至人家都给出了样例代码!
    image-1654526863376

  9. 没错,你看到的就是将来你要使用的!这些代码,我猜你都修改不了其中的20% !
    看看效果,嗯,这是人家google的:
    image-1654529253529

  10. 说干就干,代码撸起来!

  11. …漫长的封控,可恶的新冠,可恶的他!!!!

  12. 写完了。展示一下效果先(图两张,大gif等待下载中…):
    Gif_20220606_230928-1654529329657
    Gif_20220606_231113
    注意等待!这里有一张贴图,特别大!
    ^
    |
    |
    |

  13. 嗯,看到这里的朋友,很有耐心。下面说一说这个项目里边的坑。

  14. 首先就是google本身也不是神,他们的东西有些也不是很合理。比如在hands这个项目中,用到了摄像头。google封装的工具类中,居然只支持前置和后置摄像头!!!
    嗯,朋友你会说,这有什么问题呐,确实,如果是移动端专指手机的话,一般来说没有什么问题。近十年的手机都有前置和后置摄像头。但是,现在不够用!因为会有一些设备,比如电视盒子,比如车载设备,比如音箱,没有摄像头!
    我不是胡扯,你先别说没有摄像头搞什么飞机的问题。我先解决一下没有摄像头的问题,我就买了一台USB摄像头,UVC标准摄像头。插上就可以用那种,嗯,电视盒子虽然不带摄像头,但是也有一个相机APP, 接上外置摄像头,打开就可以拍照的那种。既然相机可以使用,那么是不是我们就可以用它来做手势识别呢?错!默认人家不支持usb camera!
    google封装的sdk也不好使了,mediapipe居然只有两个摄像头!front–back,肿么办?
    改呗,找到几个关键类,找到关键算法,增加一个摄像头类型,external,这才可以。

  15. 其次,还有一些小问题。
    比如mediapipe并不是原生支持手势识别,你说识别多少种手势那种。他们使用机器学习,深度学习的方法,利用人工智能,结合复杂神经网络,将人的手分割开来,识别出手的位置,并且把手切分为5个手指和一个原点。这个原点就是手腕位置,然后每个手指头使用4个点(指节两端)来标识。
    有意思极了,如果某个人的一只手只有4根手指会怎么样呢?嗯,他会凭空想象出来那一根手指的位置,并且不断的颤抖。
    在此基础之上,如果你想要它识别手势,就需要自己进行定义。比如,中国人表示的十个数字,外国人经常用的OK,蜘蛛人,兰花指等等。无非是判断哪根手指打开,哪根手指闭合,哪根手指跟哪根手指距离相近等等。
    我的应用控制比较简单,只需要:拳头、五、OK,左、 右五个基本手势就可以了,但是左右两个手势可不是那么简单。因为你可以用拇指导向左边表示左,也可以用食指导向左边表示左,甚至可以用中指…🖕…
    需要一点点算法。

  16. 最后就是一些小bug,比如经常会碰到的 EGL 0x300d错误的问题,也是他们sdk的一个bug。摄像头使用的是cameraX,原理是将摄像头的生命周期,与当前的Activity(页面)进行绑定,随着它生命周期变化而变化,息屏、退出时关闭摄像头,打开,继续显示时打开摄像头等等。
    小bug就是有时候不好使。抛错EGL 0x300d,查google也不好使,找不到对应解决方案。解决这个问题时也有点钻牛角尖,坚决认为既然打开了摄像头,就要关闭它,有始有终,结果求而不得。最终发现,原来是tm操作干多了!不需要那么多操作。
    于是改之!好在java是开源的(kotlin还不熟),反编译一下,改好了之后用咱自己的类,原理就是上面说的,跟页面绑定,页面打开时,摄像头自动打开,反之,如果想关闭摄像头,只需要解绑这个页面就好了。解绑之后,摄像头认为已经没有人需要它了,所以就自动关闭。
    image-1654532630958

  17. 期间还遇到frameBuffer错误(framebuffer status (return 36054) ),也是比较难解决,看起来没有什么特别用处的代码,删了就是不好使。翻了半天历史,才找到根本原因,人家egl封装的挺好的,buffer没有处理完毕只是表象,根本原因是你切掉了人家处理的部分。。。。好吧,都是泪。


就这些吧,想起来的时候再补上。
欢迎遇到同样问题,或者类似诡异问题的朋友留言一起讨论。

1

评论区