前言
在计算视觉领域,除了图像分类,目标检测,目标跟踪之外,图像分割也是研究的热点之一。 图像分割的常用医学图像,比如CT图像分割,视网膜图像的分割,在其他领域例如地理图像分割中应用也比较广泛。本人之所以对图像分割感兴趣,主要是想将深度学习的图像分割方法用于人像分割,人脸分割,这些应用更贴合我们的生活。
目标
- 研究常见的基于深度学习的图像分割方法。目前已知的方法:FCN,SegNet,UNet....
- 训练FCN网络,实现人脸肤色分割
开发环境
- Ubuntu 18.04
- caffe, pycaffe
- fcn工程
环境搭建
caffe,pycaffe的安装
caffe的安装在Ubuntu18.0上非常简单,一句命令搞定:
sudo apt-get install caffe-cpu
pycaffe也会自动安装到Ubuntu系统自带的python的安装包中。
FCN工程的配置
step1: 下载FCN源码
git clone https://github.com/shelhamer/fcn.berkeleyvision.org.git
FCN源码下载
step2: 下载预训练好的模型
打开文件夹 voc-fcn8s,打开caffemodel-url文件。下载模型
下载好模型之后,我直接保存到voc-fcn8s路径。
测试FCN图像分割
在训练网络之前,我们先用下载好的模型跑几张图片,测试一下效果。这样一方面我们可以有个直观的认识。
- 准备测试图像
在工程的demo文件夹下已经包含了一张测试图像,以及分割的结果。这个图像的尺寸为334x500。
这是demo中的原始图像
分割的结果
可视化结果
再准备几张测试图像,注意:尺寸保存334x500。
- 测试代码
测试代码保存在infer.py文件
import numpy as np
from PIL import Image
import caffe
import vis
# the demo image is "2007_000129" from PASCAL VOC
# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
im = Image.open('xxxx.jpg')
in_ = np.array(im, dtype=np.float32)
in_ = in_[:,:,::-1]
in_ -= np.array((104.00698793,116.66876762,122.67891434))
in_ = in_.transpose((2,0,1))
# load net
net = caffe.Net('voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST)
# shape for input (data blob is N x C x H x W), set data
net.blobs['data'].reshape(1, *in_.shape)
net.blobs['data'].data[...] = in_
# run net and take argmax for prediction
net.forward()
out = net.blobs['score'].data[0].argmax(axis=0)
# visualize segmentation in PASCAL VOC colors
voc_palette = vis.make_palette(21)
out_im = Image.fromarray(vis.color_seg(out, voc_palette))
out_im.save('output.png')
masked_im = Image.fromarray(vis.vis_seg(im, out, voc_palette))
masked_im.save('visualization.jpg')
运行:
在当前路径下打开终端,输入: python3 ./infer.py
可能会有错误产生,比如xange错误, 因为xrange是python2的用法,python3已经不再支持,只需要把xrange替换为range即可。
- 图像分割的结果
dog图像的分割:
person图像的分割:
FCN的分割效果看起来还不错,在深度学习之前,任意目标的图像分割还是一个比较棘手的问题,传统的图像算法比如满水填充water fill, 区域生长 只能适应背景简单的图像。