前言
图像分割是将一幅图像分割成有意义区域的过程(即分割图像前景和背景)。这些区域可以是一些颜色、边界或邻近相似等特性进行构建的。现在网上图像分割技术有很多种,例如Graph Cut(图割)、聚类分割、变分发等等。
(一)图割(Graph Cut)
图割算法将分割问题看成对图像个像素进行二元(前景、背景)标号的组合优化问题。通过构造一个包含数据项和光滑项的能量函数,把图像映射成带权图G=(V,E)V代表结点,E为边),如图1所示,将标号问题的全局最优化求解转化为对应带权图的最大流/最小分割问题,题。标准的能量函数定义为:
图1
另外一种简单说法,图割也是将一个有向图分割成两个不相交的集合,可以用来解决很多计算机视觉上的问题。如立体深度重建、图像拼接和图像分割等问题。从图像像素和像素近邻创建一个图并引入一个能量或“代价”函数,在运用到图割方法时,可将图像分割成两个区域或者多个区域。基本思想是:相似且彼此相近的像素划分到同一区域。
图割C(C为图1中所有边的集合)的‘代价’函数定义为所有边的权重求和相加:
所以,图割图像分割的思想是用图表示图像,并对图进行划分使代价最小。在图表示时,会增加两个额外的点(源点和汇点),方便仅考虑将源点和汇点的分割。寻找最小割(即寻找最大流)方法进行分割,这个方法主要用到Python-graph工具包,所以需要安装graph。(graph包在后面分享链接里)
(二)图割实现
1.计算最大流
计算一幅较小的图最大流(最小割)简单的例子。首先创建4个结点的有向图,4个结点的索引分别为0...3,再用add_edge()增添边并为每条边指定特定的权值。边的权重用来衡量边的最大容量,以0为源点,3为汇点,计算最大流。
from pygraph.classes.digraph import digraph
from pygraph.algorithms.minmax import maximum_flow
gr = digraph()#有向图
gr.add_nodes([0,1,2,3])
gr.add_edge((0,1), wt=4)
gr.add_edge((1,2), wt=3)
gr.add_edge((2,3), wt=5)
gr.add_edge((0,2), wt=3)
gr.add_edge((1,3), wt=4)
#最大流方法,flow最大流经过哪些边,cuts分割掉的边
flows,cuts = maximum_flow(gr, 0, 3)
print ('flow is:' , flows)
print ('cut is:' , cuts)
运行结果:
2.图像分割例子
# -*- coding: utf-8 -*-
from scipy.misc import imresize
from PCV.tools import graphcut
from PIL import Image
from numpy import *
from pylab import *
im = array(Image.open("empire.jpg"))
im = imresize(im, 0.07)
size = im.shape[:2]
print ("OK!!")
# add two rectangular training regions
labels = zeros(size)
labels[3:18, 3:18] = -1 #背景
labels[-18:-3, -18:-3] = 1 #前景
print ("OK!!")
# create graph
g = graphcut.build_bayes_graph(im, labels, kappa=1)
# cut the graph
res = graphcut.cut_graph(g, size)
print ("OK!!")
figure()
graphcut.show_labeling(im, labels)
figure()
imshow(res)
gray()
axis('off')
show()
1.对取前景和背景像素相似的图像:
运行结果:
图2
对上图2来说,自己可以手动改变矩形框的范围,蓝色表示背景,红色表示前景;因为前景图的房子与石头梯子像素很相似,所有分割效果不好。采用矩形框分割图像效果确实不好,自己手动调节矩形区域并不能很好划分,像这种背景区域有相似像素时,效果明显不好。
图2是利用贝叶斯概率模型进行图像分割。左图表示图像降采样到54*38大小(用于模型训练的标记图像),右图为分割后的结果。对于左图在利用imresize()函数修改图像,使图像适合graph库的大小,在这个例子中同意缩放到原图7%的前提下,图分割后将结果和训练区域画出来。
对取前景突出的图像:
运行结果:
图3
从运行结果看出,图3对比图2来说,会相对分割效果好,没有背景相似像素的影响。
图4 图5
图4中kapaa=1,图5中kappa=2,变量kappa决定了近邻像素间边的相对权重,改变K值可以使分割效果发生变化,K值越大,分割边界就越平滑,细节部分也会逐渐丢失。在处理一些图像分割问题,可根据自己分割需求选择适当的K值。改变K值会发生一下变化。
(三)代码下载
链接:代码下载
提取码:s72u