【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()
相关推荐
火山引擎开发者社区5 小时前
火山 PostgreSQL Serverless × 飞书妙搭:把 AI 装进数据库,一句话唤醒数据智能
人工智能
必须会一定会7 小时前
Agent Plugins 1.0实战:plugin.json、skills、mcp.json目录结构与迁移
开发语言·人工智能·ai编程
CTA量化套保8 小时前
近期零基础量化学习:先分阶段,再用 AI 检查缺口
人工智能·python
Justin3go8 小时前
AI 引荐流量报告:哪些独立产品正在从 ChatGPT 获客?
人工智能·seo
风流 少年8 小时前
Spring AI 2.0:SSE
java·人工智能·spring
深小乐9 小时前
AI 项目上线:折腾 Cloudflare,真香也藏不少坑
人工智能
ACP广源盛139246256739 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 MoE 私有化部署下 GSV2221 视频转换芯片机遇分析
大数据·数据库·人工智能
冬奇Lab10 小时前
开源项目第190期:claude-video — 给 Claude 装上「眼睛」看视频,一条命令分析 YouTube/Loom/本地视频
人工智能·开源·claude
七牛开发者10 小时前
为什么 Go 很适合 AI 辅助开发?
数据库·人工智能·python·elasticsearch·log4j