33,121
社区成员
以下附代码:
#!/usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String
import cv2
import mediapipe as mp
from geometry_msgs.msg import Twist
class HandDetector():
def __init__(self):
self.hand_detector = mp.solutions.hands.Hands()
self.drawer = mp.solutions.drawing_utils
def process(self, img, draw=True):
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
self.hands_data = self.hand_detector.process(img_rgb)
if draw:
if self.hands_data.multi_hand_landmarks:
for handlms in self.hands_data.multi_hand_landmarks:
self.drawer.draw_landmarks(img, handlms, mp.solutions.hands.HAND_CONNECTIONS)
def find_position(self, img):
h, w, c = img.shape
self.position = {'Left': {}, 'Right': {}}
if self.hands_data.multi_hand_landmarks:
i = 0
for point in self.hands_data.multi_handedness:
score = point.classification[0].score
if score >= 0.8:
label = point.classification[0].label
hand_lms = self.hands_data.multi_hand_landmarks[i].landmark
for id, lm in enumerate(hand_lms):
x, y = int(lm.x * w), int(lm.y * h)
self.position[label][id] = (x, y)
i = i + 1
return self.position
def fingers_count(self, hand='Left'):
tips = [4, 8, 12, 16, 20]
tip_data = {4:0, 8:0, 12:0, 16:0, 20:0}
for tip in tips:
ltp1 = self.position[hand].get(tip, None)
ltp2 = self.position[hand].get(tip-2, None)
if ltp1 and ltp2:
if tip == 4:
if ltp1[0] > ltp2[0]:
if hand == 'Left':
tip_data[tip] = 1
else:
tip_data[tip] = 0
else:
if hand == 'Left':
tip_data[tip] = 0
else:
tip_data[tip] = 1
else:
if ltp1[1] > ltp2[1]:
tip_data[tip] = 0
else:
tip_data[tip] = 1
return list(tip_data.values()).count(1)
def talker():
cmd_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
rospy.init_node('gesture_recognition', anonymous=True)
rate = rospy.Rate(10) # 10hz
camera = cv2.VideoCapture(0)
while(camera.isOpened):
while not rospy.is_shutdown():
hand_detector = HandDetector()
success, img = camera.read()
if success:
img = cv2.flip(img, 1)
h, w, c = img.shape
hand_detector.process(img, draw=False)
position = hand_detector.find_position(img)
left_fingers = hand_detector.fingers_count('Left')
# print('左手: ', left_fingers)
cv2.putText(img, str(left_fingers), (100, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (0, 255, 0))
right_fingers = hand_detector.fingers_count('Right')
# print('右手:', right_fingers)
cv2.putText(img, str(right_fingers), (w-200, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (255, 0, 0))
cv2.imshow('Video', img)
send_data = Twist()
if left_fingers == '1':
send_data.linear.x =1.0
send_data.angular.z = 1.0
cmd_vel_pub.publish(send_data)
k = cv2.waitKey(1)
if k == ord('q'):
break
rate.sleep()
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
# try:
talker()
# except rospy.ROSInterruptException:
# pass
感谢各路大神回答!!!
缺少依赖项导入:使用了rospy
、std_msgs.msg
和geometry_msgs.msg
等依赖项,但是在代码开头缺少相应的导入语句。请确保在代码开头添加以下导入语句:
import rospy
from std_msgs.msg import String
from geometry_msgs.msg import Twist
摄像头打开问题:您使用了cv2.VideoCapture(0)
打开摄像头,但在while(camera.isOpened)
循环中,您没有调用camera.isOpened()
方法来检查摄像头是否打开。请修改为while camera.isOpened()
。
主循环逻辑错误:在while not rospy.is_shutdown()
循环中,应将以下代码段移动到正确的位置,以确保在循环内部进行处理:
hand_detector = HandDetector()
success, img = camera.read()
if success:
img = cv2.flip(img, 1)
h, w, c = img.shape
hand_detector.process(img, draw=False)
position = hand_detector.find_position(img)
left_fingers = hand_detector.fingers_count('Left')
cv2.putText(img, str(left_fingers), (100, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (0, 255, 0))
right_fingers = hand_detector.fingers_count('Right')
cv2.putText(img, str(right_fingers), (w-200, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (255, 0, 0))
cv2.imshow('Video', img)
send_data = Twist()
if left_fingers == 1:
send_data.linear.x = 1.0
send_data.angular.z = 1.0
cmd_vel_pub.publish(send_data)
发布消息问题:在talker()
函数的末尾,您需要将以下代码段放在循环内部,以确保在每次循环迭代中都有消息发布:
cmd_vel_pub.publish(send_data)