提問:3D模型展現商品不香嗎?
香!固然香。java
當3D建模成爲電商網購應用的左膀右臂,大同小異的產品首圖就有了面目一新的呈現面貌!商品3D模型360°全方位展現,細節更豐富,輔以線上虛擬「看、試、穿、戴」,提供接近實物的差別化網購體驗,助力高效提高用戶轉化。
3D模型雖美麗,然而,時下效果佳的3D建模技術因其較高的成本而使得讓廣大需求者望而卻步。android
- 技術門檻高:專業人員手工製做,師帶徒傳承,學習成本高;
- 時間成本高:完成一個簡單物體的低模模型,工做量以小時起步,高模模型耗時更長。
- 耗費高:單個商品的專業建模成本高,平均價格達到上千元,複雜模型更貴;
華爲移動服務最新開放的3D建模服務,助力輕鬆建模。用戶只需使用普通的RGB相機,經過拍攝物體的不一樣角度圖像,即可實現物體的3D幾何模型和紋理的自動化生成,爲應用提供3D模型構建、預覽等能力。如在電商鞋子展現的場景,您能夠經過此能力自動生成鞋子3D模型,用於3D展現,用戶可360°隨心放大或縮小商品,爲用戶提供差別化的購買體驗。 git
效果示例
技術方案
3D物體建模能力由端雲協同完成,端側負責採集RGB圖像,經過環繞物體一週拍攝多張圖像,從而獲取物體的不一樣角度圖像,拍攝完畢後上傳至雲端實現3D物體建模。雲端建模的流程及關鍵技術包括目標檢測分割、特徵檢測與匹配、稀疏點雲計算、稠密點雲計算以及紋理重建等模塊。最終輸出業界通用的3D模型格式(.obj文件),面片數約40K~200K。github
開發準備
1. 配置集成的SDK包服務器
在應用的build.gradle文件中,dependencies內添加3D建模服務的SDK依賴app
// 3D Modeling Kit SDK implementation 'com.huawei.hms:modeling3d-object-reconstruct:1.0.0.300'
2. 配置AndroidManifest.xmlide
打開main文件夾中的AndroidManifest.xml文件,能夠根據場景和使用須要,配置讀取和寫入手機存儲以及相機權限,在<application>前添加學習
<!-- 往sdcard中寫入數據的權限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 使用相機的權限 --> <uses-permission android:name="android.permission.CAMERA" />
開發步驟
1. 配置存儲權限申請gradle
在MainActivity的onCreate()方法中,首先對手機存儲的讀取權限進行判斷,若是未獲取權限,則經過requestPermissions進行申請。ui
if (EasyPermissions.hasPermissions(MainActivity.this, PERMISSIONS)) { Log.i(TAG, "Permissions OK"); } else { EasyPermissions.requestPermissions(MainActivity.this, "To use this app, you need to enable the permission.", RC_CAMERA_AND_EXTERNAL_STORAGE, PERMISSIONS); }
檢查權限申請的結果,若是有權限初始化界面,沒有權限提示用戶開啓。
@Override public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) { Log.i(TAG, "permissions = " + perms); if (requestCode == RC_CAMERA_AND_EXTERNAL_STORAGE && PERMISSIONS.length == perms.size()) { initView(); initListener(); } } @Override public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) { if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { new AppSettingsDialog.Builder(this) .setRequestCode(RC_CAMERA_AND_EXTERNAL_STORAGE) .setRationale("To use this app, you need to enable the permission.") .setTitle("Insufficient permissions") .build() .show(); } }
2. 新建3D物體建模配置器
// Initializing the RGB Mode Modeling3dReconstructSetting setting = new Modeling3dReconstructSetting.Factory() .setReconstructMode(Modeling3dReconstructConstants.ReconstructMode.PICTURE) .create();
3. 新建3D物體建模引擎並初始化任務
調用Modeling3dReconstructEngine的getInstance()接口,傳入當前應用的上下文建立3D建模引擎實例
// Initializing the Rebuild Engine modeling3dReconstructEngine = Modeling3dReconstructEngine.getInstance(mContext);
使用3D物體建模引擎初始化任務
// Creating a Rebuilding Task modeling3dReconstructInitResult = modeling3dReconstructEngine.initTask(setting); // Getting a Rebuilding Task String taskId = modeling3dReconstructInitResult.getTaskId();
4. 新建上傳監聽器回調,處理拍攝的物體上傳結果
新建上傳回調接口,您能夠在該回調接口中編寫上傳成功或失敗後須要執行的操做。
// Re-establishing the upload callback listener private final Modeling3dReconstructUploadListener uploadListener = new Modeling3dReconstructUploadListener() { @Override public void onUploadProgress(String taskId, double progress, Object ext) { // Upload progress } @Override public void onResult(String taskId, Modeling3dReconstructUploadResult result, Object ext) { if (result.isComplete()) { isUpload = true; ScanActivity.this.runOnUiThread(new Runnable() { @Override public void run() { progressCustomDialog.dismiss(); Toast.makeText(ScanActivity.this, getString(R.string.upload_text_success), Toast.LENGTH_SHORT).show(); } }); TaskInfoAppDbUtils.updateTaskIdAndStatusByPath(new Constants(ScanActivity.this).getCaptureImageFile() + manager.getSurfaceViewCallback().getCreateTime(), taskId, 1); } } @Override public void onError(String taskId, int errorCode, String message) { isUpload = false; runOnUiThread(new Runnable() { @Override public void run() { progressCustomDialog.dismiss(); Toast.makeText(ScanActivity.this, "Upload failed." + message, Toast.LENGTH_SHORT).show(); LogUtil.e("taskid" + taskId + "errorCode: " + errorCode + " errorMessage: " + message); } }); } };
5. 3D物體建模引擎設置上傳監聽器,上傳採集的圖片數據
上傳回調接口傳入3D建模引擎並調用uploadFile()接口,傳入第三步獲取到的任務ID以及須要上傳的圖片路徑,將數據上傳到雲端服務器。
// Set the callBack to engine. modeling3dReconstructEngine.setReconstructUploadListener(uploadListener); // Executing a Rebuild Upload Task modeling3dReconstructEngine.uploadFile(taskId, filePath);
6. 查詢3D物體建模任務狀態
調用Modeling3dReconstructTaskUtils的getInstance接口建立3D建模任務處理實例,一樣是傳入當前應用的上下文做爲入參。
// Initialize the reconstruction task tool class. modeling3dReconstructTaskUtils = Modeling3dReconstructTaskUtils.getInstance(Modeling3dDemo.getApp());
調用任務處理實例的queryTask接口查詢當前建模任務的進度。
// Query the reconstruction task execution result. The options are as follows: 0: To be uploaded; 1: Generating; 3: Completed; 4: Failed. Modeling3dReconstructQueryResult queryResult = modeling3dReconstructTaskUtils.queryTask(task.getTaskId());
7. 新建下載監聽器回調,用於處理3D物體建模模型文件的下載結果
新建下載回調接口,您能夠在該回調接口中編寫下載成功或失敗後須要執行的操做
// Re-establishing the download callback listener private Modeling3dReconstructDownloadListener modeling3dReconstructDownloadListener = new Modeling3dReconstructDownloadListener() { @Override public void onDownloadProgress(String taskId, double progress, Object ext) { ((Activity) mContext).runOnUiThread(new Runnable() { @Override public void run() { dialog.show(); } }); } @Override public void onResult(String taskId, Modeling3dReconstructDownloadResult result, Object ext) { ((Activity) mContext).runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getContext(), "Download complete", Toast.LENGTH_SHORT).show(); TaskInfoAppDbUtils.updateDownloadByTaskId(taskId, 1); dialog.dismiss(); } }); } @Override public void onError(String taskId, int errorCode, String message) { LogUtil.e(taskId + " <---> " + errorCode + message); ((Activity) mContext).runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getContext(), "Download failed." + message, Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); } };
8. 3D物體建模引擎加入下載監聽,下載重建成功的模型文件
將下載回調接口傳入3D建模引擎並調用downloadModel接口,傳入第三步中獲取的任務id和保存路徑進行模型文件的下載。
// Setting Rebuild Download Listening modeling3dReconstructEngine.setReconstructDownloadListener(modeling3dReconstructDownloadListener); // Executing a Rebuild Download Task modeling3dReconstructEngine.downloadModel(appDb.getTaskId(), appDb.getFileSavePath());
注意事項
- 支持的物體紋理需豐富(紋理特徵明顯)、不反光、不透明/不半透明、尺寸中等、剛體,典型物體包括:商品類(毛絨玩具、包、鞋子)、 傢俱類(沙發)、文物類(青銅器、石器、木器)等。
- 支持物體尺寸15cm*15cm*15cm < 物體尺寸 < 1.5m*1.5m*1.5m(尺寸越大建模時間越長)。
- 不支持人臉、人體建模。
- 圖像拍攝時需將單一的採集物體靜置於純色平面上,光照要柔和、避免燈光過暗,拍攝時要對焦,覆蓋均勻而足夠的多視角,含仰視、平視、俯視(50張以上),相機移動儘量緩慢,全部角度照片儘量一致,同時全過程採集中物體屏佔比儘可能大且完整,要求儘可能保證拍攝無虛焦、運動模糊、抖動模糊。
超詳細代碼教程奉上,誠邀親愛的開發者小夥伴們親自實踐一把,再爲你身邊的物品建個模!
>>訪問華爲3D建模服務官網,瞭解更多相關內容
>>獲取華爲3D建模開發指導文檔
>>華爲3D建模開源倉庫地址:GitHub、Gitee
>>華爲HMS Core官方論壇
>>解決集成問題請到Stack Overflow
點擊右上角頭像右方的關注,第一時間瞭解HMS Core最新技術~