OpenCV-Python教程:32.使用GrabCut算法分割前景

理论

GranCut算法是Carsten Rother, Vladimir Kolmogorov & Andrew Blake from Microsoft Research Cambridge, UK在他们的论文“GrabCut”: interactive foreground extraction using iterated graph cuts里设计的。使用最小程度的用户交互来分解前景。

从用户角度来看是怎么工作的呢?开始用户画一个矩形方块把前景图圈起来,前景区域应该完全在矩形内,然后算法反复进行分割以达到最好效果。但是有些情况下,分割的不是很好,比如把前景给标称背景了等。在这种情况下用户需要再润色,就在图像上有缺陷的点给几笔。这几笔的意思是说“嘿,这个区域应该是前景,你把它标成背景了,下次迭代改过来”或者是反过来。那么在下次迭代,结果会更好。

看下面的图像,首先球员和足球杯包在蓝色矩形框里,然后用白色笔(指出前景)和黑色笔(指出背景)来做一些润色

后台发生了什么?

·用户输入矩形,矩形外的所有东西都被确认是背景。所有矩形内的东西都是未知的,同样的任何用户输入指定前景和背景的也都被认为是硬标记,在处理过程中不会变。

·计算机会根据我们给的数据做初始标记,它会标记出前景和背景像素。

·现在回使用高斯混合模型(GMM)来为前景和背景建模

·根据我们给的数据,GMM学习和创建新的像素分布。未知像素被标为可能的前景或可能的背景(根据其他硬标记像素的颜色统计和他们之间的关系)

·根据这个像素分布创建一个图,图中的节点是像素,另外还有两个节点,源节点和汇节点,每个前景像素和源节点相连,每个背景像素和汇节点相连。

·源节点和汇节点连接的像素的边的权重由像素是前景或者背景的概率决定。像素之间的权重是由边的信息或者像素的相似度决定。如果像素颜色有很大差异,他们之间的边的权重就比较低。

·mincut算法是用来分割图的,它用最小成本函数把图切成两个分开的源点和汇点,成本函数是被切的边的权重之和。切完以后,所有连到源节点的像素称为前景,所有连到汇节点的称为背景。

·过程持续直到分类覆盖。

Demo

现在我们用OpenCV来做grabcut算法。OpenCV有个函数cv2.grabCut()来做这个,我们先看看它的参数:

·img - 输入图像

·mask - 这是掩图,我们指定哪个区域是背景,前景以及可能是背景或者前景。由下面的标志位:cv2.GC_BGD, cv2.GC_FGD, cv2.PR_BGD, cv2.GC_PR_FGD, 或者简单传入0, 1, 2, 3.

·rect - 包含前景对象的矩形的坐标,格式(x, y, w, h).

·bdgModel, fgdModel - 算法内部使用的数组, 你创建两个np.float64 类型的0数组,大小是(1, 65)

·iterCount - 算法运行的迭代次数

·mode - 应该是cv2.GC_INIT_WITH_RECT 或者 cv2.GC_INIT_WITH_MASK或者两者合并,决定我们是否画矩形或者最终的润色。

首先让我们看看矩形模式,我们加载图片,创建一个类似的掩图。我们创建fgdModel和bgdModel。 我们给矩形参数。这些都很直接。让算法运行5个迭代。Mode应该是cv2.GC_INIT_WITH_RECT因为我们用了矩形。然后运行grabcut。 它修改掩图。在新的掩图里,像素会被标记为四种标志,来指明他们是背景/前景等。所以我们修改 掩图,所有的0-像素和2-像素被置0(背景)而所有的1-像素和3-像素被置1(前景像素)。现在我们最终的掩图就绪。

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('messi5.jpg')
mask = np.zeros(img.shape[:2],np.uint8)

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

rect = (50,50,450,290)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]

plt.imshow(img),plt.colorbar(),plt.show()

可以看到梅西的头发没了,所以我们润色一下,用1-像素确认是前景,同时有些地皮成了前景,还有logo,我们需要移除他们,我们给一些0-像素润色(确认是背景)。我们修改我们的结果掩图。

实际上我做的是,我用绘图软件打开输入图片,添加了另外一层,使用画刷工具,把丢失的前景(头发,谢,球等)用白色,不要的背景(logo,地面)用黑色画在这个新层上。然后把剩下的背景用灰色填充。然后在OpenCV里加载这个掩图,编辑原始掩图,代码:

# newmask is the mask image I manually labelled
newmask = cv2.imread('newmask.png',0)

# whereever it is marked white (sure foreground), change mask=1
# whereever it is marked black (sure background), change mask=0
mask[newmask == 0] = 0
mask[newmask == 255] = 1

mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)

mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()

也可以不用矩形初始化而直接用掩图模式,用2-像素和3-像素(可能是背景/前景)标记矩形区域,然后把我们确认前景的标为1-像素,然后直接应用grabCut函数,用mask 模式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容