AR人體姿態識別,實現無邊界的人機互動

2022-10-28 12:02:39

近年來,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. 在開發應用前需要在華為開發者聯盟網站上註冊成為開發者並完成實名認證,具體方法請參見帳號註冊認證

  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)

瞭解更多詳情>>

存取華為開發者聯盟官網
獲取開發指導檔案
華為移動服務開源倉庫地址:GitHubGitee

關注我們,第一時間瞭解 HMS Core 最新技術資訊~