程序基于python版opencv的手部跟踪识别 简介:基于opencv实现的手部跟踪小项目。 通过手部识别出21个关键点,并对21个关键点进行定位和着色,有了具体位置信息就可以DIY很多自己想要的有趣功能,比如:手势识别、石头剪刀布猜拳、手语翻译等。

撸代码玩手势识别这事儿真带劲!今天咱们用Python+OpenCV搞个实时手部跟踪,把21个骨节点都揪出来画成赛博朋克风,先看效果:摄像头里伸个手,唰唰唰冒出21个荧光点还带骨骼连线,科幻片那味儿立马出来了!

上硬货!环境配置先装这两个库:

pip install opencv-python mediapipe

MediaPipe是谷歌家的开源方案,手部关键点检测这块比传统OpenCV准太多了,关键还免费!

初始化手部检测模型:

import cv2
import mediapipe as mp

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    max_num_hands=1,  # 只检测单手(调大能检测多只手)
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5
)
mp_draw = mp.solutions.drawing_utils  # 自带绘图工具

这里maxnumhands控制识别手数,实测设成2时双人猜拳也能hold住。confidence阈值别调太低,否则画面抖动到你怀疑人生。

核心处理循环才是重头戏:

cap = cv2.VideoCapture(0)
while cap.isOpened():
    ret, frame = cap.read()
    if not ret: continue
    
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(rgb_frame)
    
    if results.multi_hand_landmarks:
        for hand_lms in results.multi_hand_landmarks:
            # 绘制骨骼连线(mediapipe自带样式)
            mp_draw.draw_landmarks(
                frame, hand_lms, 
                mp_hands.HAND_CONNECTIONS,
                landmark_drawing_spec=mp_draw.DrawingSpec(color=(180,230,90), thickness=4),
                connection_drawing_spec=mp_draw.DrawingSpec(color=(90,90,220), thickness=3)
            )
            
            # 单独标注每个关节点
            for idx, lm in enumerate(hand_lms.landmark):
                h, w, _ = frame.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                cv2.circle(frame, (cx,cy), 5, (255,0,255), -1)
    
    cv2.imshow('Hand Tracking', frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

注意颜色空间转换!OpenCV默认BGR格式,MediaPipe需要RGB输入,这个坑我当年卡了俩小时...

程序基于python版opencv的手部跟踪识别 简介:基于opencv实现的手部跟踪小项目。 通过手部识别出21个关键点,并对21个关键点进行定位和着色,有了具体位置信息就可以DIY很多自己想要的有趣功能,比如:手势识别、石头剪刀布猜拳、手语翻译等。

重点说下landmark数据结构:每个lm包含x,y,z三维坐标(0~1相对坐标),乘以画面尺寸转绝对坐标。比如食指指尖是索引8:

index_tip = hand_lms.landmark[8]
print(f"食指坐标:({index_tip.x:.2f}, {index_tip.y:.2f})")

知道坐标后就能搞事情了——计算两指间距做缩放手势,判断指尖位置实现虚拟按钮,甚至根据关节角度识别比心手势!

举个判断剪刀手的小例子:

# 获取食指和中指尖坐标
index_tip = hand_lms.landmark[8]
middle_tip = hand_lms.landmark[12]

# 计算Y轴方向距离
if index_tip.y < middle_tip.y - 0.1:  # 经验阈值需校准
    cv2.putText(frame, "V手势!", (50,100), 
                cv2.FONT_HERSHEY_SIMPLEX, 2, (0,200,200), 3)

实际开发建议用归一化坐标计算向量夹角,比直接坐标差值更鲁棒。

最后记得释放资源:

cap.release()
cv2.destroyAllWindows()

跑起来后你会发现MediaPipe在CPU上也能流畅运行,这对没有独显的笔记本太友好了!想更炫酷可以给关节点加粒子特效,或者用骨骼坐标驱动虚拟手办——反正有了这21个点,剩下的就看你脑洞了。

遇到检测抖动的话,可以加个坐标移动平均滤波,或者用Kalman滤波预测轨迹,这些进阶操作咱们下次再唠!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐