1 图像分割与提取
1.1 用分水岭算法实现图像分割与提取
未知区域UN=(图像O-确定背景B)- 确定前景F
函数connectedComponents
retval,labels=cv.connectedComponents(image)
. image为8位单通道的待标注图像
. retval为返回的标注的数量
. labels为标注的结果图像
为了能使用分水岭算法,还需要对原始图像内的未知区域进行标注,将已经计算出来的未知区域标注为0即可:
ret,markers = cv.connectedCompontens(fore)
markers=markers+1
markers[未知区域]=0
函数cv.watershed()
markers=cv.watershed(image,markers)
. image 是输入图像,必须是8位三通道的图像。在对图像使用cv.watershed()函数处理之前,必须先用正数大致勾画出图像中的期望分割区域。每一个分割的区域会被标注为1、2、3等、对尚未确定的区域,需要将他们标注为0.我们可以将标注区域理解为进行分水岭算法分割的“种子”区域。
. markers是32位单通道的标注结果,他应该和image具有相等大小。每一个像素要么被设置为初期的“种子数”,要么被设置为“-1”表示边界。
1.1.1 分水岭算法图像分割实例
1.2 交互式前景提取
mask,bgdModel,fgbModel=cv.grabCut(img,mask,rect,bgdModel,fgdModel,iterCount,model)
. img为输入图像,要求是8位3通道
. mask为掩模图像,要求是8位单通道:
. cv.GC_BGD:表示确定后背景,可用0表示
. cv.GC_FGD:表示确地前景,可用1表示
. cv.GC_PR_BGD:表示可能的背景,可用2表示
. cv.GC_PR_FGD:表示可能的前景,可用3表示
. rect 指包含前景对象的区域,该区域外的部分被认为是“确定背景”。
. bgdModel 为算法内部使用的数组,只需要创建大小为(1,65)的numpy.float64数组。
. fgdModel为算法内部使用的数组,只需要创建大小为(1,65)的numpy.float64数组。
. iterCount表示迭代的次数
. mode表示迭代模式。
o=cv.imread('lenacolor.png')
mask=np.zeros(o.shape[:2],np.uint8)
bgd=np.zeros((1,65),np.float64)
fgd=np.zeros((1,65),np.float64)
rect=(50,50,400,500)
cv.grabCut(o,mask,rect,bgd,fgd,5,cv.GC_INIT_WITH_RECT)
mask2=cv.imread('mask.png',0)
mask2show=cv.imread('mask.png')
mask[mask2==0]=0
mask[mask2==255]=1
mask,bgd,fgd=cv.grabCut(o,mask,None,bgd,fgd,5,cv.GC_INIT_WITH_MASK)
mask=np.where((mask==2)|(mask==0),0,1).astype('uint8')
ogc=o*mask[:,:,np.newaxis]
plt.subplot(121)
plt.imshow(mask2show[:,:,::-1])
plt.axis('off')
plt.subplot(122)
plt.imshow(ogc[:,:,::-1])
plt.axis('off')
plt.show()