unet训练自己的数据集_基于UNet网络实现的人像分割 | 附数据集
點擊上方↑↑↑“OpenCV學堂”關注我
來源:公眾號 AI算法與圖像處理?授權
以后我會在公眾號分享一些關于算法的應用(美顏相關的),工作之后,發現更重要的能力如何理解業務并將算法應用其中創造價值,以及如何落地?。
今天要分享的是人像分割相關的內容,如果你喜歡的話,歡迎三連哦
主要內容
人像分割簡介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 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
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的unet训练自己的数据集_基于UNet网络实现的人像分割 | 附数据集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python正则表达式模块_Python
- 下一篇: long类型python_Python如