Skip to content

Commit a688166

Browse files
committed
feat: working raising hand gesture detection
1 parent f11ccd4 commit a688166

File tree

6 files changed

+124
-8
lines changed

6 files changed

+124
-8
lines changed

common/vision/lasr_vision_bodypix/src/lasr_vision_bodypix/bodypix.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ def detect(
5858
Run BodyPix inference on given detection request
5959
"""
6060

61+
debug_publisher = rospy.Publisher("/bodypix/debug", SensorImage, queue_size=1)
62+
6163
# decode the image
6264
rospy.loginfo("Decoding")
6365
img = cv2_img.msg_to_cv2_img(request.image_raw)
@@ -69,6 +71,7 @@ def detect(
6971
# run inference
7072
rospy.loginfo("Running inference")
7173
result = model.predict_single(img)
74+
7275
mask = result.get_mask(threshold=request.confidence)
7376
rospy.loginfo("Inference complete")
7477

@@ -110,6 +113,7 @@ def detect(
110113
keypoints_msg = []
111114

112115
for i, keypoint in pose.keypoints.items():
116+
113117
if camel_to_snake(keypoint.part) in request.masks[0].parts:
114118
keypoint_msg = BodyPixKeypoint()
115119
keypoint_msg.xy = [int(keypoint.position.x), int(keypoint.position.y)]
@@ -118,7 +122,6 @@ def detect(
118122
keypoints_msg.append(keypoint_msg)
119123

120124
pose_msg.keypoints = keypoints_msg
121-
pose_msg.score = pose.score
122125
output_poses.append(pose_msg)
123126

124127
response = BodyPixDetectionResponse()
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
11
# keypoints
2-
BodyPixKeypoint[] keypoints
3-
4-
# score
5-
float32 score
6-
# x and y coordinates
7-
float32[] coord
2+
BodyPixKeypoint[] keypoints
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<launch>
2+
<description>Perform gesture detection using the camera</description>
3+
<usage doc="Run the demo"></usage>
4+
5+
6+
<!-- show debug topic -->
7+
<node name="image_view" pkg="rqt_image_view" type="rqt_image_view" respawn="false" output="screen" args="/recognise/debug" />
8+
9+
10+
<!-- launch video stream -->
11+
<include file="$(find video_stream_opencv)/launch/camera.launch">
12+
<arg name="visualize" value="true" />
13+
</include>
14+
</launch>

skills/src/lasr_skills/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
from .handover_object import HandoverObject
1818
from .ask_and_listen import AskAndListen
1919
from .clip_vqa import QueryImage
20+
from .detect_gesture import DetectGesture
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env python3
2+
import smach
3+
import rospy
4+
from lasr_skills.vision import GetImage
5+
from lasr_vision_msgs.srv import BodyPixDetection, BodyPixDetectionRequest
6+
from lasr_vision_msgs.msg import BodyPixMaskRequest
7+
8+
9+
class DetectGesture(smach.State):
10+
"""
11+
State for detecting gestures.
12+
"""
13+
14+
def __init__(self, gesture_to_detect: str = "raising_left_hand"):
15+
self.gesture_to_detect = gesture_to_detect
16+
smach.State.__init__(
17+
self,
18+
outcomes=["succeeded", "failed"],
19+
input_keys=["img_msg"],
20+
output_keys=["gesture_detected"],
21+
)
22+
23+
self.body_pix_client = rospy.ServiceProxy("/bodypix/detect", BodyPixDetection)
24+
25+
def execute(self, userdata):
26+
27+
body_pix_masks = BodyPixMaskRequest()
28+
body_pix_masks.parts = [
29+
"left_shoulder",
30+
"right_shoulder",
31+
"left_wrist",
32+
"right_wrist",
33+
]
34+
masks = [body_pix_masks]
35+
36+
req = BodyPixDetectionRequest()
37+
req.image_raw = userdata.img_msg
38+
req.masks = masks
39+
req.dataset = "resnet50"
40+
req.confidence = 0.7
41+
42+
try:
43+
res = self.body_pix_client(req)
44+
except Exception as e:
45+
print(e)
46+
return "failed"
47+
48+
part_info = {}
49+
poses = res.poses
50+
for pose in poses:
51+
for keypoint in pose.keypoints:
52+
part_info[keypoint.part] = {
53+
"x": keypoint.xy[0],
54+
"y": keypoint.xy[1],
55+
"score": keypoint.score,
56+
}
57+
58+
if self.gesture_to_detect == "raising_left_hand":
59+
if part_info["leftWrist"]["y"] < part_info["leftShoulder"]["y"]:
60+
userdata.gesture_detected = True
61+
else:
62+
userdata.gesture_detected = False
63+
elif self.gesture_to_detect == "raising_right_hand":
64+
if part_info["rightWrist"]["y"] < part_info["rightShoulder"]["y"]:
65+
userdata.gesture_detected = True
66+
else:
67+
userdata.gesture_detected = False
68+
else:
69+
raise ValueError("Invalid gesture to detect")
70+
71+
return "succeeded"
72+
73+
74+
class GestureDetectionSM(smach.StateMachine):
75+
"""
76+
State machine for detecting gestures.
77+
"""
78+
79+
def __init__(self, gesture_to_detect: str = "raising_left_hand"):
80+
smach.StateMachine.__init__(self, outcomes=["succeeded", "failed"])
81+
self.gesture_to_detect = gesture_to_detect
82+
with self:
83+
smach.StateMachine.add(
84+
"GET_IMAGE",
85+
GetImage(),
86+
transitions={"succeeded": "BODY_PIX_DETECTION", "failed": "failed"},
87+
)
88+
89+
smach.StateMachine.add(
90+
"BODY_PIX_DETECTION",
91+
DetectGesture(gesture_to_detect=self.gesture_to_detect),
92+
transitions={"succeeded": "succeeded", "failed": "failed"},
93+
)
94+
95+
96+
if __name__ == "__main__":
97+
rospy.init_node("gesture_detection_sm")
98+
while not rospy.is_shutdown():
99+
sm = GestureDetectionSM()
100+
sm.execute()
101+
print("Raising Left Hand Detected:", sm.userdata.gesture_detected)
102+
103+
rospy.spin()

skills/src/lasr_skills/vision/get_image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def __init__(self, topic: str = None):
1818
self.topic = (
1919
"/xtion/rgb/image_raw"
2020
if "tiago" in os.environ["ROS_MASTER_URI"]
21-
else "/camera/image_raw"
21+
else "/usb_cam/image_raw"
2222
)
2323
else:
2424
self.topic = topic

0 commit comments

Comments
 (0)