opencv 图割grabcut

来源:互联网 发布:java中私有属性 编辑:程序博客网 时间:2024/04/30 15:07

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 algorithmenum{    GC_BGD    = 0,  //!< background    GC_FGD    = 1,  //!< foreground    GC_PR_BGD = 2,  //!< most probably background    GC_PR_FGD = 3   //!< most probably foreground};//! GrabCut algorithm flagsenum{    GC_INIT_WITH_RECT  = 0,    GC_INIT_WITH_MASK  = 1,    GC_EVAL            = 2};

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

//! segments the image using GrabCut algorithmCV_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;}

这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 空间逃荒:团宠小尼姑路子野 别慌,学霸老爹和我一起穿越了 薄先生突然黏她上瘾 团宠崽崽是只桃花精 我那老板柔弱不能自理 反派小媳妇的逆袭指南 我有一个大佬群 二婚后,我在豪门扮柔弱 诸天仙神热搜:主神老婆竟是魔尊 团宠小福妻又娇又软 替嫁医妃有空间 重生之农门贵夫 野性偏爱 嫁给病弱太子后我躺赢了 咸鱼娘娘一心只想翻墙 救命!破产后高冷总裁处处招惹我 冷酷将军每天都想要贴贴 何以赎光 甜腻!病娇傅少竟然暗恋我! 天价萌妻:偏执帝少心尖宠 有读心术后,战神把娘子宠上天 穿书后,我刷错了反派的好感度 摄政王怀里的团宠美人娇又软 满级千金不想掉马 女帝她就是个卖药的! 华娱激荡年代 她来看我的演唱会 快穿:娇养反派大佬做替身 不努力种田就要和相公继承皇位了 穿书末世之我是金手指 转生恶少后的魔幻日常 穿书后我成了反派男二的铁血妈粉 带着超市重返年代 新婚夜,我被冷冰冰的王爷读心了 修仙女配拿了反派剧本 影后的假面童话 克死前夫后我成了心软的神 新婚夜,我治好了失明太子的隐疾 沦陷野玫瑰 完球!我的崽居然是反派 重生后她被憨憨相公娇宠了