一键抠图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分为两大类:

第一种方法需要加入辅助信息,而辅助信息一般较难获取,这也限制应用,为了提升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)有什么区别,我这里简单说明一下:


3. Matting数据

一些开源matting数据

数据

说明

matting_human_datasets

Deep Image Matting

PPM-100

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

RealWorldPortrait-636

 Compsition-1k

HAttMatting

 AM-2k

BG-20k

VideoMatte240K

PhotoMatte85

其他的:

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

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

 (2) 数据集说明

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

这是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.shape
        bh, bw, d = bg_img.shape
        ratio = [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》,请参考

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

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

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

模型 input size FLOPs and Params
modnet 416×416 Model FLOPs 10210.24M, Params 6.44M
modnet0.75 320×320 Model FLOPs 3486.23M, Params 3.64M
modnet0.5 320×320 Model 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)

项目源码内容包含


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

原文地址:https://blog.csdn.net/guyuealian/article/details/134784803

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_49204.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注