我写了一个手势识别控制小海龟移动的节点,但是发现节点无法运行,摄像头刚打开就关了。

m0_72681256 2023-11-16 13:00:17

 以下附代码:

#!/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

感谢各路大神回答!!!

...全文
420 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
牛马程序员24 2023-11-16
  • 打赏
  • 举报
回复 1

缺少依赖项导入:使用了rospystd_msgs.msggeometry_msgs.msg等依赖项,但是在代码开头缺少相应的导入语句。请确保在代码开头添加以下导入语句:

import rospy
from std_msgs.msg import String
from geometry_msgs.msg import Twist
  1. 摄像头打开问题:您使用了cv2.VideoCapture(0)打开摄像头,但在while(camera.isOpened)循环中,您没有调用camera.isOpened()方法来检查摄像头是否打开。请修改为while camera.isOpened()

  2. 主循环逻辑错误:在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)
    
  3. 发布消息问题:在talker()函数的末尾,您需要将以下代码段放在循环内部,以确保在每次循环迭代中都有消息发布:

    cmd_vel_pub.publish(send_data)
    
m0_72681256 2023-11-19
  • 举报
回复
@牛马程序员24 谢谢

33,121

社区成员

发帖
与我相关
我的任务
社区描述
旨在分享机器人领域相关技术,帮助大家提升机器人领域相关能力,为我国机器人研发与制造领域添砖加瓦。 欢迎大家在这里分享技术博客,提问机器人相关问题,一起学习,共同进步。如问题帖长时间无回复,可加群交流。
机器人人工智能科技 个人社区 浙江省·杭州市
社区管理员
  • 万俟淋曦
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

旨在分享机器人领域的相关技术,帮助大家提升机器人领域相关的技术能力,为我国机器人研发与制造领域添砖加瓦。

包括但不限于以下相关技术方向:Linux、ROS1、ROS2、OpenCV、Deep Learning、Machine Learning、Eigen、Qt等等。

大家可以在这里分享技术博客,提问机器人相关问题。

【社区积分规则】

  • 在社区「发布内容」得 15 积分
  • 内容被管理员「加精」得 20 积分
  • 点赞他人内容得 2 积分
  • 评论内容得 5 积分

试试用AI创作助手写篇文章吧