​Python使用Mediapipe对图像进行手部地标检测

目录
  • 概述
  • 行业用例
  • 导入库
  • 使用Mediapipe初始化手的地标检测模型
    • 读取图像
    • 执行手部地标检测
    • 在图像上绘制地标
  • 结论
  • 尾注

概述

在本文中,我们将以深度库即 Mediapipe为基础库,以及其他计算机视觉预处理的CV2库来制作手部地标检测模型。市场上有很多关于这种问题的用例,例如商业相关的虚拟现实、游戏部分的实时体验。

行业用例

智能家居:这是计算机视觉的现代用例之一,人们使用智能家居来过上更舒适的生活,这就是为什么它不再是一个小众领域,它也正在蔓延到普通家庭。

智能电视:我们经常看到这种用例,你可以用手势来改变音量、改变频道等等。

游戏:对于真正的体验,这项技术越来越多地融入互动游戏。

让我们建立我们的手部检测模型

导入库

在这里,我们将导入整个管道中需要的所有库

import cv2
import numpy as np
import mediapipe as mp
import matplotlib.pyplot as plt

使用 Mediapipe 初始化手的地标检测模型

第一步是使用有效参数初始化模型,无论我们采用哪种检测技术,它可以是Mediapipe 或Yolo,初始化模型很重要,遵循相同的原则,我们将遵循所有给定的步骤:

# First step is to initialize the Hands class an store it in a variable
mp_hands = mp.solutions.hands

# Now second step is to set the hands function which will hold the landmarks points
hands = mp_hands.Hands(static_image_mode=True, max_num_hands=2, min_detection_confidence=0.3)

# Last step is to set up the drawing function of hands landmarks on the image
mp_drawing = mp.solutions.drawing_utils

代码分解:

  1. 首先,使用mp.solutions.hands初始化变量 mp_hands。
  2. 然后使用相同的变量通过mp.solutions.hands.Hands()为hands设置函数。

到目前为止,我们了解了手模型初始化的结构,现在让我们深入研究函数中使用的参数hands

  • static_image_mode: 该参数将布尔值作为其有效值,即它可以是True或False。当处理视频流时,默认条件是 False ,这意味着它会降低处理延迟,即它会继续专注于特定的手并定位相同的手,直到它追踪的手消失,当我们必须检测实时流或视频中的手时,这可能是有益的,根据我们的要求,我们必须检测图像上的地标,因此我们将值设置为True
  • max_num_hands:此参数将指示模型将在一个实例中检测到的最大手数。默认情况下,该值为 2,这也是有意义的,尽管我们可以更改它,但我们希望至少检测到一双手。
  • min_detection_confidence:它提供了置信水平的阈值。最小检测置信度的理想范围是 [0.0,1.0],默认情况下,它保持为 0.5,这意味着如果置信度低于 50%,则在输出图像中根本不会检测到手。

最后,我们将使用mp.solutions.drawing_utils,它将负责在输出图像上绘制所有手的地标,这些地标由我们的 Hands 函数检测到。

读取图像

在这里,我们将首先使用cv2.imread()读取要在其上执行手部检测的图像,并使用matplotlib库来显示该特定输入图像。

# Reading the sample image on which we will perform the detection
sample_img = cv2.imread('media/sample.jpg')

# Here we are specifing the size of the figure i.e. 10 -height; 10- width.
plt.figure(figsize = [10, 10])

# Here we will display the sample image as the output.
plt.title("Sample Image");plt.axis('off');plt.imshow(sample_img[:,:,::-1]);plt.show()

输出:

执行手部地标检测

因此,现在我们已经初始化了我们的手部检测模型,下一步将是处理输入图像上的手部地标检测,并使用上述初始化模型在该图像上绘制所有 21 个地标,我们将通过以下步骤。

results = hands.process(cv2.cvtColor(sample_img, cv2.COLOR_BGR2RGB))

if results.multi_hand_landmarks:

   for hand_no, hand_landmarks in enumerate(results.multi_hand_landmarks):
        print(f'HAND NUMBER: {hand_no+1}')
        print('-----------------------')

        for i in range(2):
            print(f'{mp_hands.HandLandmark(i).name}:')
            print(f'{hand_landmarks.landmark[mp_hands.HandLandmark(i).value]}')

输出:

代码分解:

  1. 第一步,我们使用Mediapipe 库中的process函数将手部地标检测结果存储在变量results中,同时我们将图像从 BGR 格式转换为 RGB 格式。
  2. 在进入下一步时,我们将首先检查一些验证,是否检测到点,即变量results应该存放了一些结果。
  3. 如果是,那么我们将遍历在图像中检测到的具有手部地标的所有点。
  4. 现在在另一个循环中,我们可以看到只有 2 次迭代,因为我们只想显示手的 2 个地标。
  5. 最后,我们将根据要求打印出所有检测到并过滤掉的地标。

从上面的处理中,我们发现所有检测到的地标都被归一化为通用尺度,但是现在对于用户端,这些缩放点是不相关的,因此我们会将这些地标恢复到原始状态。

image_height, image_width, _ = sample_img.shape

if results.multi_hand_landmarks:

    for hand_no, hand_landmarks in enumerate(results.multi_hand_landmarks):

        print(f'HAND NUMBER: {hand_no+1}')
        print('-----------------------')

        for i in range(2):
            print(f'{mp_hands.HandLandmark(i).name}:')
            print(f'x: {hand_landmarks.landmark[mp_hands.HandLandmark(i).value].x * image_width}')
            print(f'y: {hand_landmarks.landmark[mp_hands.HandLandmark(i).value].y * image_height}')
            print(f'z: {hand_landmarks.landmark[mp_hands.HandLandmark(i).value].z * image_width}n')

输出:

代码分解:

我们只需要在这里执行一个额外的步骤,即我们将从我们定义的示例图像中获得图像的原始宽度和高度,然后所有步骤将与我们之前所做的相同,唯一不同的将是现在地标点没有专门缩放。

在图像上绘制地标

由于我们已经从上述预处理中获得了手部地标,现在是时候执行我们的最后一步了,即在图像上绘制点,以便我们可以直观地看到我们的手部地标检测模型是如何执行的。

img_copy = sample_img.copy()

if results.multi_hand_landmarks:

    for hand_no, hand_landmarks in enumerate(results.multi_hand_landmarks):

        mp_drawing.draw_landmarks(image = img_copy, landmark_list = hand_landmarks,
                                  connections = mp_hands.HAND_CONNECTIONS)
    fig = plt.figure(figsize = [10, 10])

    plt.title("Resultant Image");plt.axis('off');plt.imshow(img_copy[:,:,::-1]);plt.show()

输出:

代码分解:

  1. 首先,我们将创建原始图像的副本,此步骤是出于安全目的,因为我们不想失去图像的原创性。
  2. 然后我们将处理之前所做的验证工作。
  3. 然后我们将遍历手的每个地标。
  4. 最后,借助mp_drawing.draw_landmarks函数,我们将在图像上绘制地标。
  5. 是时候使用 matplotlib 绘制图像了,所以首先,我们将给出图形大小(此处为 width-10 和 height-10),然后在最后绘制,imshow将 BGR 格式转换为 RGB 格式后的图像使用函数,因为对于 RGB 格式更有意义。

结论

在整个管道中,我们首先初始化模型,然后读取图像,查看输入图像,然后进行预处理。我们缩小了地标点,但这些点与用户无关,因此我们将其恢复到原始状态,最后我们将在图像上绘制地标。

尾注

这是本文的 github 链接:https://github.com/Aman-Preet-Singh-Gulati/hands-landmarks-detection-mediapipe

到此这篇关于Python使用Mediapipe对图像进行手部地标检测的文章就介绍到这了,更多相关Python Mediapipe手部地标检测内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python+mediapipe+opencv实现手部关键点检测功能(手势识别)

    目录 一.mediapipe是什么? 二.使用步骤 1.引入库 2.主代码 3.识别结果 补充: 一.mediapipe是什么? mediapipe官网 二.使用步骤 1.引入库 代码如下: import cv2 from mediapipe import solutions import time 2.主代码 代码如下: cap = cv2.VideoCapture(0) mpHands = solutions.hands hands = mpHands.Hands() mpDraw = so

  • 超好玩的"隔空操物"通过Python MediaPipe库实现

    目录 1.项目效果展示 1.1:隔空音量控制 1.2:隔空绘画 1.3 :手势识别 1.4:鼠标模拟 2.所涉及到的库 2.1:OpenCv简介 2.2:MediaPipe简介 3.项目环境搭建 4.源码部分 5.总结 文章简介 :本篇文章的实战部分中主要使用到了 MediaPipe 与 OpenCv 两个库,实现了隔空操作的效果,主要有**隔空操作鼠标,隔空绘画,隔空控制音量与隔空手势识别 ** 演示视频 使用这个编程语言,我实现了隔空操物!! 1.项目效果展示 项目主要分为四个部分,分别是

  • Python+MediaPipe实现检测人脸功能详解

    目录 MediaPipe概述 人脸检测 MediaPipe概述 谷歌开源MediaPipe于2019年6月首次推出.它的目标是通过提供一些集成的计算机视觉和机器学习功能,使我们的生活变得轻松. MediaPipe是用于构建多模态(例如视频.音频或任何时间序列数据).跨平台(即eAndroid.IOS.web.边缘设备)应用ML管道的框架. Mediapipe还促进了机器学习技术在各种不同硬件平台上的演示和应用程序中的部署. 应用 人脸检测 多手跟踪 头发分割 目标检测与跟踪 目标:三维目标检测与

  • ​Python使用Mediapipe对图像进行手部地标检测

    目录 概述 行业用例 导入库 使用Mediapipe初始化手的地标检测模型 读取图像 执行手部地标检测 在图像上绘制地标 结论 尾注 概述 在本文中,我们将以深度库即 Mediapipe为基础库,以及其他计算机视觉预处理的CV2库来制作手部地标检测模型.市场上有很多关于这种问题的用例,例如商业相关的虚拟现实.游戏部分的实时体验. 行业用例 智能家居:这是计算机视觉的现代用例之一,人们使用智能家居来过上更舒适的生活,这就是为什么它不再是一个小众领域,它也正在蔓延到普通家庭. 智能电视:我们经常看到

  • python使用PyGame绘制图像并保存为图片文件的方法

    本文实例讲述了python使用PyGame绘制图像并保存为图片文件的方法.分享给大家供大家参考.具体实现方法如下: ''' pg_draw_circle_save101.py draw a blue solid circle on a white background save the drawing to an image file for result see http://prntscr.com/156wxi tested with Python 2.7 and PyGame 1.9.2

  • Python图像处理之识别图像中的文字(实例讲解)

    ①安装PIL:pip install Pillow(之前的博客中有写过) ②安装pytesser3:pip install pytesser3 ③安装pytesseract:pip install pytesseract ④安装autopy3: 先安装wheel:pip install wheel 下载autopy3-0.51.1-cp36-cp36m-win_amd64.whl[点击打开链接] 执行命令:pip install E:\360安全浏览器下载\autopy3-0.51.1-cp36

  • 关于Python 的简单栅格图像边界提取方法

    在GIS中,栅格属性里有关于栅格自身的信息,背景(nodata value)对于识别一张图像的边界像元尤为重要,我们目的只要把每行每列中的第一次出现不是nodata的像元和最后一次出现nodata的前一个像元就可以了. 对于栅格,可以用ArcPy中的RasterToNumpyArray函数将将栅格转成numpy数组,然后就可以按照所想读取出每行列中首尾像元. 以下是部分代码提取边界像元的核心算法,其实是很简单的一个思路(假设0是nodata value). a=[[0 for col in ra

  • python实现在函数图像上添加文字和标注的方法

    如下所示: import matplotlib.pyplot as plt import numpy as np from matplotlib import font_manager #先确定字体,以免无法识别汉字 my_font = font_manager.FontProperties(fname= "C:/Windows/Fonts/msyh.ttc") X=np.linspace(-np.pi,np.pi,100) plt.figure(figsize=(6,5)) Y_x2

  • 在python中画正态分布图像的实例

    1.正态分布简介 正态分布(normal distribtution)又叫做高斯分布(Gaussian distribution),是一个非常重要也非常常见的连续概率分布.正态分布大家也都非常熟悉,下面做一些简单的介绍. 假设随机变量XX服从一个位置参数为μμ.尺度参数为σσ的正态分布,则可以记为: 而概率密度函数为 2.在python中画正态分布直方图 先直接上代码 import numpy as np import matplotlib.mlab as mlab import matplot

  • python/Matplotlib绘制复变函数图像教程

    今天发现sympy依赖的库mpmath里也有很多数学函数,其中也有在复平面绘制二维图的函数cplot,具体例子如下 from mpmath import * def f1(z): return z def f2(z): return z**3 def f3(z): return (z**4-1)**(1/4) def f4(z): return 1/z def f5(z): return atan(z) def f6(z): return sqrt(z) cplot(f1) cplot(f2)

  • Python OpenCV读取png图像转成jpg图像存储的方法

    如下所示: import os import cv2 import sys import numpy as np path = "F:\\ImageLib\\VRWorks_360_Video _SDK_1.1\\footage14\\" print(path) for filename in os.listdir(path): if os.path.splitext(filename)[1] == '.png': # print(filename) img = cv2.imread(

  • 使用python绘制二元函数图像的实例

    废话少说,直接上代码: #coding:utf-8 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def function_2(x,y): # 这里的函数可以任意定义 return np.sum(x**2) fig = plt.figure() ax = Axes3D(fig) x = np.arange(-3,-3,0.1) y = np.arange(-3,

随机推荐