飞道的博客

过年拍照独缺你?用机器学习服务一秒生成全家福

404人阅读  评论(0)

“妈,今年我就不回家过年啦。”

给正在老家热火朝天备年货的老妈打完电话,难掩失落。牛年春节注定与众不同,没有老妈催我起床大扫除,不能在年饭桌上吃上一口朝思慕想的“妈妈牌”饺子,贴春联的任务今年也不能认领……那些年月里微小而温情的事儿,今年都得在回忆里复习。心里尤为惦念的,还有每年过年一家子团聚时必不可少的全家福。好在,今年虽然不能相聚餐桌前,大家在全家福里依然能相聚。

如果今年你也不回家过年,教你一招,借助华为机器学习服务,让身在异地的家人们,完成一张不缺席的温暖全家福。

合成全家福功能演示:

原理解释

应用华为机器学习服务中的图像分割能力,把照片中人像元素的部分从图像整体中分割出来,再将背景替换为家人合照的背景。

全家福生成开发步骤详解

一、开发准备

1. 配置华为Maven仓地址。


  
  1. buildscript {
  2. repositories {
  3. google()
  4. jcenter()
  5. maven {url 'https://developer.huawei.com/repo/'}
  6. }
  7. dependencies {
  8. ...
  9. classpath 'com.huawei.agconnect:agcp:1.4.1.300'
  10. }
  11. }
  12. allprojects {
  13. repositories {
  14. google()
  15. jcenter()
  16. maven {url 'https://developer.huawei.com/repo/'}
  17. }
  18. }

2. 添加编译SDK依赖


  
  1. dependencies {
  2. // 引入基础SDK
  3. implementation 'com.huawei.hms:ml-computer-vision-segmentation:2.1.0.301'
  4. // 引入人像分割模型包
  5. implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:2.1.0.303'
  6. }

3. 在AndroidManifest.xml中添加权限


  
  1. // 使用存储权限
  2. <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />

二、具体开发步骤

1. 动态权限申请


  
  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. if (!allPermissionsGranted()) {
  6. getRuntimePermissions();
  7. }
  8. }
  9. private boolean allPermissionsGranted() {
  10. for ( String permission : getRequiredPermissions()) {
  11. if (!isPermissionGranted( this, permission)) {
  12. return false;
  13. }
  14. }
  15. return true;
  16. }
  17. private void getRuntimePermissions() {
  18. List< String> allNeededPermissions = new ArrayList<>();
  19. for ( String permission : getRequiredPermissions()) {
  20. if (!isPermissionGranted( this, permission)) {
  21. allNeededPermissions.add(permission);
  22. }
  23. }
  24. if (!allNeededPermissions.isEmpty()) {
  25. ActivityCompat.requestPermissions(
  26. this, allNeededPermissions.toArray( new String[ 0]), PERMISSION_REQUESTS);
  27. }
  28. }
  29. private static boolean isPermissionGranted(Context context, String permission) {
  30. if (ContextCompat.checkSelfPermission(context, permission)
  31. == PackageManager.PERMISSION_GRANTED) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. private String[] getRequiredPermissions() {
  37. try {
  38. PackageInfo info =
  39. this.getPackageManager()
  40. .getPackageInfo( this.getPackageName(), PackageManager.GET_PERMISSIONS);
  41. String[] ps = info.requestedPermissions;
  42. if (ps != null && ps.length > 0) {
  43. return ps;
  44. } else {
  45. return new String[ 0];
  46. }
  47. } catch (RuntimeException e) {
  48. throw e;
  49. } catch (Exception e) {
  50. return new String[ 0];
  51. }
  52. }

2. 创建图片分割检测器


  
  1. MLImageSegmentationSetting setting = new MLImageSegmentationSetting.Factory()
  2. // 设置为人像分割
  3. .setAnalyzerType(MLImageSegmentationSetting.BODY_SEG)
  4. .create();
  5. this.analyzer = MLAnalyzerFactory.getInstance().getImageSegmentationAnalyzer(setting);

3. 通过android.graphics.Bitmap创建“MLFrame”对象用于分析器检测图片

MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();

4. 调用“asyncAnalyseFrame ”方法进行图像分割


  
  1. // 创建一个task,处理图像分割检测器返回的结果。
  2. Task<MLImageSegmentation> task = this.analyzer.asyncAnalyseFrame(mlFrame);
  3. // 异步处理图像分割检测器返回的结果。
  4. task.addOnSuccessListener( new OnSuccessListener<MLImageSegmentation>() {
  5. @Override
  6. public void onSuccess(MLImageSegmentation mlImageSegmentationResults) {.
  7. if (mlImageSegmentationResults != null) {
  8. //获得从图片中分割出的人像前景图
  9. foreground = mlImageSegmentationResults.getForeground();
  10. preview.setImageBitmap(MainActivity. this.foreground);
  11. }
  12. }
  13. }).addOnFailureListener( new OnFailureListener() {
  14. @Override
  15. public void onFailure(Exception e) {
  16. return;
  17. }
  18. });

5. 更换图片背景


  
  1. // 从相册中获取图片
  2. backgroundBitmap = Utils.loadFromPath( this, id, targetedSize.first, targetedSize.second);
  3. BitmapDrawable drawable = new BitmapDrawable(backgroundBitmap);
  4. preview.setBackground(drawable);
  5. preview.setImageBitmap( this.foreground);

根据以上的步骤,就可以实现这个好玩的全家福生成功能了,就地过年不能团圆,全家福依然“缺一不可”。你还可以在此功能基础上做很多有意思的拓展,比如用华为图像服务给全家福添加一些小贴纸,让照片年味更足、更有趣味。

 

 

>>访问华为开发者联盟官网,了解更多相关内容

>>获取开发指导文档

>>华为移动服务开源仓库地址:GitHubGitee

关注我们,第一时间了解华为移动服务最新技术资讯~

 


转载:https://blog.csdn.net/HUAWEI_HMSCore/article/details/113778873
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场