我是靠谱客的博主 粗心网络,最近开发中收集的这篇文章主要介绍opencv之GrabCut&FloodFill分割,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1)GrabCut图像分割算法
Opencv中的GrabCut算法是Graphcut算法的改进,Graphcut是一种直接基于图割算法的图像分割技术,仅仅需要确认前景和背景的输入,该算法就可以完成前景和背景的最优分割,该算法利用图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作就可得到比较好的分割结果,和分水岭算法比较相似,但是计算速度比较慢,得到的结果比较精确,如果从静态图像中提取前景物体(如从一个图像剪切物体到另一个图像)采用GrabCut算法就是最好的选择
用法很简单:只需输入一幅图像,并对一些像素做属于背景或者前景的标记,算法就会根据这个局部标记,计算出整个图像中前景和背景的分割线
参考源码
D:opencvsourcesmodulesimgrocsrcgrabcut.cpp
参考例程
D:opencvsourcessamplescppgrabcut.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);

最后

以上就是粗心网络为你收集整理的opencv之GrabCut&FloodFill分割的全部内容,希望文章能够帮你解决opencv之GrabCut&FloodFill分割所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部