【CV】基于UNet网络实现的人像分割 | 附数据集
文章來源于AI算法與圖像處理,作者AI_study
今天要分享的是人像分割相關的內容,如果你喜歡的話,歡迎三連哦
主要內容
人像分割簡介
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
作者提供的測試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 channelsif 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 CHWdiffY = 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_channelsself.n_classes = n_classesself.bilinear = bilinearself.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
感謝你能看到這里,希望你能給我來一個一鍵三連(分享、在看+點贊),文章都是在我996工作后擠出來時間分享給大家,你的支持是我堅持的最大動力!
總結
以上是生活随笔為你收集整理的【CV】基于UNet网络实现的人像分割 | 附数据集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 太赞了!开源下载机器学习经典书 PRML
- 下一篇: 【机器学习基础】时间序列测试题的40题,