如何讓虛擬角色自然融入現實?

2023-03-16 18:01:42

隨著AR的發展,虛擬角色被廣泛應用在遊戲、直播、社交等App中。例如在直播App裡,商家可以自由打造虛擬主播的形象,通過AR演演算法可以讓虛擬形象在介紹時做到不遮擋實物商品,提升直播真實性和趣味性。那麼,如何讓虛擬角色自然融入現實,實現與使用者的真實互動呢?

華為HMS Core AR Engine提供單人或雙人身體輪廓的識別和跟蹤能力,實時輸出人體輪廓Mask資訊和對應的骨骼點資訊。其中人體Mask能力可以識別和跟蹤當前畫面人體所在區域,支援多人識別,識別率達90%,並提供該區域的深度資訊。

通過人體輪廓跟蹤能力,開發者們可利用人體的輪廓Mask資訊對虛擬物體和場景進行遮蔽。比如在AR拍照時更換虛擬背景、讓虛擬玩偶躲到人身後等,都可使用Mask能力來實現更為自然的遮擋效果,這可進一步提升AR應用的真實感和觀看體驗。

Demo演示

開發步驟

開發準備

1 .註冊成為開發者

在開發應用前需要在華為開發者聯盟網站上註冊成為開發者並完成實名認證,具體方法請參見帳號註冊認證。

2 .建立應用

參見建立專案和在專案下建立應用完成應用的建立,設定如下:

「選擇平臺」:選擇「Android」。

「支援裝置」:選擇「手機」。

「應用分類」:選擇「應用」或「遊戲」。

3 .整合AR Engine SDK

華為提供了Maven倉整合方式的AR Engine SDK包,在開始開發前,需要將AR Engine SDK整合到您的開發環境中。

4 .設定AR Engine SDK的Maven倉地址

Android Studio的程式碼庫設定在Gradle外掛7.0以下版本、7.0版本和7.1及以上版本有所不同。請根據您當前的Gradle外掛版本,選擇對應的設定過程

5 .新增編譯依賴
  1. 開啟專案中應用級的「build.gradle」檔案。

  1. 在「dependencies」中新增如下編譯依賴。
dependencies {
    implementation 'com.huawei.hms:arenginesdk:{version}'
}
  1. 重新開啟修改完的build.gradle檔案,右上方出現Sync Now連結。點選「Sync Now」等待同步完成。

應用開發

執行前驗證

檢查當前裝置是否安裝了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. 建立BodyActivity用來展示AR Engine識別能力,展示身體骨骼,輸出人體特徵。
Public class BodyActivity extends BaseActivity{
Private BodyRendererManager mBodyRendererManager;
Protected void onCreate(){
	//初始化surfaceView
	mSurfaceView = findViewById();
	//保持OpenGL ES執行上下文。
	mSurfaceView.setPreserveEGLContextOnPause(true);
	//設定OpenGLES版本。
	mSurfaceView.setEGLContextClientVersion(2);
	//設定EGL設定選擇器,包括顏色緩衝區的位數和深度位數。
	mSurfaceView.setEGLConfigChooser(……);
	mBodyRendererManager = new BodyRendererManager(this);
	mSurfaceView.setRenderer(mBodyRendererManager);
mSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
		}
Protected void onResume(){
	//初始化ARSession,用於管理AR Engine的整個執行狀態
If(mArSession == null){
mArSession = new ARSession(this.getApplicationContext());
mArConfigBase = new ARBodyTrackingConfig(mArSession);
mArConfigBase.setEnableItem(ARConfigBase.ENABLE_DEPTH | ARConfigBase.ENABLE_MASK);
mArConfigBase.setFocusMode(ARConfigBase.FocusMode.AUTO_FOCUS
mArSession.configure(mArConfigBase);
	}
	//給setBodyMask傳入需要的引數
mBodyRendererManager.setBodyMask(((mArConfigBase.getEnableItem() & ARConfigBase.ENABLE_MASK) != 0) && mIsBodyMaskEnable);
sessionResume(mBodyRendererManager);
		}
}
  1. 建立BodyRendererManager, 此類渲染AR Engine獲取的個人資料。
Public class BodyRendererManager extends BaseRendererManager{
	Public void drawFrame(){
	//獲取所有指定型別的可跟蹤對像集合
Collection<ARBody> bodies = mSession.getAllTrackables(ARBody.class);
		 for (ARBody body : bodies) {
if (body.getTrackingState() != ARTrackable.TrackingState.TRACKING){
                continue;
          }
mBody = body;
hasBodyTracking = true;
    }
	//更新螢幕上顯示的身體識別資訊。
StringBuilder sb = new StringBuilder();
        updateMessageData(sb, mBody);
Size textureSize = mSession.getCameraConfig().getTextureDimensions();
if (mIsWithMaskData && hasBodyTracking && mBackgroundDisplay instanceof BodyMaskDisplay) {
            ((BodyMaskDisplay) mBackgroundDisplay).onDrawFrame(mArFrame, mBody.getMaskConfidence(),
            textureSize.getWidth(), textureSize.getHeight());
      }
	//在螢幕上顯示更新後的身體資訊。
mTextDisplay.onDrawFrame(sb.toString());
for (BodyRelatedDisplay bodyRelatedDisplay : mBodyRelatedDisplays) {
             bodyRelatedDisplay.onDrawFrame(bodies, mProjectionMatrix);
        } catch (ArDemoRuntimeException e) {
             LogUtil.error(TAG, "Exception on the ArDemoRuntimeException!");
        } catch (ARFatalException | IllegalArgumentException | ARDeadlineExceededException |
        ARUnavailableServiceApkTooOldException t) {
            Log(…);
        }
}
//更新手勢相關資料以進行顯示。
Private void updateMessageData(){
	   if (body == null) {
            return;
        }
      float fpsResult = doFpsCalculate();
      sb.append("FPS=").append(fpsResult).append(System.lineSeparator());
      int bodyAction = body.getBodyAction();
sb.append("bodyAction=").append(bodyAction).append(System.lineSeparator());
}
}
  1. 自定義相機預覽類,用於實現基於一定置信度的人體繪製。
Public class BodyMaskDisplay implements BaseBackGroundDisplay{}
  1. 獲取骨架資料並將其傳遞給OpenGL ES,OpenGL ES將渲染資料並在螢幕上顯示。
public class BodySkeletonDisplay implements BodyRelatedDisplay {
  1. 獲取骨架點連線資料,並將其傳遞給OpenGL ES以便在螢幕上渲染。
public class BodySkeletonLineDisplay implements BodyRelatedDisplay {}

其他類內容請參考範例程式碼整合。

瞭解更多詳情>>

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

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