跟之前的那个项目类似, 使用mediapipe, 拿到手指的位置, 来控制舵机, 从而控制一个机械臂.
直接上代码:
"""
演示一个简单的虚拟拖拽
步骤:
1、opencv 读取视频流"""# 导入opencv
import cv2
import numpy as np
import math
import serial# 导入mediapipe:https://google.github.io/mediapipe/solutions/hands
import mediapipe as mpserialFd = serial.Serial('com7', 115200, timeout=0.5)
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.handshands = mp_hands.Hands(model_complexity=0,min_detection_confidence=0.5,min_tracking_confidence=0.5)# 读取视频流
cap = cv2.VideoCapture(0)# 找不到摄像头就直接退出# 获取画面宽度、高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))gX = 0;
gY = 0;while True:ret, frame = cap.read()# 镜像frame = cv2.flip(frame, 1)frame.flags.writeable = Falseframe = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 识别results = hands.process(frame)frame.flags.writeable = Trueframe = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)# 如果有结果if results.multi_hand_landmarks:# 遍历双手for hand_landmarks in results.multi_hand_landmarks:mp_drawing.draw_landmarks(frame,hand_landmarks,mp_hands.HAND_CONNECTIONS,mp_drawing_styles.get_default_hand_landmarks_style(),mp_drawing_styles.get_default_hand_connections_style())# 使用这两句看一下里面到底是什么?# print(type(hand_landmarks))# print(hand_landmarks)# exit()# 21 个关键点的x,y坐标列表x_list = []y_list = []for landmark in hand_landmarks.landmark:x_list.append(landmark.x)y_list.append(landmark.y)# 输出一下长度# print(len(x_list))# 获取食指指尖坐标,坐标位置查看:https://google.github.io/mediapipe/solutions/handsindex_finger_x = int(x_list[8] * width)index_finger_y = int(y_list[8] * height)# print(index_finger_x)xPos = int(index_finger_x / 680 * 180)data_to_send = f"X={xPos}\r\n"print(data_to_send)# if((index_finger_x > gX ) and (index_finger_x - gX > 10)):# print("right")serialFd.write(data_to_send.encode('ascii'))# serialFd.write((bytearray('s','ascii')))# if((index_finger_x < gX ) and (gX - index_finger_x > 10)):# print("left")# serialFd.write((bytearray('w','ascii')))gX = index_finger_x;# 获取中指坐标# middle_finger_x = int(x_list[12] * width)# middle_finger_y = int(y_list[12] * height)# 计算两指距离# finger_distance =math.sqrt( (middle_finger_x - index_finger_x)**2 + (middle_finger_y-index_finger_y)**2)# finger_distance = math.hypot((middle_finger_x - index_finger_x),(middle_finger_y - index_finger_y))# 看一下距离# print(finger_distance)# 把食指指尖画出来cv2.circle(frame, (index_finger_x, index_finger_y), 20, (0, 0, 255), -1)# 显示画面cv2.imshow('demo', frame)if cv2.waitKey(10) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()
即拿到食指尖的位置, 转换成180度的舵机角度, 来控制stm32的控制的舵机.
stm32代码在下面:
https://github.com/MontaukLaw/servor_controller
手指控制舵机