白话文讲计算机视觉-第七讲-GrabCut算法

匿名 (未验证) 提交于 2019-12-03 00:22:01

大家好,我是小木,我又回来了,今天我们要讲一些算法,这些算法可以把物体和它的背景分离。这些算法最常用的有两种,一种叫做GrabCut

我们今天不讲推导过程,原因是本人还没有看明白,所以第九节课给大家普及。这节课我只讲东西是怎么用的。

GrabCutNB36040

BB

首先我们有一张图:

额,又是小熊,为啥博主总是用它呢?很简单,我喜欢这个娃娃啊!我们想要把小熊后边的背景都给干掉,那么怎么办呢?

第一种方法叫做矩形框选法:

首先我们在这个图片上面把前景部分用矩形给圈起来:

接下来,我们假定在红色框框里面的东西一部分可能是前景、一部分可能是背景。而框框外面的物体全部都是背景。

X,Y

PS00123OPENCV

GCD_BGD=0

GCD_FGD=1

GCD_PR_BGD=2

GCD_PR_FGD=3

165=13*5

GrabCut

0~342~320031101

OK

OPENCV

#导入类库  import numpy as np  import cv2  #画图类库,很好用,不用自己从头编写了  from matplotlib import pyplot as plt     #导入图像(小熊)  img = cv2.imread('D:/xiaomu/opencv7-1.png')  #建立一个和img图像一样大的蒙版  mask = np.zeros(img.shape[:2],np.uint8)  #画一个矩形框框,选出前景物体(小熊)  rect = (50,10,250,440)  #建立背景模型和前景模型,大小为1*65  bgdModel = np.zeros((1,65),np.float64)  fgdModel = np.zeros((1,65),np.float64)     #把上面的数据导入GrabCut算法中,进行计算,  #该方法参数为:1.原始图像 2.蒙版 3.矩形框框 4.背景模型 5.前景模型 6.迭代次数 7.方法选择(矩形框选法)  cv2.grabCut(img.copy(),mask,rect,bgdModel,fgdModel,10,cv2.GC_INIT_WITH_RECT)     #把2变为0,把3变为1  mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')  #将蒙版与原图做点对点乘积  img = img*mask2[:,:,np.newaxis]     #绘制出分离背景后的图像  plt.subplot(121), plt.imshow(img)  plt.title("grabcut"), plt.xticks([]), plt.yticks([])  #绘制出原图  plt.subplot(122), plt.imshow(cv2.cvtColor(cv2.imread('D:/xiaomu/opencv7-1.png'), cv2.COLOR_BGR2RGB))  plt.title("original"), plt.xticks([]), plt.yticks([])  #在窗口中显示图像  plt.show()  #保存图像  cv2.imwrite('D:/xiaomu/opencv7-2.png',img)

我们运行后的结果如下所示:

GrabCut

这种算法中,我们不是用矩形框框把某个前景物体圈起来了,而是我们画一个自定义的轮廓,接着我们上面的结果再次进行背景分离:

我们这次的图片是:

也就是我们上次矩形框框分离后的图图。

PS

在新图层中,我们用白色的刷子,把那些本来应该是前景,但是却没算成前景的地方给标记出来,然后把应该是背景的地方,但是却搞错的用黑色标记,剩下不改变的地方用灰色标记。

最后我们的,我们得到的蒙版为:

在蒙版中,我为了说明不同颜色的用途,所以我才随意画了一个白色的圈圈。

OPENCVOPENCV

#导入类库  import numpy as np  import cv2  #画图类库,很好用,不用自己从头编写了  from matplotlib import pyplot as plt     #导入图像(小熊)  img = cv2.imread('D:/xiaomu/opencv7-1.png')  #建立一个和img图像一样大的蒙版  mask = np.zeros(img.shape[:2],np.uint8)  #画一个矩形框框,选出前景物体(小熊)  rect = (50,10,250,440)  #建立背景模型和前景模型,大小为1*65  bgdModel = np.zeros((1,65),np.float64)  fgdModel = np.zeros((1,65),np.float64)     #矩形框选法  #把上面的数据导入GrabCut算法中,进行计算,  #该方法参数为:1.原始图像 2.蒙版 3.矩形框框 4.背景模型 5.前景模型 6.迭代次数 7.方法选择(矩形框选法)  cv2.grabCut(img.copy(),mask,rect,bgdModel,fgdModel,10,cv2.GC_INIT_WITH_RECT)  #把2变为0,把3变为1  mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')  #将蒙版与原图做点对点乘积  img = img*mask2[:,:,np.newaxis]     #非矩形框,蒙版法再处理  img2 = cv2.imread('D:/xiaomu/opencv7-1.png')  #导入蒙版  img3 = cv2.imread('D:/xiaomu/opencv7-3.png',0)  #把蒙版中白色地方置为1,作为确定前景。黑色地方置为0,作为确定背景  mask[img3 == 0] = 0  mask[img3 == 255] = 1     #把上面的数据导入GrabCut算法中,进行计算,  #该方法参数为:1.原始图像 2.蒙版 3.矩形框框(无) 4.背景模型 5.前景模型 6.迭代次数 7.方法选择(蒙版法)  cv2.grabCut(img2,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)     #把2变为0,把3变为1  mask3 = np.where((mask==2)|(mask==0),0,1).astype('uint8')  #将蒙版与原图做点对点乘积  img2 = img2*mask3[:,:,np.newaxis]     #绘制出蒙版法处理后的图像  plt.subplot(121), plt.imshow(img2)  plt.title("grabcut-mask"), plt.xticks([]), plt.yticks([])  #绘制出矩形框法处理后的图像  plt.subplot(122), plt.imshow(img)  plt.title("grabcut-rect"), plt.xticks([]), plt.yticks([])  #在窗口中显示图像  plt.show()     cv2.waitKey()  cv2.destroyAllWindows()

我们运行后的结果如下所示:

我们可以看出,我们把白色的地方都变成了前景(前面的小圆),黑色的地方成背景(小熊与背景分开的更好了)

这样我们的第一种算法就讲解完成了。

第二种算法我们做的是分水岭算法,下节课我们继续讲解。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!