opencv 图割grabcut

opencv grabcut

demo: http://download.csdn.net/detail/keen_zuxwang/9852585

高斯混合模型GMM和EM算法
http://blog.csdn.net/u011574296/article/details/52986943
图像分割之(四)OpenCV的GrabCut函数使用和源码解读
http://blog.sina.com.cn/s/blog_6272500201018cc7.html
opencv中的高斯混合模型源码详解
http://blog.csdn.net/u011574296/article/details/52994054
从GraphCut到GrabCut的OpenCV实现:图像分割
http://blog.sina.com.cn/s/blog_1584387c90102x5fu.html

基于图割理论
利用图像的纹理,颜色,位置信息,得到的分割结果具有交大的边界反差。这个算法要求手动设置(可能的)前景和背景的种子点。当背景和前景的差别比较大时,分割结果比较好, 反之分割结果比较差。

图像分割算法:
全自动图像分割:采用聚类算法来最大化前景与背景的差。
互动式图像分割: 根据提供的前景和背景种子,对前景背景建立概率分布模型。

GrabCut
就是属于第二类图像分割算法,主要应用高斯混合模型GMM算法、期望最大化EM算法(EM去计算GMM参数,当GMM模型参数趋于稳定即认为完成了图下像的分割)

GrabCut具体步骤如下(根据框选矩形):
1、长方形外的像素作为背景像素,长方形内的像素作为前景像素,用这两组像素去Train背景GMM和前景GMM。
2、用训练好的两个GMM来计算每一个像素属于背景和属于前景的概率,
进而计算出能量函数E中的Data项,能量函数中的Smoothness项的计算方法大致与GraphCut相同。
3、通过最优化能量函数得到图像的一个分割。
4、用3中的分割结果中的前景像素和背景像素去训练前景GMM和背景GMM.
5、重复2,3,4,直到分割结果收敛(两次迭代的结果变化小于一定程度)。
GrabCut是一个循环执行的算法,其循环的目的是为了EM(Expectation Maximization)。
长方形内也有部分背景像素,这样的种子是不完全正确的。但GMM模型并不要求所有的训练数据正确,即使有一部分分类不正确,也可以通过EM步骤使得最终结果正确。而GrabCut正是利用了GMM的这一特性。

//! class of the pixel in GrabCut algorithm
enum
{
    GC_BGD    = 0,  //!< background
    GC_FGD    = 1,  //!< foreground
    GC_PR_BGD = 2,  //!< most probably background
    GC_PR_FGD = 3   //!< most probably foreground
};

//! GrabCut algorithm flags
enum
{
    GC_INIT_WITH_RECT  = 0,
    GC_INIT_WITH_MASK  = 1,
    GC_EVAL            = 2
};

首先用户在图片上画一个方框,grabCut默认方框内部为前景,设置掩码为2,方框外部都是背景,设置掩码为0。然后根据算法,将方框内部检查出来是背景的位置,掩码由2改为0。经算法处理,方框中掩码依然为2的,就是检查出来的前景,其他为背景

//! segments the image using GrabCut algorithm
CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect,
                           InputOutputArray bgdModel, InputOutputArray fgdModel,
                           int iterCount, int mode = GC_EVAL );

功能:图像前景与背景的分离
img:
待分割的源图像,必须是8位3通道(CV_8UC3)图像
mask:
掩码图像,大小和原图像一致。可以有如下几种取值
GC_BGD(=0),背景
GC_FGD(=1),前景
GC_PR_BGD(=2),可能的背景
GC_PR_FGD(=3),可能的前景
rect:
用于限定需要进行分割的图像范围,只有该矩形窗口内的图像部分才被处理
bgdModel:
背景模型,如果为null,函数内部会自动创建一个bgdModel
fgdModel:
前景模型,如果为null,函数内部会自动创建一个fgdModel
iterCount:
迭代次数,必须大于0
mode:
用于指示grabCut函数进行什么操作。可以有如下几种选择:
GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut
GC_INIT_WITH_MASK(=1),用掩码图像初始化GrabCut
GC_EVAL(=2),执行分割

JNI代码:

JNIEXPORT jlong JNICALL Java_com_example_grabcut_MainActivity_doGrabCut(JNIEnv *env, jclass clz, jlong imageGray)
{
    Mat img  = Mat(*(Mat*)imageGray);
    Mat img0(img.size(),CV_8UC3); //输入图像须为CV_8UC3类型
    cvtColor(img, img0, CV_BGRA2BGR);

    Mat result; //4种可能结果
    Mat bgModel;//背景
    Mat fgModel;//前景
    Rect selection = Rect(img.cols/4, 0, img.cols/2, img.rows*3/4); //须框选矩形,为grabCut前景、背景

    grabCut(img0, result, selection, bgModel, fgModel, 5, GC_INIT_WITH_RECT); //迭代5次,GC_INIT_WITH_RECT矩形窗初始化GrabCut
    compare(result, GC_PR_FGD, result, CMP_EQ);  //得到前景mask
    Mat foreground(img.size(),CV_8UC3, Scalar::all(255));
    img0.copyTo(foreground,result); // img

    Mat *hist = new Mat(foreground);
    return (jlong) hist;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值