隨著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 .添加編譯依賴
- 打開項目中應用級的“build.gradle”文件。
- 在“dependencies”中添加如下編譯依賴。
dependencies {
implementation 'com.huawei.hms:arenginesdk:{version}'
}
- 重新打開修改完的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;
}
- 創建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);
}
}
- 創建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());
}
}
- 自定義相機預覽類,用于實現基于一定置信度的人體繪制。
Public class BodyMaskDisplay implements BaseBackGroundDisplay{}
- 獲取骨架數據并將其傳遞給OpenGL ES,OpenGL ES將渲染數據并在屏幕上顯示。
public class BodySkeletonDisplay implements BodyRelatedDisplay {
- 獲取骨架點連接數據,并將其傳遞給OpenGL ES以便在屏幕上渲染。
public class BodySkeletonLineDisplay implements BodyRelatedDisplay {}
其他類內容請參考示例代碼集成。
了解更多詳情>>
訪問華為開發者聯盟官網
獲取開發指導文檔
華為移動服務開源倉庫地址:GitHub、Gitee
關注我們,第一時間了解 HMS Core 最新技術資訊~