天天看點

AR人體姿态識别,實作無邊界的人機互動

近年來,AR不斷發展,作為一種增強現實技術,給使用者帶來了虛拟和現實世界的融合體驗。但使用者已經不滿足于單純地将某件虛拟物品放在現實場景中來感受AR技術,更想用身體姿勢來觸發某個指令,達到更具真實感的人機互動功能。

比如在AR體感遊戲中,使用者不必點選按鍵進行頻繁操作,通過某個姿勢即可觸發;在拍攝短視訊時,使用者無需接觸螢幕,擺出不同的姿勢便可觸發某些特定效果;健身App中,教練進行健身教學時,使用者可以擺出相應姿勢跟練,由系統識别姿勢是否标準。

那麼,如何用特定的人體姿勢來識别指令進行人機互動呢?

華為HMS Core AR Engine服務給出了解決方案,其中人體姿态識别服務提供了單人身體姿态識别能力,識别六種靜态身體姿勢并輸出識别結果,支援前後錄影機切換,實作虛拟世界與現實世界的融合。

AR人體姿态識别,實作無邊界的人機互動

開發者夥伴可将人體姿态識别能力運用在需要識别動作并觸發某些事件的應用場景中,比如互動界面控制、遊戲操作動作識别等觸發類互動行為,是體感應用的基礎核心功能,為開發者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. 在開發應用前需要在華為開發者聯盟網站上注冊成為開發者并完成實名認證,具體方法請參見帳号注冊認證。
  2. 華為提供了Maven倉內建方式的AR Engine SDK包,在開始開發前,需要将AR Engine SDK內建到您的開發環境中。
  3. Android Studio的代碼庫配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。請根據您目前的Gradle插件版本,選擇對應的配置過程。
  4. 以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. 添加依賴 在“dependencies”中添加如下編譯依賴:
dependencies {
    implementation 'com.huawei.hms:arenginesdk:{version}
}
           

應用開發

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;
}
           

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);
           

4.初始化BodyRelatedDisplay接口,用于渲染主體AR類型相關資料。

Public interface BodyRelatedDisplay{
     Void init();
     Void onDrawFrame(Collection<ARBody> bodies,float[] projectionMatrix);
  }
           
  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<ARBody> bodies = mSession.getAllTrackbles(ARBody.class);
         }
   }
           
  1. 初始化BodySkeletonDisplay,用來擷取骨架資料并将其傳遞給openGL ES,openGL ES将渲染資料并在螢幕上顯示。
Public class BodySkeletonDisplay implements BodyRelatedDisplay{
        //此類需要幾個方法
//初始化方法
public void init(){
}
//使用OpenGL更新節點資料并繪制。
Public void onDrawFrame(Collection<ARBody> 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. 擷取骨架點連接配接資料,并将其傳遞給OpenGL ES以便在螢幕上渲染。
public class BodySkeletonLineDisplay implements BodyRelatedDisplay {
     //渲染身體骨骼之間的線條。
     public void onDrawFrame(Collection<ARBody> 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);
            }
        }
}
}
           

8.具體實作請參考:AR Engine示例代碼-AR Engine | 華為開發者聯盟 (huawei.com)