yoyojacky 发表于 2021-10-12 14:02:30

【骑驴原创】如何通过树莓派4B实现手势识别-Easy Way

hi,大家好,国庆期间想在Jetson Nano上实现手势识别的环境搭建遭遇各种滑铁卢,决定在树莓派上尝试一下通过Python3 + openCV + Mediapipe 库来实现手势的捕捉,为了让实验有趣一些,给食指指尖染上”中国红“, 算是蹭一波热度吧!哈哈

整个项目分为这几个步骤:
0. 项目介绍

OpenCV是什么? 开源的计算机视觉框架,起始也提供了很多强大的视频流处理的能力,各种视觉的应用都离不开这个框架,什么人脸识别啦,动态检测啦,颜色捕捉啦,等等,不一而足,你能通过它实现各种各样有趣的应用。深受视觉学习爱好者的喜爱,由于其基于C++开发,如果有C++编程基础的人用起来可谓得心应手,但是Life is short, 还是用python实现起来更加容易一些。合作厂商也不少:
什么是Mediapipe呢? 它是google开发的一款能够”随时随地进行机器学习“ 的能够为直播和流媒体提供跨平台,可定制的机器学习解决方案的集合。
说人话就是,它让你的openCV用起来更加方便,并提供了机器学习的部分,就算你不太懂机器学习也可以快速搭建自己原型的一个库。通过这个库提供的解决方案能帮你实现什么功能呢?它的解决方案有很多,例如:通过GOOGLE地图实现森林覆盖面积的统计。通过对人脸检测实现人脸模糊处理,想象一下那些失德的艺人, 在其失德之前都已经录制好的影片怎么办?哈哈,让剪辑师一帧帧去剪辑?那不要累死? 通过机器学习分分钟把脸给他模糊了。。。哈哈当遇到需要手写签名而有没有扫描仪的时候怎么办? 手写好,拍张照片,处理一下。。。想要捕获面部的486个landmarks怎么做?如何实现ai换脸? face mesh解决方案就在那里。如果能在染发前先预知了染发后自己能否hold住这个颜色而不是等待染完头发后想要杀了tonny老师? 试试这个:神龙龙抓手?今天我们就想实现这个。而且是在树莓派上实现。下面的这个不错吧?随你摇摆,始终锁定你手部的21个landmark(地标?),就算你的葵花点穴手也一样无从遁形~当然,对象检测(object detection)也是极为有用的,通过对比前后两帧的图像变化检测是否有人入侵?小偷再也逃不出摄像头的视觉范围了,另外,捕捉老鼠一样适用。想要检测”基尼太美“的骨骼动态变化? holistic 解决方案就可以实现,结合pose和face mesh,让你捕捉的明明白白的。使用KNIFT(关键点神经不变特征变换) 将真实的停车标志与停车标志的模板匹配。虹膜检测,管你搔首弄姿,抓住你的虹膜不放手,驾驶舱里的老司机,你瞌睡的样子也会被抓到哦!再看看自动驾驶的应用场景,视觉,激光雷达,一个也少不了。虚拟现实vr,现实增强AR 都可以用到它,捕获物品的整体结构。检测物品类型。。。。更换图形背景,想想腾讯会议的换背景功能。
Pose 解决方案提供了身体姿态检测的方法,自动计数可好?33点的landmarks图示,虽然看起来很诡异,但是想要的每个点都能捕获得到,而且很精准。生活中的OCR很常见了,什么车牌检测识别,已经烂大街了。。还可以用摄像头在天桥上数车玩儿,但凡能够做成产品,交通部的流控摄像头你也可以参与搞一波~对象跟踪也是非常棒的应用,这里就不一一举例了,反正是各种解决方案都会让你目不暇接~那么我们先定一个小目标实现一下, 通过树莓派4B的摄像头识别手部的21个点的landmarks信标。操作步骤:
1. 烧录系统
去树莓派官方下载最新的Raspbian OS(https://www.raspberrypi.com/soft ... pberry-pi-os-32-bit)
选择它,虽然会稍微大一些,但是用起来方便很多,如果你想要小巧的,选择lite版。
2. 安装摄像头
按照下面的步骤依次安装好摄像头,注意蓝色固定硬片的位置永远靠近锁扣。
拔锁扣的时候轻微用力,不然一不小心就拉脱了。。。


3. 启用摄像头
树莓派上安装好硬件启动后,需要在系统中启用摄像头。
在启动好树莓派后,打开一个终端:
输入:
sudo raspi-config选择:



然后重启树莓派。
sudo reboot

4. 配置系统基本环境并更新系统软件仓库索引
重启好以后登陆系统,打开一个终端(ctrl+T)也可以。
按照我以往的操作步骤,肯定是去修改dns配置文件的。
sudo vim.tiny /etc/resolvconf.conf编辑成如下内容:

同时编辑一下:
sudo vim.tiny /etc/resolv.conf
然后在联网成功的基础上执行更新操作。
我在更新前喜欢删除掉wolfram的引擎,占磁盘2155MB的软件,我一般很少用到它,所以干掉它:
sudo apt-get purge wolfram* -y然后再执行更新操作:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get -y install vim tree virtualenv
网速快的情况下,基本上只需要3-5分钟完成更新和升级软件包的操作,并且我根据自己的习惯安装了vim的包,和virtualenv的包,这些能够帮助我们创建一个虚拟的python环境,不会影响系统本身的python环境。作为项目环境非常方便。


我实际上用了9分钟左右完成这个更新操作,相信我,这近10分钟的时间值得你等待,因为后期安装就没有这么复杂了,速度会快很多,而且会很少出问题。
全部更新完成后,建议重启一下树莓派。
sudo sync
sudo reboot


5. 创建虚拟环境并安装相应的库文件
在前期工作都准备好了的情况下,我们开始创建虚拟环境并激活它。
virtualenv -p python3 venv

检查一下当前的库信息:
pip freeze

pip list

安装openCV库和Mediapipe库:
pip install opencv-python
pip install mediapipe-rpi4
numpy会自动安装,不用担心,包括一些依赖的库。


安装完成,我们就可以检查一下安装了哪些库:

下面我们测试一下摄像头。

6. 编写测试摄像头代码
vim test_camera.py
在代码中通过下面的内容来尝试调用摄像头。
import cv2
import time

pTime = 0
cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if cv2.waitKey(1) & 0xFF == 27:
      break
cap.release()

保存退出后,执行:
python test_camera.py如果出现下面的报错消息,可以安装缺少的库。

sudo apt-get -y install libatlas-base-dev
然后再执行:
python test_camera.py
可以发现摄像头可以被opencv调用了。
7. 通过Mediapipe的hands solution来完成手部的Landmark(地标?)的识别。
这里面,会通过Mediapipe的drawing.utils 来实现绘制骨架,并给手指舔一抹”中国红“

下面我们只需要修改之前的代码来实现:
import cv2
import time
import mediapipe as mp

# 定义变量previous time,为了测试fps使用
pTime = 0

执行一下看看:
python test_camera.py



愉快的实现了,虽然FPS只有14帧左右,但是简单应用是足够了。。。
10. 结束语
在Jetson Nano板上受挫后,回归树莓派,还是成功实现了这个小功能,更多的内容等待大家去探索了~

喜欢的话,就赶快翻出你的树莓派开始折腾吧!
{:5_171:}{:5_173:}

yoyojacky 发表于 2021-10-12 14:11:25

import cv2
import time
import mediapipe as mp


pTime = 0

cap = cv2.VideoCapture(0)

mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils

while True:
    ret, frame = cap.read()
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    results = hands.process(frame_rgb)

    if results.multi_hand_landmarks:
      for handlms in results.multi_hand_landmarks:
            for index, landmark in enumerate(handlms.landmark):
                height, width, channel = frame.shape
                middlex, middley = int(landmark.x * width), int(landmark.y * height)
                if index == 8 or index == 4:
                  cv2.circle(frame, (middlex, middley), 15,(0, 0, 255), cv2.FILLED)

            mpDraw.draw_landmarks(frame, handlms, mpHands.HAND_CONNECTIONS)

    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime

    cv2.putText(frame, str(round(fps)), (10, 60), cv2.FONT_HERSHEY_TRIPLEX, 3, (0, 255, 0), 3)

    if cv2.waitKey(1) & 0xFF == 27:
      break
   
    cv2.imshow("frame", frame)

cap.release()
cv2.destroyAllWindows()

yoyojacky 发表于 2021-10-12 14:11:51

完整代码在2楼。

RRoy 发表于 2021-10-12 18:10:40

学习了{:5_167:}

hnyzcj 发表于 2021-10-12 21:35:18

骑驴出品必属精品

yoyojacky 发表于 2021-10-13 15:05:15

hnyzcj 发表于 2021-10-12 21:35
骑驴出品必属精品

太过奖了啊 , 希望对你们有用哈哈。

yoyojacky 发表于 2021-10-13 15:10:47

RRoy 发表于 2021-10-12 18:10
学习了

哈哈,加油~

hnyzcj 发表于 2021-10-14 06:05:30

yoyojacky 发表于 2021-10-13 15:05
太过奖了啊 , 希望对你们有用哈哈。

有用,非常又用

yoyojacky 发表于 2021-10-14 12:59:40

有用就搞起来,想想有啥好创意搞搞看
页: [1]
查看完整版本: 【骑驴原创】如何通过树莓派4B实现手势识别-Easy Way