【机器视觉】从零基础开始的Python+OpenCV+MediaPipe实现手势识别教程(一)手势识别
Tuzli6
2021年05月03日 18:17
收录于文集
共1篇

前言

第一次发表文章,如有错误,恳请读者指正。 本文将抛弃繁杂的理论知识,直接上手项目。 文章大部分问题可以在以下几个链接中解决: https://www.liaoxuefeng.com/wiki/1016959663602400 (廖雪峰Python教程)

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html

(opencv简单入门) https://google.github.io/mediapipe/solutions/hands.html (mediapipe参考)

一、OpenCV及MediaPipe

顾名思义,“Open”表示开放;“CV”即“Computer Vision”,是一款开源的跨平台计算机视觉和机器学习软件库。MediaPipe是一款多媒体机器学习模型应用框架。 两者主要的优点是不需要我们下载预训练模型,只是安装上其包即可。

二、实操步骤

1.下载

1.Pycharm的下载安装

(需要提前安装Python)下载地址:http://www.jetbrains.com/pycharm/download/#section=windows

选择社区版即可。

(如未安装,先安装此软件)Python官网下载:https://www.python.org/downloads/ 按照软件按照提示下载即可。

2.Opencv和MediaPipe的下载安装

打开安装好的pycharm 如图依次点击

此处搜索chinese安装插件可将软件部分替换成中文。 重启IDE后即可生效。

新建项目。

此处我们将我们的第一个项目命名为hand 创建好项目后,安装Opencv以及MediaPipe

左上角进入设置。

如图依次点击。

点击安装包,分别安装好Opencv以及mediapipe 到此,安装完毕。

2.手势追踪的最小代码实现

新建Python文件

命名为HandTrakingMin,回车确认。 文件创建好了,我们来逐段编写代码

代码块
Python
自动换行
复制代码
import cv2

import mediapipe as mp

import time
复制成功

import

python中的import语句是用来调用模块的,在模块定义好后,我们可以使用import语句来引入模块。

import as

用于引入一个模块的同时为该模块取一个别名。 使用语法:import mediapipe as mp 表示引入mediapipe模块并取别名为mp,在该文件的后续调用中mp就相当于是mediapipe

接着

代码块
Python
自动换行
复制代码
# 获取视频对象,0为摄像头,也可以写入视频路径
cap = cv2.VideoCapture(0)

mpHands = mp.solutions.hands
# Hands是一个类,有四个初始化参数,static_image_mode,max_num_hands,min_detection_confidence,min_tracking_confidence
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils  # 画线函数

pTime = 0  # 开始时间初始化
cTime = 0  # 目前时间初始化

复制成功

我们利用Opencv的cv2.VideoCapture()函数,获取视频对象,时间初始化为的是之后显示帧数而提前准备。

代码块
Python
自动换行
复制代码
while True:
    # sucess是布尔型,读取帧正确返回True;img是每一帧的图像(BGR存储格式)
    success, img = cap.read()
    # 将一幅图像从一个色彩空间转换为另一个,返回转换后的色彩空间图像
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # 处理RGB图像并返回手的标志点和检测到的每个手对象
    results = hands.process(imgRGB)
    # results.multi_hand_landmarks返回None或手的标志点坐标
    if results.multi_hand_landmarks:
        for handLms in results.multi_hand_landmarks:
            # landmark有21个(具体查阅上面的参考网址),id是索引,lm是x,y坐标
            for id, lm in enumerate(handLms.landmark):
                # print(id, lm)  # lm的坐标是点在图像中的比例坐标
                # h-height,w-weight图像的宽度和高度
                h, w, c = img.shape
                # 将landmark的比例坐标转换为在图像像元上的坐标
                cx, cy = int(lm.x * w), int(lm.y * h)
                print(id, cx, cy)
                # 将手的标志点个性化显示
                cv2.circle(img, (cx, cy), int(w / 50), (255, 0, 255), cv2.FILLED)
            # 在图像上绘制手的标志点和他们的连接线
            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)

    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    # 将帧率显示在图像上
    cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,
                (255, 0, 255), 1)
    # 在Image窗口上显示新绘制的图像img
    cv2.imshow("Image", img)
    # 这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户按下键,则继续执行后面的代码,如果用户没有按下键,则接续等待
    cv2.waitKey(1)
复制成功

运行结果

(转自本人博客) 看完有收获可读者可关注收藏评论 接下来的章节将更新如何模块化我们的代码,以及实现手势控制音量