I would like to show the coordinates of the left hand wrist if I show my left hand or the coordinates of the right hand wrist if I show my right hand. Ive implemented it, but it will only show if my webcam can see both hands. What is wrong in my code? I'm using mediapipe and opencv as Framework.
with mp_holistic.Holistic(min_detection_confidence=0.5, min_tracking_confidence=0.5) as holistic:
while cap.isOpened():
ret, frame = cap.read()
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
results = holistic.process(image)
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS )
mp_drawing.draw_landmarks(image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
try:
wrist_left_x = results.left_hand_landmarks.landmark[0].x
wrist_left_y = results.left_hand_landmarks.landmark[0].y
wrist_right_x = results.right_hand_landmarks.landmark[0].x
wrist_right_y = results.right_hand_landmarks.landmark[0].y
if results.left_hand_landmarks:
text = wrist_left_x
text2 = wrist_left_y
if results.right_hand_landmarks:
text = wrist_right_x
text2 = wrist_right_y
cv2.putText(image, str(text), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1,
cv2.LINE_AA)
cv2.putText(image, str(text2), (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1,
cv2.LINE_AA)
except:
pass
You should generally try to avoid using a bare except
clause whenever possible, as you will invisibly catch any error that occurs in the try
block. Instead, you should catch only the exceptions that you expect may arise in normal execution.
I suspect, based on looking at the MediaPipe source, that what is happening here is that when there is only one hand detected, the value of results.{left|right}_hand_landmarks
for the hand that is not detected is None
. Since None
is a falsey value, your if results.left_hand_landmarks:
and if results.right_hand_landmarks:
guards are good practice*, but the problem is that you are attempting to access attributes of those objects outside of the guards, namely here:
try:
wrist_left_x = results.left_hand_landmarks.landmark[0].x
wrist_left_y = results.left_hand_landmarks.landmark[0].y
wrist_right_x = results.right_hand_landmarks.landmark[0].x
wrist_right_y = results.right_hand_landmarks.landmark[0].y
In Python, if these objects are None
, this will raise an error:
AttributeError: 'NoneType' object has no attribute 'left_hand_landmarks'
Try rewriting the code to this:
try:
if results.left_hand_landmarks:
text = results.left_hand_landmarks.landmark[0].x
text2 = results.left_hand_landmarks.landmark[0].y
if results.right_hand_landmarks:
text = results.right_hand_landmarks.landmark[0].x
text2 = results.right_hand_landmarks.landmark[0].y
*Best practice would be to explicitly use a None
check: if x is not None:
. Since each type in Python can have a different way of determining its truth value, relying on just if x:
to ascertain the existence of an object can be a pitfall.