OpenCVGrabCut图像分割算法的使⽤及其原理
本⽂架构
GrabCut算法和Graphcut算法的关系
GrabCut函数参数的介绍
GrabCut算法的使⽤案例
GrabCut算法实现的步骤rectangle函数opencv
GrabCut算法实现的原理
知识扩展
图像分割:选取图像中的指定⽬标,并将背景⾊置为⿊⾊。识别⽬标
实例分割:在像素级识别对象轮廓的任务【最困难的视觉任务之⼀】。识别⽬标特征
GrabCut算法和GraphCut算法的关系
OpenCV中的GrabCut算法是GraphCut算法的改进
GraphCut是⼀种直接基于图割算法的图像分割技术, 仅仅需要确认前景和背景输⼊, 该算法就可以完成前景和背景的最优分割,该算法利⽤了图像中的纹理(颜⾊)信息和边界(反差)信息, 只要少量的⽤户交互操作即可得到⽐较好的分割结果, 和分⽔岭算法⽐较相似,但是计算速度⽐较慢, 得到的结果⽐较精确。
如果要从静态图像中提取前景物体(如从⼀个图像剪切物体到另⼀个图像), 采⽤GrabCut算法是最好的选择。
GrabCut函数参数的介绍
def grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None):
# grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) -> mask, bgdModel, fgdModel
img:待分割原图像, 需为8位三通道彩⾊图像
mask:8位单通道掩码图像, 如果使⽤掩码进⾏初始化, 那么mask保存掩码信息, 在执⾏分割的时候, 也可以将⽤户交互所设定的前景与背景保存到mask中,然后再传⼊grabCut函数, 在处理结束之后,mask中会保存结果。
rect:包含分割对象的矩形ROI, 矩形外部的像素为背景, 矩形内部的像素为前景,当参数mode=GC_INIT_WITH_RECT使⽤
bgdModel:背景模型(内部使⽤), ⼤⼩为 (1,65),数据类型为 np.float64 的数组
fgdModel:前景模型(内部使⽤ ), ⼤⼩为 (1,65),数据类型为 np.float64 的数组
iterCount: 迭代次数, 必须⼤于0(并不是越⼤越好的)
mode:⽤于指⽰grabCut函数进⾏什么操作
mask只能选取四种情况:
1. GC_BGD:表⽰明确属于背景的像素
2. GC_FGD:表⽰明确属于前景的像素
3. GC_PR_BGD:表⽰可能属于背景的像素
4. GC_PR_FGD:表⽰可能属于前景的像素
5. 如果没有⼿动标记GC_BGD或者GC_FGD, 那么结果只会有GC_PR_BGD或GC_PR_FGD
mode可以选择的值有:
1. GC_INIT_WITH_RECT:⽤矩形框初始化GrabCut
2. GC_INIT_WITH_MASK:⽤掩码图像初始化GrabCut
3. GC_EVAL:执⾏分割
GrabCut算法的使⽤案例
运⾏结果
代码及解析
import numpy as np
from matplotlib import pyplot as plt
import cv2
img = cv2.imread('../../data/messi5.jpg')# 读⼊⽬标图像
plt.imshow(img)# 显⽰图⽚,⽅便记录⽬标图像的起始点和⼤⼩,为rectangle函数做准备
plt.show()
mask = np.zeros(img.shape[:2],np.uint8)# 制作mask图像(注意:必须与原图的⼤⼩相同)
#mask = mask.ravel()
#print(set(mask)) # {0}
bgdModel = np.zeros((1,65),np.float64)# 定义前景模块:65为固定值
fgdModel = np.zeros((1,65),np.float64)# 定义背景模块
rect =(0,0,0,0)# 次数rect参数对结果⽆影响
#print(set(mask)) # {0, 2, 3}
mask2 = np.where((mask==1)|(mask==3),1,0).astype('uint8')# 提取前景
# mask2[:,:,np.newaxis]:将⼆维图像转换成三维图像
"""
mask2.shape
(342, 548)
mask2[:,:,np.newaxis].shape
(342, 548, 1)
"""
# 将原图与mask的每⼀个颜⾊空间相乘(⼴播)
img = img * mask2[:,:,np.newaxis]# 改变数组维度与原图保持⼀致
cv2.imshow('result',img)# 显⽰图⽚
cv2.waitKey(0)
cv2.destroyAllWindows()
GrabCut算法实现的步骤
1. 在⽬标图像中创建⼀个或多个矩形(矩形外部区域默认为背景)
2. 利⽤⾼斯混合模型(GMM)对背景和前景进⾏建模,并将未定义的像素标记为可能的前景或背景
3. 图形中的每⼀个像素都被看作通过虚拟边与周围像素相连,基于周边像素颜⾊的相似度
4. 每⼀个像素(即算法中的节点)会与⼀个前景或背景节点连接
5. 节点连接完成后,若节点属于不同的终端,则切断他们之间的边
6. 完成图像分割
GrabCut算法实现的原理
GrabCut分割算法在GraphCut算法的基础做了三⽅⾯的改进
1. 利⽤⾼斯混和模型(Gaussian Mix—ture Model,GMM )取代直⽅图 ,将灰度图像扩展到彩⾊图像
2. ⽤估计和参数学习过程中可进化的迭代算法代替⼀次最⼩估计来完成能量最⼩化
3. 通过⾮完全编号降低了对交互⼯作的要求
1.灰度图像扩展到彩⾊图像
彩⾊图像是由RGB三⾊空间上的像素组成的,所以创建⾜够的彩⾊空间直⽅图是很难现实的,因此采⽤GMM模型来创建彩⾊空间数据模型。
GMM可以看作是⼀个维的协⽅差(通常为5)
为了⽅便处理GMM,在优化的过程中引⼊向量作为每个像素的独⽴GMM(前景或者背景)参数
并且每个像素点的不透明度为0或者1故Gibbs能量函数可以改写为:为不透明度,,为背景,为前景⽬标为图像前景与背景的灰度直⽅图,为图像灰度值数组,=()
:主要受到值的影响
引⼊GMM的彩⾊数据模型,数据项可以定义为:其中:是⾼斯概率分布
是混和权重系数(累积和为常数)
即可以推导出:
因此模型的参数就确定为彩⾊图像的平滑项为:
2.迭代算法代替⼀次最⼩估计来完成能量最⼩化
GrabCut中的能量最⼩化(能量越低,越稳定)通过迭代来实现的,不像GraphCuts算法⼀次就完成
迭代最⼩化的优点是可以⾃动修改不透明度的值,并利⽤初始三元图的像素中重新确定的像素来校正彩⾊模型的参数。
主要流程如下
1. ⽤户通过设定背景来初始化三元图T,前景设置为空集,即,
2. 对于有;有
3. 分别⽤和两个集合来初始化前景和背景的GMM模型
4. 求得中的每个像素n所对应的GMM参数,
5. 从数据中获取GMM参数,
6. ⽤最⼩能量来得到初始分割:
7. 从第四步开始重复执⾏,直到收敛
8. 执⾏边界优化
迭代最⼩化过程可看成总能量在、、三个⽅⾯上的单调递减。
这样可以保证算法最终收敛到的最⼩值。
当判断出⼤幅度衰减时,⾃动终⽌迭代。
3.⽤户交互与不完全三元图(⾮完全编号)K K (K ...K )1n E (α,k ,θ,z )=U (α,k ,θ,z )+V (α,z )
αα∈[0,1]01θθ=h (z ,α),α=0,1
z z z ,...z ,...z 1n N E (α,k ,θ,z )=U (α,k ,θ,z )+V (α,z )k U (α,k ,θ,z )=D (α,k ,θ,z )
∑i =1n
n n n D (α,k ,θ,z )=n n n −log (z ∣α)−p n n log (α,k )πn n p (z ∣α)n n π(α,k )n n D (α,k ,θ,z )=n n n −log (α,k )+πn n logdet (α,k )+21n n [z −21
n μ(α,k )](α,k )[z −n n T ∑n n n μ(α,k )]
n n θ=π(α,k ),μ(α,k ),(α,k ),k =1,2,...K
n n n n ∑V (α,z )=γ[α=∑m n
m α]exp (−β∥z −n m z ∥)
n 2T U T B T =F ØT 取背景的补集
U n ∈T B α=n 0n ∈T U α=n 1
α=n 0α=n 1T U k n k =n argminD (α,k ,θ,z )
n n n n z θθ=argminU (α,k ,θ,z )
minminE (α,k ,θ,z )
E k θαE E
⾮完全编号取代完整三元图,能够对⽤户的交互带来更⼤的灵活性。
⽤户的初始交互只需要确定背景区域,并不需要确定前景(从代码中即可看出),可令迭代能量最⼩化是通过允许⼀些编号临时表⽰前景像素,⽽背景的编号是固定不变的。GrabCut中的初始值是⽤户通过标定的矩形区域来确定的
GrabCut算法实现的原理参考于《GrabCut彩⾊图像分割算法的研究》部分节选T B T =F 0T B
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论