GrabCut

GrabCut简介
    OpenCV中的GrabCut算法是依据《"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts》这篇文章来实现的。该算法利用了图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作即可得到比较好的分割结果。如果前景和背景之间的颜色反差不大,分割的效果不好;不过,这种情况下允许手工标记一些前景或背景区域,这样能得到较好的结果。经我测试,GrabCut算法的效率不高,初始化341x326大小的矩形窗大约需要20秒,处理需要9秒;而论文中宣称初始化450x300大小的矩形窗仅0.9秒,处理只要0.12秒;虽然矩形大小和测试环境稍有区别,但是结果却相差太多。

GrabCut函数说明
函数原型:
    void cv::grabCut( const Mat& img, Mat& mask, Rect rect,
             Mat& bgdModel, Mat& fgdModel,
             int iterCount, int mode )
其中:
img——待分割的源图像,必须是8位3通道(CV_8UC3)图像,在处理的过程中不会被修改;
mask——掩码图像,如果使用掩码进行初始化,那么mask保存初始化掩码信息;在执行分割的时候,也可以将用户交互所设定的前景与背景保存到mask中,然后再传入grabCut函数;在处理结束之后,mask中会保存结果。mask只能取以下四种值:
GCD_BGD(=0),背景;
GCD_FGD(=1),前景;
GCD_PR_BGD(=2),可能的背景;
GCD_PR_FGD(=3),可能的前景。
如果没有手工标记GCD_BGD或者GCD_FGD,那么结果只会有GCD_PR_BGD或GCD_PR_FGD;
rect——用于限定需要进行分割的图像范围,只有该矩形窗口内的图像部分才被处理;
bgdModel——背景模型,如果为null,函数内部会自动创建一个bgdModel;bgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13x5;
fgdModel——前景模型,如果为null,函数内部会自动创建一个fgdModel;fgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13x5;
iterCount——迭代次数,必须大于0;
mode——用于指示grabCut函数进行什么操作,可选的值有:
GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;
GC_INIT_WITH_MASK(=1),用掩码图像初始化GrabCut;
GC_EVAL(=2),执行分割。

GrabCut的用法
    您可以按以下方式来使用GrabCut函数:
(1)用矩形窗或掩码图像初始化grabCut;
(2)执行分割;
(3)如果对结果不满意,在掩码图像中设定前景和(或)背景,再次执行分割;
(4)使用掩码图像中的前景或背景信息。

GrabCut_第1张图片

GrabCut_第2张图片

GrabCut_第3张图片

从上述图片中可以看出,用更多的迭代次数,或者更多的用户交互都能得到更好的结果。

示例
    下面是一个使用GrabCut进行图像分割的例子,其中用了P/INVOKE形式的CvGrabCut函数,以及封装在Image<TColor,TDepth>类中的GrabCut方法。封装的方法便于使用,但是缺少一些功能,灵活性不足。

来自:http://www.cnblogs.com/xrwang/archive/2010/04/27/GrabCut.html

你可能感兴趣的:(算法,测试,null,Graph,2010)