专栏首页AI算法与图像处理基于UNet网络实现的人像分割 | 附数据集

基于UNet网络实现的人像分割 | 附数据集

工作之后,发现更重要的能力如何理解业务并将算法应用其中创造价值,以及如何落地。

主要内容

人像分割简介

UNet的简介

UNet实现人像分割

人像分割简介

人像分割的相关应用非常广,例如基于人像分割可以实现背景的替换做出各种非常酷炫的效果。我们将训练数据扩充到人体分割,那么我们就是对人体做美颜特效处理,同时对背景做其他的特效处理,这样整张画面就会变得更加有趣,更加提高颜值了,这里我们对人体前景做美颜调色处理,对背景做了以下特效:

①景深模糊效果,用来模拟双摄聚焦效果;

②马赛克效果

③缩放模糊效果

④运动模糊效果

⑤油画效果

⑥线条漫画效果

⑦Glow梦幻效果

⑧铅笔画场景效果

⑨扩散效果

例子:

例子来源:https://blog.csdn.net/Trent1985/article/details/80578841 https://zhuanlan.zhihu.com/p/48080465 (实现背景灰化)

而在在实现这些效果之前,所需要的一步操作都是需要将人像抠出来。今天的主要内容是要介绍如何使用UNet实现人像分割。

UNet的简介

UNet的结构非常简单,广泛应用于医学图像分割,2015年发表在 MICCAI,谷歌学术上目前引用量8894,可以看出来其影响力。

UNet的结构,有两个最大的特点,U型结构和skip-connection(如下图)。

UNet网络,类型于一个U字母:首先进行Conv(两次)+Pooling下采样;然后Deconv反卷积进行上采样(部分采用resize+线性插值上采样),crop之前的低层feature map,进行融合;然后再次上采样。重复这个过程,直到获得输出388x388x2的feature map,最后经过softmax获得output segment map。总体来说与FCN思路非常类似。

U-Net采用了与FCN完全不同的特征融合方式:拼接!

参考资料:https://zhuanlan.zhihu.com/p/57437131 https://www.zhihu.com/question/269914775/answer/586501606 https://www.zhihu.com/people/george-zhang-84/posts

UNet实现人像分割

该项目是基于 https://github.com/milesial/Pytorch-UNet (2.6k star 车辆分割)修改的,并提供人像分割的数据集(1.15G)。

人像分割项目链接:https://github.com/leijue222/portrait-matting-unet-flask

官方下载链接:http://www.cse.cuhk.edu.hk/leojia/projects/automatting/index.html 或者: 百度网盘:http://pan.baidu.com/s/1dE14537 密码:ndg8

该项目已经提供了预训练模型,如果你不想重新训练,可以自己clone下来,按照下面的操作一步一步运行即可。

环境配置

  • Python 3.6
  • PyTorch >= 1.1.0
  • Torchvision >= 0.3.0
  • Flask 1.1.1
  • future 0.18.2
  • matplotlib 3.1.3
  • numpy 1.16.0
  • Pillow 6.2.0
  • protobuf 3.11.3
  • tensorboard 1.14.0
  • tqdm==4.42.1
# clone 项目
git clone https://github.com/leijue222/portrait-matting-unet-flask.git

# 进入到文件夹中
cd portrait-matting-unet-flask/

# 准备好一张待分割的人像图片,运行下面的代码即可生成mask并保存
python predict.py -i image.jpg -o output.jpg

作者提供的测试demo

如果你想重新训练的话,也很容易,根据上面提供的数据集,将原图和mask分别

放置在 文件夹 data/imgs和 data/masks 路径下即可

然后运行下面的代码

python train.py -e 200 -b 1 -l 0.1 -s 0.5 -v 15.0

各个参数的含义

-e 表示 epoch 数

-b 表示 batch size

-l 表示学习率

-s 表示 scale

-v 表示 验证集所占的百分比

最后我们在看一下 UNet 网络的核心代码

定义UNet 需要用的主要模块

class DoubleConv(nn.Module):
    """(convolution => [BN] => ReLU) * 2"""
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.double_conv = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        )
    def forward(self, x):
        return self.double_conv(x)

class Down(nn.Module):
    """Downscaling with maxpool then double conv"""

    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.maxpool_conv = nn.Sequential(
            nn.MaxPool2d(2),
            DoubleConv(in_channels, out_channels)
        )
    def forward(self, x):
        return self.maxpool_conv(x)

class Up(nn.Module):
    """Upscaling then double conv"""
    def __init__(self, in_channels, out_channels, bilinear=True):
        super().__init__()
        # if bilinear, use the normal convolutions to reduce the number of channels
        if bilinear:
            self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
        else:
            self.up = nn.ConvTranspose2d(in_channels // 2, in_channels // 2, kernel_size=2, stride=2)

        self.conv = DoubleConv(in_channels, out_channels)

    def forward(self, x1, x2):
        x1 = self.up(x1)
        # input is CHW
        diffY = torch.tensor([x2.size()[2] - x1.size()[2]])
        diffX = torch.tensor([x2.size()[3] - x1.size()[3]])

        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2])
        x = torch.cat([x2, x1], dim=1)
        return self.conv(x)

class OutConv(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(OutConv, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)

    def forward(self, x):
        return self.conv(x)

利用上面定义好的模块,轻松的实现UNet网络

class UNet(nn.Module):
    def __init__(self, n_channels, n_classes, bilinear=True):
        super(UNet, self).__init__()
        self.n_channels = n_channels
        self.n_classes = n_classes
        self.bilinear = bilinear

        self.inc = DoubleConv(n_channels, 64)
        self.down1 = Down(64, 128)
        self.down2 = Down(128, 256)
        self.down3 = Down(256, 512)
        self.down4 = Down(512, 512)
        self.up1 = Up(1024, 256, bilinear)
        self.up2 = Up(512, 128, bilinear)
        self.up3 = Up(256, 64, bilinear)
        self.up4 = Up(128, 64, bilinear)
        self.outc = OutConv(64, n_classes)

    def forward(self, x):
        x1 = self.inc(x)
        x2 = self.down1(x1)
        x3 = self.down2(x2)
        x4 = self.down3(x3)
        x5 = self.down4(x4)
        x = self.up1(x5, x4)
        x = self.up2(x, x3)
        x = self.up3(x, x2)
        x = self.up4(x, x1)
        logits = self.outc(x)
        return logits

资料汇总

人像分割项目链接:https://github.com/leijue222/portrait-matting-unet-flask

数据集下载

百度网盘:http://pan.baidu.com/s/1dE14537

密码:ndg8

官方下载链接:http://www.cse.cuhk.edu.hk/leojia/projects/automatting/index.html

UNet相关知识点参考资料:

https://zhuanlan.zhihu.com/p/57437131

https://www.zhihu.com/question/269914775/answer/586501606

https://www.zhihu.com/people/george-zhang-84/posts

本文分享自微信公众号 - AI算法与图像处理(AI_study),作者:AI_study

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 万字长文!攻克目标检测难点秘籍一,模型加速之轻量化网络

    目标检测是计算机视觉中一个重要问题,在行人跟踪、车牌识别、无人驾驶等领域都具有重要的研究价值。近年来,随着深度学习对图像分类准确度的大幅度提高,基于深度学习的目...

    AI算法与图像处理
  • 面向对象编程的方式搭建CNN网络 | PyTorch系列(十三)

    从我们深度学习项目的高层视角或概括的角度来看,我们准备了数据,现在,我们准备构建我们的模型。

    AI算法与图像处理
  • CNN输出大小公式 | PyTorch系列(二十)

    原标题:CNN Output Size Formula - Bonus Neural Network Debugging Session

    AI算法与图像处理
  • 项目笔记 LUNA16-DeepLung:(二)肺结节检测

    在前面进行了肺结节数据的预处理之后,接下来开始进入肺结节检测环节。首先附上该项目的Github链接:https://github.com/Minerva-J/D...

    Minerva
  • 接口测试 | 24 requests + unittest集成你的接口测试

    概述 本文就如何结合requests、unittest进行实例演示,如果你还不了解unittest、PO模型,请翻阅公众号前期发布的unittest专题和PO模...

    苦叶子
  • 接口测试 | 24 requests + unittest集成你的接口测试

    概述 本文就如何结合requests、unittest进行实例演示,如果你还不了解unittest、PO模型,请翻阅公众号前期发布的unittest专题和PO模...

    苦叶子
  • 理解unittest测试框架(三)——结果处理

    前文说到了测试的核心,用例的处理,这篇文章来说说unittest框架对于测试结果的处理方式。

    点点寒彬
  • 使用Django+channels+Python3.7时提交Form表单: 400 Bad Request问题

    上次在自己的博客项目上尝试了Python3.7的beta版之后,意识到Celery因为惯性还是不能兼容3.7,所以不在做升级的打算。直到前不久开始弄一个简单的内...

    the5fire
  • 毕业设计:基于CNN的图像分类算法

    近年来人工智能越来越火,好像本科毕设不搞人工智能都很丢人似的。但是普通本科生对于这个领域的了解显然很少,基本也就是做做数据搜集、数据标注、工程实现、调调参的工作...

    用户2145057
  • 500行代码,教你用python写个微信飞机大战

    这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手。

    猴哥yuri

扫码关注云+社区

领取腾讯云代金券