用GrabCUt算法进行图片前景的提取(这个是之前解决词云图片问题的一种方法):
grabCut算法的实现步骤为:
- 在图片中定义含有(一个或多个)物体的矩形。
- 矩形外的区域被自动认为是背景
- 对于用户定义的矩形区域,可用背景中数据来区分是前景还是背景
- 用高斯混合模型(GMM)来对被禁和前景见面,并将未定义的像素标记为可能的前景或背景
- 图像中的每一个像素都被看作通过通过虚拟变与周围像素连接,而每条边都有一个属于前景或背景的概率这基于它和周围像素颜色上的相似性
- 每一个像素(即算法中的节点)会与前一各前景或背景节点连接,与下图类似:
-在节点连接完成后,用图论中最大流最小割的方法来分割:
例子:
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('statue_small.jpg')
mask = np.zeros(img.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (100,1,421,378)
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.subplot(121), plt.imshow(img)
plt.title("grabcut"), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(cv2.imread('statue_small.jpg'), cv2.COLOR_BGR2RGB))
plt.title("original"), plt.xticks([]), plt.yticks([])
plt.show()
结果:
例程先创建一个与加载图像相同形状的mask:
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('statue_small.jpg')
mask = np.zeros(img.shape[:2],np.uint8)
创建以0填充的前景和背景模型:
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
可以用数据填充这些模型,要准备一个标识出想要各类的对象的矩形框来初始化GrabCut算法。背景和前景要基于这个矩形框来决定:
这边用下面一行代码来决定:
rect = (100,1,421,378)
其实可以用opencv提供的窗口函数自己写一个取前景;
使用致敬的空模型来运行GrabCUt算法,实际上是用一个矩形框来初始化这个操作:
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
fgbModel后面是一个算法的迭代次数
之后mask编程0~3之间的值,值中0~2转换为01和3转为1 保存在mask2中,
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]