这个也就图一乐,只是对 mediaPipe 的熟悉而已,有很大漏洞,并不建议直接使用。
mediaPipe 检测手部动作的方法
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_drawing = mp.solutions.drawing_utils
cap = cv.VideoCapture(0) # 打开摄像头
while True:
ret, frame = cap.read() # 读取视频帧
if not ret:
break
image = cv.cvtColor(frame, cv.COLOR_BGR2RGB) # 转换颜色空间
results = hands.process(image) # 手势识别
# 处理识别结果
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS) # 用于指定地标如何在图中连接。
for point in hand_landmarks.landmark:
x = int(point.x * frame.shape[1])
y = int(point.y * frame.shape[0])
cv.circle(frame, (x, y), 5, (0, 255, 0), -1) # 画出关键点
cv.imshow('Gesture Recognition', frame) # 显示结果
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
hands.process 的返回值 results 里的一些属性
multi_hand_landmarks 的格式如下
[手 1 的所有信息点坐标,手 2 的所有信息点坐标,。。。]其中每个信息点分成 3 个坐标,x:与左侧的距离,y:与上侧的距离,z:与掌根的距离
multi_hand_world_landmarks 的格式如下
这个参数跟 multi_hand_landmarks 的形式一致,但是坐标的组织方式不同,根据官方说明,检测到跟踪的手的集合,其中每只手都表示为世界坐标中 21 个手地标的列表。每个地标由 x、y 和 z 组成,以米为单位的真实世界 3D 坐标,原点位于手部的近似几何中心。
print(results.multi_hand_world_landmarks)
multi_handedness 的格式如下
[手 1 的对象,手 2 的对象,。。。]其中手的对象的格式为{index,score(惯用手的概率),label(left or right)}
21 个手点的位置
把手点的 index 打印在图片就可以方便后面进行手势比较的时候进行查看
if results.multi_hand_landmarks:
i = 0
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS) # 用于指定地标如何在图中连接。
for point in hand_landmarks.landmark:
x = int(point.x * frame.shape[1])
y = int(point.y * frame.shape[0])
cv.circle(frame, (x, y), 5, (0, 255, 0), -1) # 画出关键点
cv.putText(frame, str(i), (x, y - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
i = i+1

结印判断
我这里是靠哪些手指弯曲来计算的,但这方法其实有很大的问题,后面我会详细说明
原理
靠手指弯曲的的话,原理其实就是两个骨头的夹角去和一个阈值进行比较,我这里选择的是从食指到小指的一和二小节,这样选择的原因也很简单,一般的结印并不需要单独动第三个指节,而且我个人认为大拇指的作用不大,弯不弯都一样。
综上,我们主要要设计以下两个方向的函数:计算角度、判断是什么结印
计算角度
计算角度首先要两个向量,拿上面我


4501

被折叠的 条评论
为什么被折叠?



