• AR人体姿态识别,实现无边界的人机交互


    近年来,AR不断发展,作为一种增强现实技术,给用户带来了虚拟和现实世界的融合体验。但用户已经不满足于单纯地将某件虚拟物品放在现实场景中来感受AR技术,更想用身体姿势来触发某个指令,达到更具真实感的人机交互功能。

    比如在AR体感游戏中,用户不必点击按键进行频繁操作,通过某个姿势即可触发;在拍摄短视频时,用户无需接触屏幕,摆出不同的姿势便可触发某些特定效果;健身App中,教练进行健身教学时,用户可以摆出相应姿势跟练,由系统识别姿势是否标准。

    那么,如何用特定的人体姿势来识别指令进行人机交互呢?

    华为HMS Core AR Engine服务给出了解决方案,其中人体姿态识别服务提供了单人身体姿态识别能力,识别六种静态身体姿势并输出识别结果,支持前后摄像机切换,实现虚拟世界与现实世界的融合。

    开发者伙伴可将人体姿态识别能力运用在需要识别动作并触发某些事件的应用场景中,比如交互界面控制、游戏操作动作识别等触发类交互行为,是体感应用的基础核心功能,为开发者AR应用提供较远距离远程控制和协作能力,丰富应用交互体验。

    下面是开发者应用集成AR Engine人体姿态识别能力的具体步骤。

    开发步骤

    开发环境要求:

    JDK 1.8.211及以上。

    安装Android Studio 3.0及以上:

    minSdkVersion 26及以上

    targetSdkVersion 29(推荐)

    compileSdkVersion 29(推荐)

    Gradle 6.1.1及以上(推荐)

    在华为终端设备上的应用市场下载AR Engine服务端APK(需在华为应用市场,搜索“华为AR Engine”)并安装到终端设备。

    测试应用的设备:参见AREngine特性软硬件依赖表。如果同时使用多个HMS Core的服务,则需要使用各个Kit对应的最大值。

    开发准备

    1. 在开发应用前需要在华为开发者联盟网站上注册成为开发者并完成实名认证,具体方法请参见帐号注册认证
    1. 华为提供了Maven仓集成方式的AR Engine SDK包,在开始开发前,需要将AR Engine SDK集成到您的开发环境中。
    1. Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle插件版本,选择对应的配置过程。
    1. 以7.0为例:

    打开Android Studio项目级“build.gradle”文件,添加Maven代码库。

    在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。

    buildscript {
            repositories {
                google()
                jcenter()
                maven {url "https://developer.huawei.com/repo/" }
            }
    }
    打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。
    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
                repositories {
                        repositories {
                                google()
                            jcenter()
                            maven {url "https://developer.huawei.com/repo/" }
                        }
                    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. 添加依赖 在“dependencies”中添加如下编译依赖:
    dependencies {
        implementation 'com.huawei.hms:arenginesdk:{version}
    }
    • 1
    • 2

    应用开发

    1.运行前验证:检查当前设备是否安装了AR Engine,若已经安装则正常运行,若没有安装,App应采用合适的方式提醒用户安装AR Engine,如主动跳转应用市场,请求安装AR Engine。具体实现代码如下:

    boolean isInstallArEngineApk =AREnginesApk.isAREngineApkReady(this);
    if (!isInstallArEngineApk) {
                // ConnectAppMarketActivity.class为跳转应用市场的Activity。
    startActivity(new Intent(this, com.huawei.arengine.demos.common.ConnectAppMarketActivity.class));
               isRemindInstall = true;
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    2.初始化AR场景:AREngine提供5种场景,包括运动跟踪(ARWorldTrackingConfig)、人脸跟踪(ARFaceTrackingConfig)、手部识别(ARHandTrackingConfig)、人体跟踪(ARBodyTrackingConfig)和图像识别(ARImageTrackingConfig)。

    3.调用ARBodyTrackingConfig接口,初始化人体跟踪场景。

      mArSession = new ARSession(context)
      ARBodyTrackingConfig config = new ARHandTrackingConfig(mArSession);
      Config.setEnableItem(ARConfigBase.ENABLE_DEPTH | ARConfigBase.ENABLE.MASK);
      配置session信息
      mArSession.configure(config);
    • 1
    • 2
    • 3
    • 4

    4.初始化BodyRelatedDisplay接口,用于渲染主体AR类型相关数据。

    Public interface BodyRelatedDisplay{
         Void init();
         Void onDrawFrame(Collection bodies,float[] projectionMatrix);
      }
    • 1
    • 2
    • 3
    1. 初始化BodyRenderManager类,此类渲染AREngine获取的个人数据。
    Public class BodyRenderManager implements GLSurfaceView.Renderer{
    
            //实现onDrawFrame方法
             Public void onDrawFrame(){
                 ARFrame frame = mSession.update();
                 ARCamera camera = Frame.getCramera();
                 //获取AR相机的投影矩阵。
                 Camera.getProjectionMatrix();
                 //获取所有指定类型的可跟踪对像集合,传入ARBody.class, 用于人体骨骼跟踪时返回跟踪结果
                 Collection bodies = mSession.getAllTrackbles(ARBody.class);
             }
       }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 初始化BodySkeletonDisplay,用来获取骨架数据并将其传递给openGL ES,openGL ES将渲染数据并在屏幕上显示。
    Public class BodySkeletonDisplay implements BodyRelatedDisplay{
            //此类需要几个方法
    //初始化方法
    public void init(){
    }
    //使用OpenGL更新节点数据并绘制。
    Public void onDrawFrame(Collection bodies,float[] projectionMatrix){
       for (ARBody body : bodies) {
                if (body.getTrackingState() == ARTrackable.TrackingState.TRACKING) {
                    float coordinate = 1.0f;
                    if (body.getCoordinateSystemType() == ARCoordinateSystemType.COORDINATE_SYSTEM_TYPE_3D_CAMERA) {
                        coordinate = DRAW_COORDINATE;
                    }
                    findValidSkeletonPoints(body);
                    updateBodySkeleton();
                    drawBodySkeleton(coordinate, projectionMatrix);
                }
            }
    }
    //查找有效骨架点
    private void findValidSkeletonPoints(ARBody arBody) {
            int index = 0;
            int[] isExists;
            int validPointNum = 0;
            float[] points;
            float[] skeletonPoints;
    
    if (arBody.getCoordinateSystemType() == ARCoordinateSystemType.COORDINATE_SYSTEM_TYPE_3D_CAMERA) {
                isExists = arBody.getSkeletonPointIsExist3D();
                points = new float[isExists.length * 3];
                skeletonPoints = arBody.getSkeletonPoint3D();
            } else {
                isExists = arBody.getSkeletonPointIsExist2D();
                points = new float[isExists.length * 3];
                skeletonPoints = arBody.getSkeletonPoint2D();
            }
    for (int i = 0; i < isExists.length; i++) {
                if (isExists[i] != 0) {
                    points[index++] = skeletonPoints[3 * i];
                    points[index++] = skeletonPoints[3 * i + 1];
                    points[index++] = skeletonPoints[3 * i + 2];
                    validPointNum++;
                }
            }
            mSkeletonPoints = FloatBuffer.wrap(points);
            mPointsNum = validPointNum;
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    1. 获取骨架点连接数据,并将其传递给OpenGL ES以便在屏幕上渲染。
    public class BodySkeletonLineDisplay implements BodyRelatedDisplay {
         //渲染身体骨骼之间的线条。
         public void onDrawFrame(Collection bodies, float[] projectionMatrix) {
            for (ARBody body : bodies) {
                if (body.getTrackingState() == ARTrackable.TrackingState.TRACKING) {
                    float coordinate = 1.0f;
                    if (body.getCoordinateSystemType() == ARCoordinateSystemType.COORDINATE_SYSTEM_TYPE_3D_CAMERA) {
                        coordinate = COORDINATE_SYSTEM_TYPE_3D_FLAG;
                    }
                    updateBodySkeletonLineData(body);
                    drawSkeletonLine(coordinate, projectionMatrix);
                }
            }
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    8.具体实现请参考:AR Engine示例代码-AR Engine | 华为开发者联盟 (huawei.com)

    了解更多详情>>

    访问华为开发者联盟官网
    获取开发指导文档
    华为移动服务开源仓库地址:GitHubGitee

    关注我们,第一时间了解 HMS Core 最新技术资讯~

  • 相关阅读:
    ISP学习笔记
    CVE-2022-22963:Spring Cloud Function SpEL 远程代码执行漏洞
    【自动驾驶】针对低速无人车的线控底盘技术
    vertx学习总结5
    shell流程控制
    图的理论基础
    昨天步行的思考
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(10.A)- FlexSPI NAND启动时间(RT1170)
    HTTP 代理服务器的设计与实现(C++)
    继承和多态
  • 原文地址:https://blog.csdn.net/HUAWEI_HMSCore/article/details/127565798