一键抠图1:Python实现人像抠图 (Portrait Matting)

2023-12-05 21:28

本文主要是介绍一键抠图1:Python实现人像抠图 (Portrait Matting),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一键抠图1:Python实现人像抠图 (Portrait Matting)

目录

一键抠图1:Python实现人像抠图 (Portrait Matting)

1. 项目介绍

2. 抠图算法

3. Matting数据集

4. MODNet模型

 (1) 项目安装

 (2) 数据集说明

 (3) MODNet模型

5. Demo测试效果 

6. 源码下载(Python)

7.人像抠图C++版本

8.人像抠图Android版本


1. 项目介绍

抠图算法(英文中,一般称为Matting)有多种实现方式,一种是基于辅助信息输入的,加入一些先验信息(如Trimap,背景图,用户交互信息,深度等信息)提供抠图效果,如比较经典的Deep Image Matting和Semantic Image Matting这些算法加入Trimap; Background Matting算法需要提供背景图等;另一种是无需辅助信息,输入RGB图像,直接预测matte的方法,其效果相对第一种方法,会差很多。而对Portrait Matting(人像抠图),现在有很多方案在无需Trimap条件下,也可以获得不错的抠图效果,比如MODNet,Fast Deep Matting等算法,真正实现一健抠图的效果。

本篇博客是一键抠图项目系列之《Python实现人像抠图 (Portrait Matting)》,项目将在MODNet人像抠图算法基础上进行模型压缩和优化,开发一个效果相当不错的Matting算法,可以达到头发细致级别的人像抠图效果,为了方便后续模型工程化和Android平台部署,项目提供高精度版本人像抠图和轻量化快速版人像抠图,并提供Python/C++/Android多个版本;

尊重原创,转载请注明出处】https://blog.csdn.net/guyuealian/article/details/134784803

Android Demo APP下载地址:https://download.csdn.net/download/guyuealian/63228759

先展示一下一键人像抠图效果:


更多项目《一键抠图》系列文章请参考:

  1. 一键抠图1:Python实现人像抠图 (Portrait Matting)https://blog.csdn.net/guyuealian/article/details/134784803
  2. 一键抠图2:C/C++实现人像抠图 (Portrait Matting)https://blog.csdn.net/guyuealian/article/details/134790532
  3. 一键抠图3:Android实现人像抠图 (Portrait Matting)https://blog.csdn.net/guyuealian/article/details/134801795


2. 抠图算法

基于深度学习的Matting分为两大类:

  • 一种是基于辅助信息输入。即除了原图和标注图像外,还需要输入其他的信息辅助预测。最常见的辅助信息是Trimap,即将图片划分为前景,背景及过度区域三部分。另外也有以背景或交互点作为辅助信息。

  • 一种是不依赖任何辅助信息,直接对Alpha进行预测。如本博客复现的MODNet

第一种方法,需要加入辅助信息,而辅助信息一般较难获取,这也限制其应用,为了提升Matting的应用性,针对Portrait Matting领域MODNet摒弃了辅助信息,直接实现Alpha预测,实现了实时Matting,极大提升了基于深度学习Matting的应用价值。

更多抠图算法(Matting),请参考我的一篇博客《图像抠图Image Matting算法调研》:

图像抠图Image Matting算法调研_image matting调研-CSDN博客文章浏览阅读4.3k次,点赞8次,收藏68次。1.Trimap和StrokesTrimap和Strokes都是一种静态图像抠图算法,现有静态图像抠图算法均需对给定图像添加手工标记以增加抠图问题的额外约束。Trimap,三元图,是对给定图像的一种粗略划分,即将给定图像划分为前景、背景和待求未知区域Strokes则采用涂鸦的方式在图像上随意标记前景和背景区域,剩余未标记部分则为待求的未知区域Trimap是最常用的先验知识,多数抠图算法采用了Trimap作为先验知识,顾名思义Trimap是一个三元图,每个像素取值为{0,128,..._image matting调研https://blog.csdn.net/guyuealian/article/details/119648686可能,有小伙伴搞不清楚分割(segmentation)和抠图(matting)有什么区别,我这里简单说明一下:

  •  分割(segmentation):从深度学习的角度来说,分割本质是像素级别的分类任务,其损失函数最简单的莫过于是交叉熵CrossEntropyLoss(当然也可以是Focal Loss,IOU Loss,Dice Loss等);对于前景和背景分割任务,输出Mask的每个像素要么是0,要么是1。如果拿去直接做图像融合,就很不自然,Mask边界很生硬,这时就需要使用抠图算法了
  •  抠图(matting): 而抠图本质是一种回归任务,其损失函数可以是MSE Loss,L1 Loss,L2 Loss等,对于前景和背景抠图任务,输出Mask的每个像素是0~1之间的连续值,可看作是对图像透明通道(Alpha)的回归预测。可以用公式表示为C = αF + (1-α)B ,其中α(不透明度)、F(前景色)和B(背景色),alpha是[0, 1]之间的连续值,可以理解为像素属于前景的概率。在人像分割任务中,alpha只能取0或1,而抠图任务中,alpha可取[0, 1]之间的连续值,
  • 本质上就是一句话:分割是分类任务,而抠图是回归任务。

3. Matting数据集

一些开源的matting数据集

数据集

说明

matting_human_datasets

  • 本数据集为目前已知最大的人像matting数据集,包含34427张图像和对应的matting结果图。
  • 数据集由北京玩星汇聚科技有限公司高质量标注,使用该数据集所训练的人像软分割模型已商用。
  • 数据集中的原始图片来源于Flickr、百度、淘宝。经过人脸检测和区域裁剪后生成了600*800的半身人像。
  • GitHub - aisegmentcn/matting_human_datasets: 人像matting数据集,包含34427张图像和对应的matting结果图。
  • PS:Matting比较粗糙,没有达到头发细致抠图;不过数据比较大,可以作为pretrained数据集使用

Deep Image Matting

  • Adobe Research论文《Deep Image Matting》提供的Matting Dataset。大约有455张图片,论文将MSCOCO和PASCAL VOC当做背景图,与455张图片进行合成后,大概有45500张训练图片和1000张测试图片
  • 论文地址:https://sites.google.com/view/deepimagematting
  • 项目地址:GitHub - Joker316701882/Deep-Image-Matting: This is tensorflow implementation for paper "Deep Image Matting"
  • PS:该数据集发邮箱给作者申请即可,一般作为通用物体Matting数据集,比较精细;如果用于人像抠图,需要自行把含有人的图片挑选出来

PPM-100

  • PPM-100 是论文 MODNet (Github | Arxiv) 中提出的一个人像抠图基准,它包含了100张来自Flickr的人像图片,具有以下特点:

  • 精细标注 - 所有图像都被仔细标注并检查。
  • 丰富多样 - 图像涵盖全身/半身人像和各种姿态。
  • 高分辨率 - 图像的分辨率介于1080P和4K之间。
  • 自然背景 - 所有图像都包含原始无替换的背景。
  • 项目地址:GitHub - ZHKKKe/PPM: A High-Quality Photograpy Portrait Matting Benchmark

PPM-100下载:https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.3/contrib/Matting

RealWorldPortrait-636

  • real-world portrait dataset
  • 项目地址:GitHub - yucornetto/MGMatting: This repository includes the official project of Mask Guided (MG) Matting, presented in our paper: Mask Guided Matting via Progressive Refinement Network

 Compsition-1k

  • 使用Deep Image Matting合成的数据集
  • 项目地址:GitHub - Yaoyi-Li/GCA-Matting: Official repository for Natural Image Matting via Guided Contextual Attention

HAttMatting

  • 项目地址:GitHub - yuhaoliu7456/CVPR2020-HAttMatting: Attention-Guided Hierarchical Structure Aggregation for Image Matting(CVPR2020)

 AM-2k

  • AM-2k contains 2,000 high-resolution natural animal images from 20 categories along with manually labeled alpha mattes. Some examples are shown as below, more can be viewed in the video demo (YouTube | bilibili | Google drive).

    AM-2k can be accessed from here (Google Drive | Baidu Wangpan (pw: 29r1)), please make sure that you have read this agreement before accessing the dataset. Please refer to the readme.txt in the dataset folder for more details.

  • 项目地址:GitHub - JizhiziLi/GFM: [IJCV 2022] Bridging Composite and Real: Towards End-to-end Deep Image Matting

BG-20k

  • BG-20k contains 20,000 high-resolution background images excluded salient objects, which can be used to help generate high quality synthetic data. Some examples are shown as below, more can be viewed in the video demo (YouTube | bilibili | Google drive).

    BG-20k can be accessed from here (Google Drive | Baidu Wangpan (pw: dffp)), please make sure that you have read this agreement before accessing the dataset. Please refer to the readme.txt in the dataset folder for more details.

  • 项目地址:GitHub - JizhiziLi/GFM: [IJCV 2022] Bridging Composite and Real: Towards End-to-end Deep Image Matting

VideoMatte240K

  • Background Matting V2 数据集

PhotoMatte85

其他的:

  • VideoMatte240K
  • PhotoMatte85
  • GitHub - thuyngch/Human-Segmentation-PyTorch: Human segmentation models, training/inference code, and trained weights, implemented in PyTorch
  • Automatic Portrait Segmentation for Image Stylization: 1800 images
  • Supervisely Person: 5711 images

4. MODNet模型

 (1) 项目安装

 整套工程项目基本结构如下:

 项目依赖python包请参考requirements.txt,使用pip安装即可:

numpy==1.21.6
matplotlib==3.2.2
Pillow==8.4.0
bcolz==1.2.1
easydict==1.9
onnx==1.8.1
onnx-simplifier==0.2.28
onnxoptimizer==0.2.0
onnxruntime==1.6.0
opencv-contrib-python==4.5.2.52
opencv-python==4.5.1.48
pandas==1.1.5
PyYAML==5.3.1
scikit-image==0.17.2
scikit-learn==0.24.0
scipy==1.5.4
seaborn==0.11.2
sklearn==0.0
tensorboard==2.5.0
tensorboardX==2.1
torch==1.7.1+cu110
torchvision==0.8.2+cu110
tqdm==4.55.1
xmltodict==0.12.0
pycocotools==2.0.2
pybaseutils==0.9.4
basetrainer

项目安装教程请参考(初学者入门,麻烦先看完下面教程,配置好开发环境):

  • 项目开发使用教程和常见问题和解决方法
  • 视频教程:1 手把手教你安装CUDA和cuDNN(1)
  • 视频教程:2 手把手教你安装CUDA和cuDNN(2)
  • 视频教程:3 如何用Anaconda创建pycharm环境
  • 视频教程:4 如何在pycharm中使用Anaconda创建的python环境

 (2) 数据集说明

关于训练数据如何生成的问题:

  • 原论文MODNet使用了PPM-100数据集+私有的数据集,并合成了大部分训练数据
  • 鄙人复现时,先使用matting_human_datasets数据集训练base-model当作pretrained模型;然后合并多个数据集(PPM-100 + RealWorldPortrait-636 + Deep Image Matting),采用背景图来自VOC+COCO+BG-20k ,一共合成了5W+的训练数据和500+的测试数据
  • 合成的方法有两种:方法1:利用公式:合成图 = 前景*alpha+背景*(1-alpha) ;方法二:前景+mask+背景通过GAN生成;

这是Python实现的背景合成,需要提供原始图像image,以及image的前景图像alpha,和需要合成的背景图像bg_img:

    def image_fusion(image: np.ndarray, alpha: np.ndarray, bg_img=(219, 142, 67)):"""图像融合:合成图 = 前景*alpha+背景*(1-alpha):param image: RGB图像(uint8):param alpha: 单通道的alpha图像(uint8):param bg_img: 背景图像,可以是任意的分辨率图像,也可以指定指定纯色的背景:return: 返回与背景合成的图像"""if isinstance(bg_img, tuple) or isinstance(bg_img, list):bg = np.zeros_like(image, dtype=np.uint8)bg_img = np.asarray(bg[:, :, 0:3] + bg_img, dtype=np.uint8)if len(alpha.shape) == 2:# alpha = cv2.cvtColor(alpha, cv2.COLOR_GRAY2BGR)alpha = alpha[:, :, np.newaxis]if alpha.dtype == np.uint8:alpha = np.asarray(alpha / 255.0, dtype=np.float32)sh, sw, d = image.shapebh, bw, d = bg_img.shaperatio = [sw / bw, sh / bh]ratio = max(ratio)if ratio > 1:bg_img = cv2.resize(bg_img, dsize=(math.ceil(bw * ratio), math.ceil(bh * ratio)))bg_img = bg_img[0: sh, 0: sw]image = image * alpha + bg_img * (1 - alpha)image = np.asarray(np.clip(image, 0, 255), dtype=np.uint8)return image

当然,为了方便JNI调用,我这里还实现C++版本图像合成算法,这部分图像处理的基本工具,都放在我的base-utils中

/**** 实现图像融合:out = imgBGR * matte + bg * (1 - matte)* Fix a Bug: 1-alpha实质上仅有B通道参与计算,多通道时(B,G,R),需改Scalar(1.0, 1.0, 1.0)-alpha* @param imgBGR 输入原始图像* @param matte  输入原始图像的Mask,或者alpha,matte* @param out    输出融合图像* @param bg     输入背景图像Mat(可任意大小),也可以通过Scalar指定纯色的背景*/
void image_fusion(cv::Mat &imgBGR, cv::Mat matte, cv::Mat &out, cv::Mat bg) {assert(matte.channels() == 1);out.create(imgBGR.size(), CV_8UC3);vector<float> ratio{(float) imgBGR.cols / bg.cols, (float) imgBGR.rows / bg.rows};float max_ratio = *max_element(ratio.begin(), ratio.end());if (max_ratio > 1.0) {cv::resize(bg, bg, cv::Size(int(bg.cols * max_ratio), int(bg.rows * max_ratio)));}bg = image_center_crop(bg, imgBGR.cols, imgBGR.rows);int n = imgBGR.channels();int h = imgBGR.rows;int w = imgBGR.cols * n;// 循环体外进行乘法和除法运算matte.convertTo(matte, CV_32FC1, 1.0 / 255, 0);for (int i = 0; i < h; ++i) {uchar *sptr = imgBGR.ptr<uchar>(i);uchar *dptr = out.ptr<uchar>(i);float *mptr = matte.ptr<float>(i);uchar *bptr = bg.ptr<uchar>(i);for (int j = 0; j < w; j += n) {//float alpha = mptr[j] / 255; //循环体尽量减少乘法和除法运算float alpha = mptr[j / 3];float _alpha = 1.f - alpha;dptr[j] = uchar(sptr[j] * alpha + bptr[j] * _alpha);dptr[j + 1] = uchar(sptr[j + 1] * alpha + bptr[j + 1] * _alpha);dptr[j + 2] = uchar(sptr[j + 2] * alpha + bptr[j + 2] * _alpha);}}
}

 (3) MODNet模型

本文主要在MODNet人像抠图算法基础上进行模型压缩和优化,关于《MODNet: Trimap-Free Portrait Matting in Real Time》,请参考:

  • Paper: https://arxiv.org/pdf/2011.11961.pdf
  • 官方Github: GitHub - ZHKKKe/MODNet: A Trimap-Free Solution for Portrait Matting in Real Time 

 MODNet模型学习分为三个部分,分别为:语义部分(S),细节部分(D)和融合部分(F)

  • 在语义估计中,对high-level的特征结果进行监督学习,标签使用的是下采样及高斯模糊后的GT,损失函数用的L2-Loss,用L2loss应该可以学到更soft的语义特征;
  • 在细节预测中,结合了输入图像的信息和语义部分的输出特征,通过encoder-decoder对人像边缘进行单独地约束学习,用的是交叉熵损失函数。为了减小计算量,encoder-decoder结构较为shallow,同时处理的是原图下采样后的尺度。
  • 在融合部分,把语义输出和细节输出结果拼起来后得到最终的alpha结果,这部分约束用的是L1损失函数。

官方GitHub仅仅放出推理代码,并未提供训练代码和数据处理代码 ;鄙人参考原论文花了几个星期的时间,总算复现了其基本效果,并做了一些轻量化和优化的工作,主要有:

  • 复现Pytorch版本的MODNet训练过程和数据处理
  • 增加了数据增强方法:如多尺度随机裁剪,Mosaic(拼图),随机背景融合等方法,提高模型泛化性
  • 对MODNet骨干网络backbone进行轻量化,减少计算量
  • 模型压缩,目前提供三个版本:高精度人像抠图modnet+快速人像抠图modnet0.75+超快人像抠图modnet0.5
  • 转写模型推理过程,实现C++版本人像抠图算法
  • 实现Android版本人像抠图算法,支持CPU和GPU
  • 提供高精度版本人像抠图,可以达到精细到发丝级别的抠图效果(Android GPU 150ms,  CPU 500ms左右)
  • 提供轻量化快速版人像抠图,满足基本的人像抠图效果,可以在Android达到实时的抠图效果(Android GPU 60ms,  CPU 140ms左右)

高精度人像抠图modnet+快速人像抠图modnet0.75+超快人像抠图modnet0.5的模型参数量和计算量:

模型input sizeFLOPs and Params
modnet416×416Model FLOPs 10210.24M, Params 6.44M
modnet0.75320×320Model FLOPs 3486.23M, Params 3.64M
modnet0.5320×320Model FLOPs 1559.07M, Params 1.63M

最近发现,百度PaddleSeg团队也复现了MODNet算法(基于PaddlePaddle框架,非Pytorch版本),提供了更丰富的backbone模型选择,如MobileNetV2,ResNet50,HRNet_W18,可适用边缘端、服务端等多种任务场景,有兴趣的可以看看:

 PaddlePaddle版本:https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.3/contrib/Matting


5. Demo测试效果 

项目环境配置好后,运动demo.py即可测试抠图效果,方法

  • 测试图片
# 测试图片
python demo.py --model_type "modnet" --model_file "work_space/modnet_416/model/best_model.pth" --image_dir "data/test_images"
  • 测试视频文件
# 测试视频文件
python demo.py --model_type "modnet" --model_file "work_space/modnet_416/model/best_model.pth" --video_file "data/video/video-test1.mp4"
  • 测试摄像头
# 测试摄像头
python demo.py --model_type "modnet" --model_file "work_space/modnet_416/model/best_model.pth" --video_file 0

下图GIF是Python版本的视频抠图效果

实际使用中,建议你:

  • 背景越单一,抠图的效果越好,背景越复杂,抠图效果越差;建议你实际使用中,找一比较单一的背景,如墙面,天空等
  • 上半身抠图的效果越好,下半身或者全身抠图效果较差;本质上这是数据的问题,因为训练数据70%都是只有上半身的
  • 白种人抠图的效果越好,黑人和黄种人抠图效果较差;这也是数据的问题,因为训练数据大部分都是隔壁的老外

下图是高精度版本人像抠图和快速人像抠图的测试效果,相对而言,高精度版本人像抠图可以精细到发丝级别的抠图效果;而快速人像构图目前仅能实现基本的抠图效果

高精度版本人像抠图快速人像抠图

6. 源码下载(Python)

项目源码下载地址:Python实现人像抠图 (Portrait Matting)

项目源码内容包含:

  • 提供Python的推理代码(不含训练代码和不含数据集)
  • 提供高精度版本人像抠图模型(modnet_416),可以达到精细到发丝级别的抠图效果
  • 提供轻量化快速版人像抠图模型(modnet0.75_320和modnet0.5_320),满足基本的人像抠图效果,
  • Demo支持图片抠图,视频抠图,摄像头抠图

7.人像抠图C++版本

一键抠图2:C/C++实现人像抠图 (Portrait Matting)https://blog.csdn.net/guyuealian/article/details/134790532


8.人像抠图Android版本

一键抠图3:Android实现人像抠图 (Portrait Matting)https://blog.csdn.net/guyuealian/article/details/134801795

这篇关于一键抠图1:Python实现人像抠图 (Portrait Matting)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/459211

相关文章

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u