MLKitSegmenter 拓展:人像分割(抠图 / 换背景 / 背景虚化)

« 返回首页

logo MLKitSegmenter 拓展

把照片里的人和背景分开,然后:抠出人像(背景透明)、换成纯色背景、换成另一张图、把背景虚化。

为什么选它:

  • 完全离线。模型随 .aix 打包,设备不需要 Google Play 服务,断网也能用。
  • 只给成品,不给中间产物。ML Kit 原始输出是一张「每个像素属于人像的置信度」浮点图, 在 App Inventor 里几乎没法用。本拓展直接输出 PNG 文件并返回路径, 可以直接给「图像」组件显示、「分享」组件发送、「文件」组件读取。
  • 四个方法覆盖绝大多数需求,不用自己算像素。

常用场景:证件照换底色、人像贴纸、朋友圈风格的背景虚化、把自己”放”到别的风景里。

  • .aix 拓展下载:

cn.fun123.MLKit.Segmenter.aix


快速上手

一、证件照换底色(最常见的需求)

设计器里放一个 MLKitSegmenter、一个「图像选择器」、一个「图像」组件。

when 图像选择器1.AfterPicking() {
  标签1.Text = "处理中…"
  Segmenter1.ReplaceBackgroundWithColor(图像选择器1.Selection, -16776961)
}
when Segmenter1.GotResult(imagePath, width, height) {
  图像1.Picture = imagePath
  标签1.Text = join("完成 ", width, "×", height)
}
when Segmenter1.SegmentFailed(operation, errorMessage) {
  标签1.Text = errorMessage
}

颜色参数直接用颜色块接上去最方便(示例里的数字是蓝色的 ARGB 值)。

二、抠出人像(背景透明)

when 按钮_抠图.Click() {
  Segmenter1.ExtractPerson(图像选择器1.Selection)
}

输出是带透明通道的 PNG,可以叠在别的图上。

三、背景虚化

when 按钮_虚化.Click() {
  Segmenter1.BlurBackground(图像选择器1.Selection, 18)
}

radius 建议 8~25。太大不仅慢,效果也会糊成一团。

四、换成另一张图片当背景

when 按钮_替换.Click() {
  Segmenter1.ReplaceBackgroundWithImage(图像选择器1.Selection, "beach.jpg")
}

背景图会被自动缩放到与原图一样大。beach.jpg 可以是素材文件名,也可以是设备上的路径。

五、边缘不理想时调阈值

when 滑动条_阈值.PositionChanged(thumbPosition) {
  Segmenter1.Threshold = thumbPosition
  标签_数值.Text = join("阈值 ", thumbPosition)
}

六、清理生成的文件

global removed = 0

when 按钮_清除.Click() {
  removed = Segmenter1.ClearCache()
  标签1.Text = join("已清理 ", removed, " 个文件")
}

属性

Threshold
前景判定阈值,0~1,默认 0.5。 模型给每个像素一个「属于人像」的置信度,高于这个值就算人像。 调高更保守(头发、手指边缘可能被切掉);调低更宽松(可能带上一圈背景)。 边缘不理想时先调这个。
Busy
只读。是否正在处理。处理期间再次调用会触发 SegmentFailed。

事件

GotResult(imagePath,width,height)
处理完成。imagePath 是生成的 PNG 文件路径,可以直接给「图像」组件的 图片 属性, 或用「分享」组件的 分享文件 发送。width/height 是结果图尺寸。
SegmentFailed(operation,errorMessage)
处理失败。operation 是出错的方法名,便于定位。

方法

ExtractPerson(image)
抠出人像,背景变透明,输出 PNG。 image 可以是素材文件名、设备路径、file:// 或 content:// 地址。
ReplaceBackgroundWithColor(image,color)
把背景换成纯色。color 直接接颜色块最方便。
ReplaceBackgroundWithImage(image,backgroundImage)
把背景换成另一张图片。背景图自动缩放到与原图同尺寸。
BlurBackground(image,radius)
把背景虚化,人像保持清晰。radius 建议 8~25(上限 40)。
ClearCache()
清空本拓展生成的所有图片,返回删除的文件个数。

文件放在哪里

结果存在应用私有的外部目录下的 MLKitSegmenter/ 子目录,形如:

/storage/emulated/0/Android/data/<你的包名>/files/MLKitSegmenter/seg_1751234567890.png

好处:不需要存储权限、卸载 App 自动清理、路径可以直接给其它组件用。 文件名带毫秒时间戳,多次处理不会互相覆盖。记得适时调用 ClearCache,否则会一直堆积。


运行环境:AI 伴侣联机需要 Android 11 及以上

本拓展的识别模型放在依赖库自带的 assets 里,AI 伴侣联机调试要把它挂进 AssetManager,用的是 Android 11(API 30)才有的 ResourcesLoader —— 这是系统提供的 唯一公开办法,更低版本没有等价 API。所以:

运行方式 Android 6 ~ 10 Android 11 及以上
打包 APK ✅ 正常 ✅ 正常
AI 伴侣联机 ❌ 模型加载不了 ✅ 正常

打包 APK 之所以不受限制,是因为模型在编译时就被并进了 APK 的 assets,装到手机上 就是 App 自己的资源,与系统版本无关。伴侣的 APK 是提前编好装在手机上的,运行时没法 往自己已安装的包里加文件,只能靠系统的运行时挂载 API。

低版本设备上想验证功能,直接打包 APK 测即可;要用伴侣边改边调,请换 Android 11+ 的设备。

常见问题

只对人有效吗? 是的。这是 ML Kit 的 selfie(自拍)分割模型,专门训练用来分离人像和背景。 猫狗、物品、风景都不行 —— 要抠任意物体需要别的方案(本拓展做不到)。

边缘有毛刺 / 头发被切掉了。 先调 阈值:切掉太多就调低(如 0.3),带上背景就调高(如 0.7)。 另外这个模型对半身近景效果最好;全身远景、多个人、复杂发型都会明显变差。

为什么输出一定是 PNG? 抠图结果带透明通道,JPG 不支持透明会把透明区域压成黑色。所以四个方法统一输出 PNG。

处理大图很慢。 合成是逐像素运算,耗时与像素数成正比。虚化尤其重(radius 越大越慢)。 建议先把图缩到 1080P 左右再处理。本拓展已经把识别和合成都放在后台线程,不会卡界面。

能处理摄像头实时画面吗? 本拓展是单张图片模式,不适合实时。实时人像分割需要每帧处理 + 预览合成, 性能和实现复杂度都是另一个量级,不在本拓展范围内。

文档反馈