5808浏览
查看: 5808|回复: 2

[项目分享] [教程]【Mind+Mediapipe+pinpong】机械手

[复制链接]
本帖最后由 gray6666 于 2022-10-17 15:39 编辑

一直关注群里的各种手势识别案例的帖子,无奈机器不给力,安装起来各种小状况不断;9月份学校升级新电脑,在闲鱼偶遇机械手,给孩子们上课写简单的了一个入门帖子,记录这段无奈的幸运。
一、计算机硬件
1.i5处理器,8GB内存
[教程]【Mind+Mediapipe+pinpong】机械手图1


2.自带摄像头,功能稍微有点弱,后期准备换高清的试试
[教程]【Mind+Mediapipe+pinpong】机械手图2
二、实验硬件
1.机械手1只
2.Romeo 三合一Arduino兼容控制器(DF出品利器,可用其他uno板替换)https://www.dfrobot.com.cn/goods-54.html
3.9V电池*1
4.USB数据线一条[教程]【Mind+Mediapipe+pinpong】机械手图7
三、实验软件
mind+1.7.2RC Python模式
[教程]【Mind+Mediapipe+pinpong】机械手图3
四、实现过程
1.基于Google的Mediapipe框架,利用其自身返回的坐标,计算手指的弯曲角度;依据官网的说明,mediapipe处理视频流的函数能够返回手部标注节点的三维坐标


[教程]【Mind+Mediapipe+pinpong】机械手图4
判断手指弯曲,可以使用每个手指的三个定位点,比如食指为6-7-8三点;知道坐标点位置,开始计算手指运动过程中的夹角。以食指为例,计算∠876。推导过程比较简单,因为知道三个点的xy坐标,借助三角函数弧度rad=arctan(y/x)分别求出两条直线的正切角,再相减即可。


[教程]【Mind+Mediapipe+pinpong】机械手图5


2.代码实现
导入CV,mediapipe,pinpong库;初始化xy点的坐标,初始化uno板和舵机
  1. <font size="4" face="微软雅黑">import cv2
  2. import mediapipe as mp
  3. import time
  4. import numpy as np
  5. from pinpong.board import Board,Pin,Servo
  6. Board("uno").begin()
  7. cap=cv2.VideoCapture(0)
  8. mpHands = mp.solutions.hands
  9. hands = mpHands.Hands(max_num_hands=1)
  10. mpDraw = mp.solutions.drawing_utils
  11. handLmsStyle = mpDraw.DrawingSpec(color=(0,0,255),thickness=10)
  12. handConStyle = mpDraw.DrawingSpec(color=(0,255,255),thickness=5)
  13. pTime = 0
  14. cTime = 0
  15. #获取定位点,x,y的坐标
  16. pos2=pos_2=pos3=pos_3=pos4=pos_4=0
  17. pos5=pos8=pos9=pos12=pos16=pos20=0
  18. pos6=pos7=pos8=pos_6=pos_7=pos_8=0
  19. pos10=pos11=pos12=pos_10=pos_11=pos_12=0
  20. pos14=pos15=pos16=pos_14=pos_15=pos_16=0
  21. pos18=pos19=pos20=pos_18=pos_19=pos_20=0
  22. s1 = Servo(Pin(Pin.D3)) #将Pin传入Servo中初始化舵机引脚 大拇指
  23. s2 = Servo(Pin(Pin.D5)) #将Pin传入Servo中初始化舵机引脚 食指
  24. s3 = Servo(Pin(Pin.D7)) #将Pin传入Servo中初始化舵机引脚 中指
  25. s4 = Servo(Pin(Pin.D10)) #将Pin传入Servo中初始化舵机引脚 无名指
  26. s5 = Servo(Pin(Pin.D11)) #将Pin传入Servo中初始化舵机引脚 小拇指
  27. s1.angle(170) #控制舵机转到170度位置
  28. s2.angle(60) #控制舵机转到60度位置
  29. s3.angle(60) #控制舵机转到60度位置
  30. s4.angle(60) #控制舵机转到60度位置
  31. s5.angle(60) #控制舵机转到60度位置
  32. a=['@','0','0','0','0','0'] #检测是否识别到手<span id="kM0.533716621430318">@表示没检测到,$表示检测到手</span></font>
复制代码
3.主程序部分
  1. <font size="4" face="微软雅黑">while True:
  2.         ret, img = cap.read()
  3.         if ret:
  4.             imgRGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
  5.             result = hands.process(imgRGB)
  6.             imgHeight = img.shape[0]
  7.             imgWidth = img.shape[1]
  8.             if result.multi_hand_landmarks :
  9.                 a[0]='[font=微软雅黑][size=4]4.拇指部分代码[/size][/font]
  10. [code]<font size="4" face="微软雅黑">##########################大拇指################################                        
  11.                         if i == 2:
  12.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  13.                             pos2,pos_2=xPos,yPos
  14.                         if i == 3:
  15.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  16.                             pos3,pos_3=xPos,yPos
  17.                         if i == 4:
  18.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  19.                             pos4,pos_4=xPos,yPos
  20.                         radians_fingers = np.arctan2(pos_2- pos_3, pos2 - pos3) - np.arctan2(pos_4 - pos_3, pos4 - pos3)
  21.                         angle = np.abs(radians_fingers * 180.0 / np.pi)
  22.                         if angle > 180.0:
  23.                             angle = 360 - angle
  24.                         if angle<150:
  25.                             a[1]='0'
  26.                             s1.angle(80) #s1.angle(70)
  27.                         else:
  28.                             a[1]='1'
  29.                             s1.angle(170) #s1.angle(180)</font>
复制代码
5.食指部分,其他三个手指通用该模式
  1. <font size="4" face="微软雅黑">##############################食指##########################
  2.                         if i == 6:
  3.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  4.                             pos6,pos_6=xPos,yPos
  5.                         if i == 7:
  6.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  7.                             pos7,pos_7=xPos,yPos
  8.                         if i == 8:
  9.                             cv2.circle(img,(xPos,yPos),10,(255,255,255),cv2.FILLED)
  10.                             pos8,pos_8=xPos,yPos
  11.                         radians_fingers = np.arctan2(pos_6- pos_7, pos6 - pos7) - np.arctan2(pos_8 - pos_7, pos8 - pos7)
  12.                         angle2 = np.abs(radians_fingers * 180.0 / np.pi)
  13.                         if angle2 > 180.0:
  14.                             angle2 = 360 - angle2
  15.                         if angle2<150:
  16.                             a[2]='0'
  17.                             s2.angle(60)
  18.                         else:
  19.                             a[2]='1'
  20.                             s2.angle(150)</font>
复制代码
6.检测导出的五个手指弯曲的角度
  1. <font size="4" face="微软雅黑">##############################################################                        
  2.                         cv2.putText(img,f"hand1 : {int(angle)}",(10,20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))
  3.                         cv2.putText(img,f"hand2 : {int(angle2)}",(10,30),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))
  4.                         cv2.putText(img,f"hand3 : {int(angle3)}",(10,40),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))
  5.                         cv2.putText(img,f"hand4 : {int(angle4)}",(10,50),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))
  6.                         cv2.putText(img,f"hand5 : {int(angle5)}",(10,60),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))</font>
复制代码


7.结尾部分
  1. <font size="4" face="微软雅黑">############ftp/s
  2.         cTime = time.time()
  3.         fps = 1/(cTime-pTime)
  4.         pTime = cTime
  5.         cv2.putText(img,f"FPS : {int(fps)}",(130,150),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0))
  6.         cv2.imshow('img',img)
  7.         #time.sleep(0.3)
  8.         if cv2.waitKey(1) &0xFF == 27: #按q键退出视频
  9.                 break
  10. cap.release()
  11. cv2.destroyAllWindows()</font>
复制代码
五、测试视频

我的模型大拇指设计有问题,归位有时会失灵




计算机性能跟不上功能,对识别有影响



增加延时,效果稍有改进






六、完整代码下载
下载附件handtestv1.0.zip



附:参考网址
https://blog.csdn.net/kalakalabala/article/details/122530825
https://google.github.io/mediapipe/solutions/hands

rzegkly  版主

发表于 2022-10-18 07:45:57

赞一个
回复

使用道具 举报

ASH腻  管理员

发表于 2022-10-19 17:19:59

谢谢记录分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail