opencv之GrabCut&FloodFill分割

1)GrabCut图像分割算法
Opencv中的GrabCut算法是Graphcut算法的改进,Graphcut是一种直接基于图割算法的图像分割技术,仅仅需要确认前景和背景的输入,该算法就可以完成前景和背景的最优分割,该算法利用图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作就可得到比较好的分割结果,和分水岭算法比较相似,但是计算速度比较慢,得到的结果比较精确,如果从静态图像中提取前景物体(如从一个图像剪切物体到另一个图像)采用GrabCut算法就是最好的选择
用法很简单:只需输入一幅图像,并对一些像素做属于背景或者前景的标记,算法就会根据这个局部标记,计算出整个图像中前景和背景的分割线
参考源码
D:\opencv\sources\modules\imgroc\src\grabcut.cpp
参考例程
D:\opencv\sources\samples\cpp\grabcut.cpp
GrabCut算法–grabcut()
void grabCut(InputArray img,InputOutputArray mask,Rect rect,InputOutputArray bgdModel,InputOutputArray fgdModel,int iterCount,int mode=GC_EVAL);
**img:待分割原图像,需为8位三通道彩色图像
**mask:8位单通道掩码图像,如果使用掩码进行初始化,那么mask保存掩码信息,在执行分割的时候,也可以将用户交互所设定的前景和背景保存到mask中,然后再传入grabCut函数,在处理结束之后,mask会保存结果,Mask只能取4种可能的值:
GC_BGD:表示明确属于背景的像素
GC_FGD:表示明确属于前景的像素
GC_PR_BGD:表示可能属于背景的像素
GC_PR_FGD:表示可能属于前景的像素
如果没有手动标记GC_BGD或者GC_FGD那么结果只会有GC_PR_BGD或GC_PR_FGD
GC_BGD=0,//!

//利用Rect做分割
Mat src=imread("bird.jpg");
Rect rect(84,84,406,318);
Mat result;
Mat bgModel,fgModel;
grabCut(src,result,rect,bgModel,fgModel,1,GC_INIT_WITH_RECT);
imshow("grab",result);
//threshold();//二值化就可以显示
compare(result,GC_PR_FGD,result,CMP_EQ);
//result=result&1; 两种方法``
imshow("result",result);
Mat foreground(src.size(),CV_8UC3,Scalar(255,255,255));
src.copy(forground,result);
imshow("forground",forground);
waitKey(0);
Mat src=imread("bird.jpg");
Rect rect;
Mat bgModel,fgModel;
Mat result(src.sizer(),CV_*U,Scalar(0));
Mat ROI(result(Rect(84,84,406,318));
ROI.setTo(GC_PR_FGD);
grabCut(src,result,rect,bgModel,fgModel,1,GC_INIT_WITH_MASK);
imshow("grab",result);
compare(result,GC_PR_FGD,result,CMP_EQ);
imshow("result",result);
Mat foreground(src.size(),CV_8UC3,Scalar(255,255,255));
src.copyTo(forground,result);
imshow("forground",forgeound);
waitKey(0);

2)漫水填充算法–floodFill
FloodFill漫水填充算法是在很多图形绘制软件中常用的填充算法,通常是说自己选中与种子像素相连的区域,利用指定颜色进行区域颜色填充,常用于标记或分离图像的一部分,以便做进一步分析和处理,
原理:就是从一个点开始遍历附近像素点,填充成新的颜色,直到封闭区域内所有像素点都被填充成新颜色为止,FloodFill填充的实现方法常见的有4邻域像素填充法,8邻域像素填充法,基于扫描线的像素填充方法
floodFill()
int floodFill(InputOutputArray image,Point seedPoint,Scalar newVal,CV_OUT Rect*rect=0,Scalar loDiff=Scalar(),Scalar upDiff=Scalar(),int flag=4);
int floodFill(InputOutArray image,InputOutputArray mask,Point seedPoint,Scalar newVal,CV_OUT Rect *rect=0,Scalar loDiff=Scalar(),Scalar upDiff=Scalar(),int flag=4);
&&image:输入/输出单通道或3通道8位或浮点图像
&&mask:操作掩码,应为8位单通道且长和宽比输入图像大两个像素点的图像,漫水填充不会填充mask的非零像素区域(可以用边缘检测算子输出来防止漫充到边界),mask中与输入图像(x,y)像素点对应的点坐标(x+1,y+1);
&&seedPoint:种子点,漫水填充算法的起始点
&&newVal:像素点被染颜色的值,即在重绘区域像素的新值
&&rect:Rect*类型,默认值0可选参数,用来设置floodFill函数将要重绘区域的最小边界矩形区域
&&loDiff:默认值Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的像素之间的亮度或颜色之负差的最大值
&&upDiff:默认值Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差最大值
&&flags:操作标识符,包含三部分
低八位(0-7位):用于控制算法的连通性可以取4(默认)或8
高八位(16-32位):可以为0或者如下两种标志符的组合
FLOODFILL_FIXED_RANGE:设置此标志符会考虑当前像素与种子像素之间的差,否则会考虑当前像素与其相邻像素的差
FLOODFILL_MASK_ONLY:设置此标志符,函数不会去填充改变原始图像,也就是忽略第三个参数newVal而是去填充掩码图像mask,中间八位(8-15位)用来指定填充掩码图像的值,但是如果中间8为0则掩码用1来填充`

Mat srcImg=imread("bird.jpg");
imshow("src",srcImg);
Rect rect;
floodFill(srcImg,Point(20,20),Scalar(255,0,255),&rect,Scalar(10,10,10),Scalar(10,10,10));
imshow("result",srcImg);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值