mediapipe
mediapipe copied to clipboard
Calculating thumb and finger angles from coordinates
What is the best way to calculate the angles of the thumb and finger from the XYZ coordinates?
Its my code in python:
a = np.array(
[handLms.landmark[joint[0]].x , handLms.landmark[joint[0]].y ]) # First coord
b = np.array([handLms.landmark[joint[1]].x ,
handLms.landmark[joint[1]].y ]) # Second coord
c = np.array([handLms.landmark[joint[2]].x ,
handLms.landmark[joint[2]].y ]) # Third coord
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
angle = int(np.abs(radians * 180.0 / np.pi))
if angle > 180:
angle = 360 - angle
which joint = [joint1,joint2,joint3] which are 3 joints numbers from mediapipe hand landmarks.
Thank you! How would you recommend calculating the angle of the thumb?
Its my code in python:
a = np.array( [handLms.landmark[joint[0]].x , handLms.landmark[joint[0]].y ]) # First coord b = np.array([handLms.landmark[joint[1]].x , handLms.landmark[joint[1]].y ]) # Second coord c = np.array([handLms.landmark[joint[2]].x , handLms.landmark[joint[2]].y ]) # Third coord radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0]) angle = int(np.abs(radians * 180.0 / np.pi)) if angle > 180: angle = 360 - anglewhich joint = [joint1,joint2,joint3] which are 3 joints numbers from mediapipe hand landmarks.
can you share full code with me ?
import mediapipe as mp import cv2 import numpy as np import uuid import os mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands
cap = cv2.VideoCapture(0) #Set Frame Size cap.set(3, 1280) cap.set(4, 650) joint_list = [[8,7,6], [12,11,10], [16,15,14], [20,19,18],[2,3,4]]
def fingerAngles(image, results, joint_list):
# Loop through hands
for hand in results.multi_hand_landmarks:
#Loop through joint sets
for joint in joint_list:
a = np.array([hand.landmark[joint[0]].x, hand.landmark[joint[0]].y]) # First coord
b = np.array([hand.landmark[joint[1]].x, hand.landmark[joint[1]].y]) # Second coord
c = np.array([hand.landmark[joint[2]].x, hand.landmark[joint[2]].y]) # Third coord
radians = np.arctan2(c[1] - b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
angle = np.abs(radians*180.0/np.pi)
if angle > 180.0:
angle = 360-angle
cv2.putText(image, str(round(angle, 2)), tuple(np.multiply(b, [1280, 650]).astype(int)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
return image
#Set the detection confidence and tracking confidence for better result with mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5) as hands: while cap.isOpened(): ret, frame = cap.read()
# BGR 2 RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Flip on horizontal
image = cv2.flip(image, 1)
# Set flag
image.flags.writeable = False
# Detections
results = hands.process(image)
# Set flag to true
image.flags.writeable = True
# RGB 2 BGR
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Rendering results
if results.multi_hand_landmarks:
for num, hand in enumerate(results.multi_hand_landmarks):
mp_drawing.draw_landmarks(image, hand, mp_hands.HAND_CONNECTIONS,
mp_drawing.DrawingSpec(color=(150, 22, 150), thickness=2, circle_radius=4),
mp_drawing.DrawingSpec(color=(150, 200, 250), thickness=2, circle_radius=2),
)
# Draw angles to image from joint list
fingerAngles(image, results, joint_list)
#Showing the camera
cv2.imshow('Finger Angles', image)
#exxit the program
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release() cv2.destroyAllWindows()
Here's mine
# https://github.com/google/mediapipe/issues/2999
class HandAngles:
def __init__(self, fingers):
self.thumb = fingers[0]
self.index = fingers[1]
self.middle = fingers[2]
self.ring = fingers[3]
self.pinky = fingers[4]
# https://google.github.io/mediapipe/solutions/hands#hand-landmark-model
joint_list = [
[4, 3, 2, 1],
[8, 7, 6, 5, 0],
[12, 11, 10, 9, 0],
[16, 15, 14, 13, 0],
[20, 19, 18, 17, 0],
]
def fingerAngles(hand_landmarks):
fingers = []
# Loop through joint sets
for joint in HandAngles.joint_list:
angle = 0
for i in range(0, len(joint) - 2):
a = hand_landmarks.landmark[joint[i]]
b = hand_landmarks.landmark[joint[i + 1]]
c = hand_landmarks.landmark[joint[i + 2]]
angle += HandAngles.angle(a, b, c)
fingers.append(angle)
return HandAngles(fingers)
def angle(a, b, c):
firstVector = (b.x - a.x, b.y - a.y, b.z - a.z)
secondVector = (c.x - b.x, c.y - b.y, c.z - b.z)
return angle_between(firstVector, secondVector)
# https://stackoverflow.com/a/13849249/3492994
def unit_vector(vector):
return vector / np.linalg.norm(vector)
def angle_between(v1, v2):
v1_u = unit_vector(v1)
v2_u = unit_vector(v2)
return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))
Hello @EigenSpiral, We are upgrading the MediaPipe Legacy Solutions to new MediaPipe solutions However, the libraries, documentation, and source code for all the MediapPipe Legacy Solutions will continue to be available in our GitHub repository and through library distribution services, such as Maven and NPM.
You can continue to use those legacy solutions in your applications if you choose. Though, we would request you to check new MediaPipe solutions which can help you more easily build and customize ML solutions for your applications. These new solutions will provide a superset of capabilities available in the legacy solutions. Thank you
This issue has been marked stale because it has no recent activity since 7 days. It will be closed if no further activity occurs. Thank you.
This issue was closed due to lack of activity after being marked stale for past 7 days.