华为机器学习-图像分割

记得以前,经常拍大头贴和寸照,要去专门的照相馆,先是让你站在一个红色或者蓝色的幕布前进行拍照,然后就去电脑上把刚刚拍的照片背景在进行修饰,最后再打印出来。其实这都没什么,最主要的是难以忍受他们拍的照片~~

我们肯定想的是能够自己拍照,然后自己制作一个好看的寸照,但是这里面涉及到一个人像和背景分离的问题。但幸好的是,已经有很多AI网站已经帮我们处理了,我们只需要使用即可,这里我们使用华为的图像分割

可以通过打开 HMS Core 图像分割 网站去了解具体信息

准备

在使用华为的图像分割之前需要做好准备:

流程

这里以Android进行演示图像分隔的使用方法,大概有以下几个方面的内容。

初始化

初始化图像分割服务ML Kit

1
2
3
4
5
6
MLImageSegmentationSetting setting = new MLImageSegmentationSetting.Factory()
.setExact(false)
.setAnalyzerType(MLImageSegmentationSetting.BODY_SEG)
.setScene(MLImageSegmentationScene.FOREGROUND_ONLY)
.create();
analyzer = MLAnalyzerFactory.getInstance().getImageSegmentationAnalyzer(setting);

这里需要注意几个参数设置:

  • setExact - 设置分割精细模式,true为精细分割模式,false为速度优先分割模式

  • setAnalyzerType - 设置分割模式,目前有三种模式:

    • BODY_SEG - 人像分割模式
    • IMAGE_SEG - 图像分隔模式
    • HAIR_SEG - 头发分隔模式
  • setScene - 设置返回结果类型:

    • MLImageSegmentationScene.ALL - 返回所有分割结果,包括:像素级标记信息、背景透明的人像图和人像为白色,背景为黑色的灰度图以及被分割的原图。
    • MLImageSegmentationScene.MASK_ONLY - 只返回像素级标记信息和被分割的原图
    • MLImageSegmentationScene.FOREGROUND_ONLY - 只返回背景透明的人像图和被分割的原图
    • MLImageSegmentationScene.GRAYSCALE_ONLY - 只返回人像为白色,背景为黑色的灰度图和被分割的原图

分割

将拍摄的照片、图像交给图像分割服务处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MLFrame frame = new MLFrame.Creator().setBitmap(mScaleBitmap).create();

// 创建一个task,处理图像分割检测器返回的结果。
Task<MLImageSegmentation> task = analyzer.asyncAnalyseFrame(frame);
// 异步处理图像分割检测器返回结果。
// 检测失败处理。
task.addOnSuccessListener(segmentation -> {
// 检测成功处理。
if (segmentation != null) {
mForegroundBitmap = segmentation.foreground;
colorIndex = 0;
mixtureBitmap();
}
}).addOnFailureListener(Throwable::printStackTrace);

如上大概就是简单的几步:

  • 创建一个人像检测的MLFrame对象frame
  • 开启一个异步任务去处理分割
  • 监听分割成功或失败

换背景

给分割出来的人像添加背景

1
2
3
4
5
6
7
8
9
10
11
mViewBinding.inchImage.setDrawingCacheEnabled(true);
// 生成背景图
GradientDrawable drawable = new GradientDrawable();
drawable.setColor(ResourceUtils.getColor(InchActivity.this, colors.get(colorIndex)));
// 设置背景和前景图
mViewBinding.inchImage.setBackground(drawable);
mViewBinding.inchImage.setImageBitmap(mForegroundBitmap);
// 获取合成图片
mMixtureBitmap = mViewBinding.inchImage.getDrawingCache();

mViewBinding.inchImage.setDrawingCacheEnabled(false);

这样就完成了给一个人像换背景

图像分隔不光支持人像分割,还支持

  • 头发分割
  • 视频流分割(仅人像分割模型包支持)

感兴趣的童鞋可以去尝试处理一下。