隨著電子產品的普遍應用,AR技術也開始廣泛普及,在游戲、電商、家裝等領域都有涉及。比如,在室內設計時,我們可以通過AR技術在實際場景中進行虛擬軟裝的搭配,運用華為AR Engine運動跟蹤能力在實際應用中實時輸出室內環境的三維坐標信息,確定現實室內環境和虛擬軟裝之間的變換關係,從而穩定精準的實現軟裝 ...
隨著電子產品的普遍應用,AR技術也開始廣泛普及,在游戲、電商、家裝等領域都有涉及。比如,在室內設計時,我們可以通過AR技術在實際場景中進行虛擬軟裝的搭配,運用華為AR Engine運動跟蹤能力在實際應用中實時輸出室內環境的三維坐標信息,確定現實室內環境和虛擬軟裝之間的變換關係,從而穩定精準的實現軟裝在室內空間的合理放置。
作為華為AR Engine的一項基本能力,運動跟蹤能力主要通過持續穩定跟蹤終端設備的位置和姿態相對於周圍環境的變化,同時輸出周圍環境特征的三維坐標信息,在AR 技術的實際應用中起到了框架搭建的作用,是構建現實世界和虛擬世界的橋梁。
特性介紹
運動跟蹤能力通過跟蹤終端設備的位置和姿態相對於周圍環境的變化,可以確定終端設備的虛擬坐標系與周圍環境世界坐標系的變換關係,把終端設備的虛擬坐標系一起統一到周圍環境的世界坐標系下,從觀察者視角渲染虛擬物體,再疊加到攝像頭圖像中,從而實現虛擬與現實在幾何上的融合。
比如在下圖AR車展的場景中,就需要藉助運動跟蹤的能力,實時跟蹤攝像頭相對於周圍環境的運動姿態和變化軌跡,通過建立虛擬世界和現實世界統一的幾何空間,實現虛擬汽車在現實地面上的精準放置。
實現虛實融合的基本條件是實時跟蹤終端設備的運動,並根據運動跟蹤結果實時更新虛擬物體狀態,才能在現實和虛擬世界之間建立穩定的聯繫,所以說,運動跟蹤的精度與質量直接影響AR應用的整體效果,凡是出現延遲、誤差等情況,都會造成虛擬物體抖動或者漂移,很大程度上破壞AR體驗的真實感和沉浸性。
特性優勢
近日,華為AR Engine 3.0使用SLAM 3.0技術,在技術指標方面取得了進一步的提升。
-
實現6DOF的運動跟蹤方式(世界跟蹤方式),能從不同距離、方向、角度觀察虛擬物體,營造更加真實的AR體驗環境;
-
實現單目ATE(絕對軌跡誤差)低至1.6cm,確保虛擬物體穩定性,體驗效果更佳。
-
平面檢測時長小於1秒,平面識別和擴展速度更快。
集成步驟
一、 登錄華為開發者聯盟官網,創建應用。
二、 集成AR Engine SDK。
- 打開Android Studio項目級“build.gradle”文件。添加Maven代碼庫。(這裡以7.0以下版本舉例)
在“buildscript > repositories”中配置HMS Core SDK的Maven倉地址。
在“allprojects > repositories”中配置HMS Core SDK的Maven倉地址。
buildscript {
repositories {
google()
jcenter()
// 配置HMS Core SDK的Maven倉地址。
maven {url "https://developer.huawei.com/repo/" }
}
}
allprojects {
repositories {
google()
jcenter()
// 配置HMS Core SDK的Maven倉地址。
maven {url "https://developer.huawei.com/repo/" }
}
}
- 打開項目中應用級的“build.gradle”文件。
dependencies {
implementation 'com.huawei.hms:arenginesdk:3.1.0.1'
}
三、 代碼開發
- 檢查當前設備是否安裝了AR Engine,若已經安裝則正常運行,若沒有安裝主動跳轉應用市場,請求安裝AR Engine。
private boolean arEngineAbilityCheck() {
boolean isInstallArEngineApk = AREnginesApk.isAREngineApkReady(this);
if (!isInstallArEngineApk && isRemindInstall) {
Toast.makeText(this, "Please agree to install.", Toast.LENGTH_LONG).show();
finish();
}
LogUtil.debug(TAG, "Is Install AR Engine Apk: " + isInstallArEngineApk);
if (!isInstallArEngineApk) {
startActivity(new Intent(this, com.huawei.arengine.demos.common.ConnectAppMarketActivity.class));
isRemindInstall = true;
}
return AREnginesApk.isAREngineApkReady(this);
}
- 運行前許可權檢查
AndroidManifest裡面配置相機許可權
<uses-permission android:name="android.permission.CAMERA" />
private static final int REQUEST_CODE_ASK_PERMISSIONS = 1;
private static final int MAX_ARRAYS = 10;
private static final String[] PERMISSIONS_ARRAYS = new String[]{Manifest.permission.CAMERA};
List<String> permissionsList = new ArrayList<>(MAX_ARRAYS);
boolean isHasPermission = true;
for (String permission : PERMISSIONS_ARRAYS) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
isHasPermission = false;
break;
}
}
if (!isHasPermission) {
for (String permission : PERMISSIONS_ARRAYS) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
}
}
ActivityCompat.requestPermissions(activity,
permissionsList.toArray(new String[permissionsList.size()]), REQUEST_CODE_ASK_PERMISSIONS);
}
- 調用ARWorldTrackingConfig介面,創建運動跟蹤ARSession,
private ARSession mArSession;
private ARWorldTrackingConfig mConfig;
config.setCameraLensFacing(ARConfigBase.CameraLensFacing.FRONT); // 通過config.setXXX方法配置場景參數
config.setPowerMode(ARConfigBase.PowerMode.ULTRA_POWER_SAVING);
mArSession.configure(config);
mArSession.resume();
mArSession.configure(config);
mSession.setCameraTextureName(mTextureDisplay.getExternalTextureId());
ARFrame arFrame = mSession.update(); // 從ARSession中獲取一幀的數據。
// Set the environment texture probe and mode after the camera is initialized.
setEnvTextureData();
ARCamera arCamera = arFrame.getCamera(); // 可以從ARFrame中獲取ARCamera,ARCamera對象可以獲取相機的投影矩陣,用來渲染視窗。
// The size of the projection matrix is 4 * 4.
float[] projectionMatrix = new float[16];
arCamera.getProjectionMatrix(projectionMatrix, PROJ_MATRIX_OFFSET, PROJ_MATRIX_NEAR, PROJ_MATRIX_FAR);
mTextureDisplay.onDrawFrame(arFrame);
StringBuilder sb = new StringBuilder();
updateMessageData(arFrame, sb);
mTextDisplay.onDrawFrame(sb);
// The size of ViewMatrix is 4 * 4.
float[] viewMatrix = new float[16];
arCamera.getViewMatrix(viewMatrix, 0);
for (ARPlane plane : mSession.getAllTrackables(ARPlane.class)) { // 從ARSession中獲取所有的可跟蹤平面。
if (plane.getType() != ARPlane.PlaneType.UNKNOWN_FACING
&& plane.getTrackingState() == ARTrackable.TrackingState.TRACKING) {
hideLoadingMessage();
break;
}
}
drawTarget(mSession.getAllTrackables(ARTarget.class), arCamera, viewMatrix, projectionMatrix);
mLabelDisplay.onDrawFrame(mSession.getAllTrackables(ARPlane.class), arCamera.getDisplayOrientedPose(),
projectionMatrix);
handleGestureEvent(arFrame, arCamera, projectionMatrix, viewMatrix);
ARLightEstimate lightEstimate = arFrame.getLightEstimate();
ARPointCloud arPointCloud = arFrame.acquirePointCloud();
getEnvironmentTexture(lightEstimate);
drawAllObjects(projectionMatrix, viewMatrix, getPixelIntensity(lightEstimate));
mPointCloud.onDrawFrame(arPointCloud, viewMatrix, projectionMatrix);
ARHitResult hitResult = hitTest4Result(arFrame, arCamera, event.getEventSecond());
if (hitResult != null) {
mSelectedObj.setAnchor(hitResult.createAnchor()); // 在命中檢測位置創建錨點,使得AREngine持續跟蹤。
}
- 根據錨點位置來繪製所需的虛擬物體。
mEnvTextureBtn.setOnCheckedChangeListener((compoundButton, b) -> {
mEnvTextureBtn.setEnabled(false);
handler.sendEmptyMessageDelayed(MSG_ENV_TEXTURE_BUTTON_CLICK_ENABLE,
BUTTON_REPEAT_CLICK_INTERVAL_TIME);
mEnvTextureModeOpen = !mEnvTextureModeOpen;
if (mEnvTextureModeOpen) {
mEnvTextureLayout.setVisibility(View.VISIBLE);
} else {
mEnvTextureLayout.setVisibility(View.GONE);
}
int lightingMode = refreshLightMode(mEnvTextureModeOpen, ARConfigBase.LIGHT_MODE_ENVIRONMENT_TEXTURE);
refreshConfig(lightingMode);
});
瞭解更多詳情>>
訪問華為AR Engine 官網,瞭解更多相關內容
華為AR Engine開源倉庫地址:GitHub 、Gitee
訪問華為開發者聯盟官網,瞭解更多相關內容
獲取開髮指導文檔
關註我們,第一時間瞭解 HMS Core 最新技術資訊~