学习 MediaPipe 手部检测和手势识别
前文链接:学习 MediaPipe 手部检测和手势识别(1)
所有图片均来自互联网。
3 手势识别
3.0 识别内容讨论
个人认为,在手势识别中,应该对:手掌朝向、手指弯曲、指间距离,这 3 个方面进行识别。
3.1 手掌朝向
通过计算向量 0 —> 5 和 0 —> 17 的叉乘,确定手掌朝向。规定代表手掌朝向的向量由手背指向掌心。所以,识别的左手(label == Left)为 v0_5 × v0_17,识别的右手(label == Right)为 v0_17 × v0_5。将叉乘结果归一化,并将向量在xoy平面的映射向量画出来。用绿点表示朝外,红色表示朝内。
计算手掌朝向向量部分的代码:
@staticmethod
def _calculate_cross_product(vector_a, vector_b, normalized:bool=True):
if vector_a.shape == (3,) and vector_b.shape == (3,):
cross_product = np.cross(vector_a, vector_b)
if normalized:
norm = np.linalg.norm(cross_product)
if norm != 0:
cross_product = cross_product / norm
return cross_product
return None
def _get_palm_facing(self):
for result in self.results_list:
# 绘制手掌方向
if "palm_facing" not in result.keys():
label = result["label"]
coord_w = result["coord_w"]
p0 = coord_w[:, 0]
v0_5 = coord_w[:, 5] - p0
v0_17 = coord_w[:, 17] - p0
if label == "Left":
result["plam_facing"] = self._calculate_cross_product(
v0_5, v0_17)
else:
result["plam_facing"] = self._calculate_cross_product(
v0_17, v0_5)
绘制手掌朝向向量部分的代码:
# 手掌朝向
self._get_palm_facing()
vector_palm = result["plam_facing"]
p0 = result["coord"][:, 0]
pv = (p0 + vector_palm * 100)
cv2.line(image, tuple(map(int, p0[:2])), tuple(map(int, pv[:2])),
(0, 0, 255), 2)
if vector_palm[2] < 0:
cv2.circle(image, tuple(map(int, p0[:2])), 3, (0, 255, 0), -1)
========== 2024/08/11 学习中 ==========