【OpenCV 实战】1.手势虚拟拖拽(双手骨骼点识别)

step:

1.opencv 获取视频流

2.在画面上画一个方块

3.通过mediapipe获取手指关键点坐标

4.判断手指是否在方块上

5.若在方块上,方块跟着手指移动

mediapipe网站介绍:Hands - mediapipe (chuoling.github.io)

已上传到GitHub : plumqm/OpenCV-project: 通过20个项目学习计算机视觉(Learn computer vision through 20 projects) (github.com)

python 复制代码
"""
author = qian
date = 2024-10-07

step:
1.opencv 获取视频流
2.在画面上画一个方块
3.通过mediapipe获取手指关键点坐标
4.判断手指是否在方块上
5.若在方块上,方块跟着手指移动

"""

import cv2
import numpy as np

import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands

hands = mp_hands.Hands(
    static_image_mode=True,
    max_num_hands=2,
    min_detection_confidence=0.5)

# 1.opencv 获取视频流
cap = cv2.VideoCapture(0)

#获取画面宽和高
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 方块相关参数
square_x = 100
square_y = 100
square_width = 100
square_color = (255,0,0)
L1 = 0
L2 = 0
on_square = False

while True:

    # 读取每一帧
    ret, frame = cap.read()

    # 处理图像
    frame = cv2.flip(frame, 1)  # 镜像

    # mediapipe处理
    frame.flags.writeable = False
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(frame)

    frame.flags.writeable = True    
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

    # 判断是否出现手
    if results.multi_hand_landmarks:
    
        # 解析遍历每一双手
        for hand_landmarks in results.multi_hand_landmarks:

            # 绘制21个关键点
            mp_drawing.draw_landmarks(
                frame,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing_styles.get_default_hand_landmarks_style(),
                mp_drawing_styles.get_default_hand_connections_style())

        # 保存21个x,y坐标
        x_list = [landmark.x for landmark in hand_landmarks.landmark]
        y_list = [landmark.y for landmark in hand_landmarks.landmark]

        # 获取食指指尖
        index_finger_X = int(x_list[8] * width)
        index_finger_Y = int(y_list[8] * height)

        # 获取中指指尖
        middle_finger_X = int(x_list[12] * width)
        middle_finger_Y = int(y_list[12] * height)

        # 计算食指中指指尖距离
        finger_len = np.sqrt((middle_finger_X - index_finger_X)**2 + (middle_finger_Y - index_finger_Y)**2)

        # cv2.circle(frame, (index_finger_X,index_finger_Y)
        # ,20 ,(255,0,255) ,-1)

        # 手指是否在方块上
        if square_x <= x_list[4] <= square_x + square_width and square_y <= y_list[4] <= square_y + square_width:
            square_x += (x_list[4] - square_x) / 10
            square_y += (y_list[4] - square_y) / 10

        # 如果距离小于30算激活
        if finger_len < 30:
            # 判断食指指尖在不在方块上
            if (square_x <= index_finger_X <= square_x + square_width and square_y <= index_finger_Y <= square_y + square_width):
                if on_square == False :
                    L1 = abs(index_finger_X - square_x)
                    L2 = abs(index_finger_Y - square_y)
                    on_square = True
                    square_color = (255,0,255)
            else :
                pass

            if on_square == True:
                square_x = index_finger_X - L1
                square_y = index_finger_Y - L2

        else :
            on_square = False
            square_color = (255,0,0)

    # 2. 在画面上画一个方块
    # cv2.rectangle(frame, (square_x, square_y), (square_x+square_width, square_y+square_width), (255, 0, 0), -1)

    # 画半透明方块
    overlay = frame.copy()
    cv2.rectangle(frame, (square_x, square_y), 
    (square_x+square_width, square_y+square_width), 
    square_color, -1)

    frame = cv2.addWeighted(overlay,0.5,frame,0.5,0)
    # 显示
    cv2.imshow('Virtual drag', frame)

    if cv2.waitKey(10) & 0xFF == 27:
        break 

cap.release()
cv2.destroyAllWindows()
相关推荐
染指111029 分钟前
26.RAG进阶(Advanced RAG)-假设性问题索引
人工智能·windows·agent·rag·advanced rag
闵孚龙32 分钟前
动态图机制:为什么 PyTorch 调试起来更舒服
人工智能·pytorch·python
甲维斯1 小时前
还要啥Codex!DeepSeek接入Zcode远程连接!
人工智能
百胜软件@百胜软件1 小时前
百胜软件亮相“AI消费新生活”主题日活动,AI智能运营平台入选市级案例征集
人工智能·生活·零售数字化·数智中台·珠宝行业
专注搞钱2 小时前
GPT-4o写设备Recipe:从3小时到10分钟
数据库·人工智能·gpt·半导体
闻道参看3 小时前
贝芯宠AI灵兽 ELFVET 大模型聚焦临床应用,强化宠物诊疗综合能力
人工智能·宠物
MartinYeung53 小时前
[论文学习]重新思考大型语言模型忘却目标:梯度视角与超越
人工智能·学习·语言模型
财经资讯数据_灵砚智能3 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月14日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
m0_380167143 小时前
加密货币价格 API、市场数据 API 与 分析 API 有什么区别?
人工智能·ai·区块链
zyplayer-doc3 小时前
企业知识库安全与权限管理完全指南:从加密到审计的六层防护
人工智能·安全·pdf·编辑器·创业创新