关于移动应用开发:5分钟给商品建立3D模型我是如何做到的

​发问:3D模型展现商品不香吗?
香!当然香。

当3D建模成为电商网购利用的左膀右臂,大同小异的产品首图就有了面目一新的出现风貌!商品3D模型360°全方位展现,细节更丰盛,辅以线上虚构“看、试、穿、戴”,提供靠近实物的差异化网购体验,助力高效晋升用户转化。

3D模型虽漂亮,然而,时下成果佳的3D建模技术因其较高的老本而使得让宽广需求者望而生畏。

  • 技术门槛高:业余人员手工制作,师带徒传承,学习老本高;
  • 工夫老本高:实现一个简略物体的低模模型,工作量以小时起步,高模模型耗时更长。
  • 消耗高:单个商品的业余建模老本高,平均价格达到上千元,简单模型更贵;

华为挪动服务最新凋谢的3D建模服务,助力轻松建模。用户只需应用一般的RGB相机,通过拍摄物体的不同角度图像,便可实现物体的3D几何模型和纹理的自动化生成,为利用提供3D模型构建、预览等能力。如在电商鞋子展现的场景,您能够通过此能力主动生成鞋子3D模型,用于3D展现,用户可360°随心放大或放大商品,为用户提供差异化的购买体验。  

成果示例

技术计划

3D物体建模能力由端云协同实现,端侧负责采集RGB图像,通过盘绕物体一周拍摄多张图像,从而获取物体的不同角度图像,拍摄结束后上传至云端实现3D物体建模。云端建模的流程及关键技术包含指标检测宰割、特色检测与匹配、稠密点云计算、浓密点云计算以及纹理重建等模块。最终输入业界通用的3D模型格局(.obj文件),面片数约40K~200K。

开发筹备

1.配置集成的SDK包

在利用的build.gradle文件中,dependencies内增加3D建模服务的SDK依赖

// 3D Modeling Kit SDK
implementation 'com.huawei.hms:modeling3d-object-reconstruct:1.0.0.300'

2.配置AndroidManifest.xml

关上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、配置存储权限申请

在MainActivity的onCreate()办法中,首先对手机存储的读取权限进行判断,如果未获取权限,则通过requestPermissions进行申请。

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());

注意事项

  1. 反对的物体纹理需丰盛(纹理特色显著)、不反光、不通明/不半透明、尺寸中等、刚体,典型物体包含:商品类(毛绒玩具、包、鞋子)、 家具类(沙发)、文物类(青铜器、石器、木器)等。
  2. 反对物体尺寸15cm15cm15cm < 物体尺寸 < 1.5m1.5m1.5m(尺寸越大建模工夫越长)。
    不反对人脸、人体建模。
  3. 图像拍摄时需将繁多的采集物体静置于纯色立体上,光照要柔和、防止灯光过暗,拍摄时要对焦,笼罩平均而足够的多视角,含仰望、平视、仰视(50张以上),相机挪动尽可能迟缓,所有角度照片尽可能统一,同时全过程采集中物体屏占比尽量大且残缺,要求尽量保障拍摄无虚焦、静止含糊、抖动含糊。
  4. 超具体代码教程奉上,诚邀敬爱的开发者小伙伴们亲自实际一把,再为你身边的物品建个模~
  • 拜访华为3D建模服务官网,理解更多相干内容
  • 获取华为3D建模开发领导文档
  • 华为HMS Core官方论坛
  • 华为3D建模开源仓库地址:GitHub、Gitee
  • 解决集成问题请到Stack Overflow

点击右上角头像右方的关注,第一工夫理解HMS Core最新技术~

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元

阿里云限时活动-1核2G-1M带宽-40-100G ,特惠价87.12元/年(原价1234.2元/年,可以直接买3年),速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

You may also like...

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据