jjzjj

【基于Mediapipe与Unity的人体姿态捕捉系统】

TonyZhang老师 2023-04-04 原文

基于Mediapipe与Unity的人体姿态捕捉系统

1. 工程整体介绍

整个工程主要分成三部分:1.基于Mediapipe的人体姿态估计;2.基于Unity的人体姿态展示;3.从Mediapipe到Unity的通讯,即Mediapipe估计的姿态如何实时传递给Unity。

2. 基于Mediapipe的人体姿态估计

姿态估计部分,使用opencv进行人体采集,然后调用Mediapipe对读取的每一帧图像进行姿态估计。

2.1 环境搭建

版本要求:python >= 3.7

 pip install mediapipe
 pip install opencv-python
 pip install opencv-contrib-python

参考官方文档:
链接: https://google.github.io/mediapipe/solutions/pose.

2.2 代码片段

博主假设你已经掌握了最基础的python语法

import cv2
import mediapipe as mp
import numpy as np

def Pose_Images():
    #使用算法包进行姿态估计时设置的参数
    mp_pose = mp.solutions.pose
    with mp_pose.Pose(
        min_detection_confidence=0.5,
        min_tracking_confidence=0.8) as pose:
      #打开摄像头
      cap = cv2.VideoCapture(0)
      while(True):
        #读取摄像头图像
        hx, image = cap.read() 
        if hx is False:
            print('read video error')
            exit(0)
        image.flags.writeable = False
        # Convert the BGR image to RGB before processing.
        # 姿态估计
        results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
        print(results.pose_landmarks)
        cv2.imshow('image', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):       # 按q退出
          break
      cap.release()


if __name__ == '__main__':
    Pose_Images()

2.3 结果展示

在你的控制台可以看到一个一个点的输出,如下,那么姿态估计就完成了第一步。

landmark {
  x: 0.7439931035041809
  y: 3.0562074184417725
  z: -0.25115278363227844
  visibility: 0.00022187501599546522
}
landmark {
  x: 0.5690034627914429
  y: 3.0262765884399414
  z: -0.44416818022727966
  visibility: 0.00034665243583731353
}
......

2.4 结果分析

下面我们来分析一下这些点的坐标到底代表了什么。
每一张图片都会产生一组坐标,每组坐标包含32个坐标点。

每个地标包括以下内容:

  • x和y:通过图像宽度和高度分别归一化为[0.0, 1.0],通俗点说是,真实的x,y坐标,分别除以图像的宽度跟高度。
  • z: 代表坐标的深度,臀部中点的深度为原点,数值越小,地标就越靠近摄像机。z的大小使用与x大致相同的比例。
  • visibility:一个[0.0, 1.0]的值,表示坐标在图像中可见(存在且不被遮挡)的可能性。

2.5 本章总结

我们通过使用opencv库,打开摄像头采集照片,将照片传递给Mediapipe进行姿态坐标估计,后续我们将坐标放到Unity中进行展示就可以了。

3. 基于Unity的人体姿态展示

博主假设你已经掌握了unity的基础知识。

3.1 Unity 人体骨骼动画

我们可以从Unity商店中或者在此网站https://www.mixamo.com选择任意一个3D的人物模型导入到工程中。

3.2 Mediapipe坐标到Unity的映射

具体转换细节会专门写一篇文件来解释,数据是驱动骨骼运动的。整体的实现参考了开源的解决方案。
参考:
https://github.com/digital-standard/ThreeDPoseTracker
VNectModel.cs 文件实现了从预测坐标到Unity骨骼坐标的转换。

4. 从Mediapipe到Unity的数据传递

姿态预测跟unity的姿态展示毕竟属于不同的进程,对于进程之间的通讯有不同的实现方式。本文选择网络通讯中的UDP通讯,因为UDP通讯具有延迟小的特点,同时我们对于数据的丢失存在一定的容忍性。

4.1 使用Python发送数据

#代码片段示例:
json_data = json.dumps(pose_data)
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dest_addr = ('127.0.0.1', 5052)
text = json_data.encode('utf-8')
udp_socket.sendto(text, dest_addr)

4.2 使用C#接收数据

此代码片段借鉴了此博主的文章(如有侵权,联系删除)。
Link

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class UDPRecive : MonoBehaviour
{
    Thread receiveThread;
    UdpClient client; 
    public int port = 5052;
    public bool startRecieving = true;
    public string data;
    // Start is called before the first frame update
    void Start()
    {
        receiveThread = new Thread(
            new ThreadStart(ReceiveData));
        receiveThread.IsBackground = true;
        receiveThread.Start();
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    
    private void ReceiveData()
    {
        client = new UdpClient(port);
        while (startRecieving)
        {
             Debug.Log("startRecieving");
            try
            {
                IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
                byte[] dataByte = client.Receive(ref anyIP);
                data = Encoding.UTF8.GetString(dataByte);
                Debug.Log(data);
            }
            catch (Exception err)
            {
                print(err.ToString());
            }
        }
    }
}

5. 成果展示

从姿态预测到3D展示就完成了,那么我们来看一下效果吧。

11月25日

6. 后续展望

后续会根据需求,出一个对全部代码的讲解,可以帮助读者一步步实现自己的工程。
欢迎提出意见或建议。

7.联系方式

欢迎私信加我。

有关【基于Mediapipe与Unity的人体姿态捕捉系统】的更多相关文章

  1. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  2. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  7. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  10. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

随机推荐