简介
华为HMS ML Kit提供拍照购服务,用户通过拍摄商品图片,在预先建立的商品图片库中在线检索同款或相似商品,返回相似商品ID和相关信息。
应用场景
-
使用摄像头设备从开发的购物APP当中捕捉产品图像。
- 在循环视图当中显示返还的产品列表。
开发准备
-
推荐使用Java JDK 1.8或者更高版本。
-
推荐使用Android Studio。
-
搭载HMS Core4.0.0.300 或者更高版本的华为安卓设备。
-
在开发APP之前,你需要注册华为开发者,账号注册。
- 集成AppGallery Connect SDK, 请访问AppGallery Connect 服务入门指南。
开发
-
在Manage APIs中启用ML Kit, 可参考开通服务。
- 在app-level bulid.gradle 中集成以下依赖项。
// Import the product visual search SDK.
implementation 'com.huawei.hms:ml-computer-vision-cloud:2.0.1.300'
- 在app.gradle文件的顶部添加agc插件。
apply plugin: 'com.huawei.agconnect'
- 在清单中添加以下权限。
-
摄像头权限android.permission.CAMERA: 从摄像头中获取实时图像或视频。
-
网络连接权限 android.permission.INTERNET:访问互联网上的云服务。
-
存储写权限android.permission.WRITE_EXTERNAL_STORAGE: 升级算法版本。
- 存储读权限android.permission.READ_EXTERNAL_STORAGE: 读取存储在设备上的照片。
- 实时请求相机权限
private void requestCameraPermission() {
final String[] permissions = new String[] {Manifest.permission.CAMERA};
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, permissions, this.CAMERA_PERMISSION_CODE);
return;
}
}
- 在Application class 中添加以下代码
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MLApplication.getInstance().setApiKey("API KEY");
}
}
可以从AGC或者集成的agconnect-services.json获得API key。
- 为拍照购物创建一个分析器。
private void initializeProductVisionSearch() {
MLRemoteProductVisionSearchAnalyzerSetting settings = new MLRemoteProductVisionSearchAnalyzerSetting.Factory()
// Set the maximum number of products that can be returned.
.setLargestNumOfReturns(16)
// Set the product set ID. (Contact mlkit@huawei.com to obtain the configuration guide.)
// .setProductSetId(productSetId)
// Set the region.
.setRegion(MLRemoteProductVisionSearchAnalyzerSetting.REGION_DR_CHINA)
.create();
analyzer
= MLAnalyzerFactory.getInstance().getRemoteProductVisionSearchAnalyzer(settings);
}
- 从相机中捕捉图像。
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQ_CAMERA_CODE);
- 一旦图像被捕捉,将执行onActivityResult() method。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult");
if(requestCode == 101) {
if (resultCode == RESULT_OK) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
if (bitmap != null) {
// Create an MLFrame object using the bitmap, which is the image data in bitmap format.
MLFrame mlFrame = new MLFrame.Creator().setBitmap(bitmap).create();
mlImageDetection(mlFrame);
}
}
}
}
private void mlImageDetection(MLFrame mlFrame) {
Task> task = analyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener>() {
public void onSuccess(List products) {
// Processing logic for detection success.
displaySuccess(products);
}})
.addOnFailureListener(new OnFailureListener() {
public void onFailure(Exception e) {
// Processing logic for detection failure.
// Recognition failure.
try {
MLException mlException = (MLException)e;
// Obtain the result code. You can process the result code and customize respective messages displayed to users.
int errorCode = mlException.getErrCode();
// Obtain the error information. You can quickly locate the fault based on the result code.
String errorMessage = mlException.getMessage();
} catch (Exception error) {
// Handle the conversion error.
}
}
});
}
private void displaySuccess(List productVisionSearchList) {
List productImageList = new ArrayList();
String prodcutType = "";
for (MLProductVisionSearch productVisionSearch : productVisionSearchList) {
Log.d(TAG, "type: " + productVisionSearch.getType() );
prodcutType = productVisionSearch.getType();
for (MLVisionSearchProduct product : productVisionSearch.getProductList()) {
productImageList.addAll(product.getImageList());
Log.d(TAG, "custom content: " + product.getCustomContent() );
}
}
StringBuffer buffer = new StringBuffer();
for (MLVisionSearchProductImage productImage : productImageList) {
String str = "ProductID: " + productImage.getProductId() + "
ImageID: " + productImage.getImageId() + "
Possibility: " + productImage.getPossibility();
buffer.append(str);
buffer.append("
");
}
Log.d(TAG , "display success: " + buffer.toString());
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_fragment_container, new SearchResultFragment(productImageList, prodcutType ));
transaction.commit();
}
onSuccess()回调将给我们MLProductVisionSearch.getType()对象列表,可用于获取每个产品的ID和图像URL。我们还可以使用productVisionSearch.getType()获取产品类型,gatType()返回可映射的编号。
在撰写本文时,产品类型是:
- 我们可以使用以下代码实现产品类型映射。
private String getProductType(String type) {
switch(type) {
case "0":
return "Others";
case "1":
return "Clothing";
case "2":
return "Shoes";
case "3":
return "Bags";
case "4":
return "Digital & Home appliances";
case "5":
return "Household Products";
case "6":
return "Toys";
case "7":
return "Cosmetics";
case "8":
return "Accessories";
case "9":
return "Food";
}
return "Others";
}
- 从MLVisionSearchProductImage获取产品ID和图像URL。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MLVisionSearchProductImage mlProductVisionSearch = productVisionSearchList.get(position);
holder.tvTitle.setText(mlProductVisionSearch.getProductId());
Glide.with(context)
.load(mlProductVisionSearch.getImageId())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.imageView);
}
Demo
欲了解更多详情,请参阅:
参与开发者讨论请到Reddit社区
下载demo和示例代码请到Github
解决集成问题请到Stack Overflow
原文链接:
https://developer.huawei.com/consumer/cn/forum/topic/0201434135672410084?fid=18
作者:胡椒