今天要整理记录的笔记是关于GrabCut图像分割的内容,GrabCut是基于图割(graph cut)实现的图像分割算法,它需要指定输入一个bounding box作为分割目标区域,根据目标区域中的像素,来实现对目标前景与背景的分割。注意GrabCut图像分割算法并不是把图像分成若干区域,而是注重于将我们需要的前景区域从整幅图像中提取出来,以达到前景、背景相互分割的目的。
而且由于GrabCut图像分割算法的分割速度比较快、效果比较好、同时支持交互操作,因此在很多图像分割或背景虚化的程序中都具有它的一席之地。
在维基百科中,关于GrabCut图像分割算法的介绍如下:
GrabCut是一种基于图形切割的图像分割方法。
该算法从要分段的对象周围的用户指定的边界框开始,使用高斯混合模型估计目标对象和背景的颜色分布。这用于在像素标签上构造Markov 随机字段,其能量函数更喜欢具有相同标签的连接区域,并运行基于图形剪切的优化以推断其值。由于此估计值可能比从边界框中获取的原始估计值更准确,因此重复这一两步过程,直到收敛。
用户可以通过指出错误分类的区域并重新运行优化来进一步更正估计值。该方法还会更正结果以保留边。
有几个开源实现可用,包括OpenCV(截至版本 2.1)。
通过维基百科的定义我们能了解到GrabCut图像分割算法的大致内容,那么对于GrabCut算法的主要步骤则可以总结为如下几步:
(1)在图片中选取(一个或者多个)包含目标的ROI矩形框,矩形框中即是我们所要提取出的目标对象;
(2)将图像中矩形框以外的区域都自动认为是属于背景区域,在掩膜mask中将背景区域的像素值置为0(GC_BGD);
(3)对于用户定义的ROI矩形区域,使用背景区域中的像素数据(如灰度值、颜色分布等等)来判断ROI区域中的前景区域和背景区域;
(4)使用高斯混合模型(GMM)来分别对背景和前景进行建模,并将未定义的像素标记为可能的前景或者可能的背景;
(5)图像中的每一个像素点都被看作通过虚拟边与周围像素点相连接,并且基于该像素点与周边像素点颜色上的相似性,来对其所具有的每一条虚拟边分别赋予一个属于前景或者背景的概率;
(6)通过对像素点的虚拟边具有的概率进行统计,从而判断该像素点属于哪一种区域,每一个像素点都会属于一个前景或背景;
(7)在每个像素点都完成连接后(可能是与背景或前景相连接),若像素点之间的虚拟边属于不同区域(即一条虚拟边连接着的两个像素点,其中一个像素点属于前景,另一个像素点属于背景),则会切断他们之间的虚拟边。对所有像素点进行类似操作后,就能将图像的前景和背景分割出来。
同时,可以通过迭代地运行GrabCut图像分割算法来提高图像分割的效果,当然了在提升效果的同时也会以牺牲时间为代价。
正如维基百科中所说,在OpenCV中已经封装好了实现GrabCut图像分割算法的APIgrabCut()
,我们可以通过调用这个API来实现所需的功能。这个API的参数含义如下:
(1)参数img:输入的进行图像分割的8位三通道图像;
(2ÿ