GrabCut图像分割
1、算法步骤
1、在图片中定义含有(一个或多个)物体的矩形
2、在矩形外的区域被自动认为是背景
3、对于用户定义的矩形区域,可以用背景中的数据来区别他里面的前景和背景区域
4、用高斯混合模型来对背景和前景进行建模,并将未定义的像素标记为可能的前景或背景
5、图像中的每一个像素都被看做通过虚拟便于周围像素相连接,而每条边都有一个属于前景和背景 的概率,这基于他与周围像素颜色上的相似性
6、每一个像素(即算法中的节点)会与一个前景和背景节点连接。这与下图类似:
7、在节点完成连接后(可能与背景或前景连接),若节点之间的边属于不同的终端(一个属于背景,一个输入前景),则会切断他们之间的边,这就将图像的各个部分分割出来,下图能够很好的说明算法:
2、实例代码
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("../images/13.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 创建于读入图像,相同大小的掩模
mask = np.zeros(img.shape[:2],np.uint8)
# 创建以0填充的前景和背景模型
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
rect = (100,50,421,378)
cv2.grabCut(img, mask, rect, bgdModel,fgdModel,6,cv2.GC_INIT_WITH_RECT)
# 此时的掩模已经变成了0-3之间的数字,
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(gray)
plt.title("original"),plt.xticks([]),plt.yticks([])
plt.show()