OpenCV学习09_图像漫水填充

一、基本思想

所谓漫水填充,简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色 ,这是个非常有用的功能,经常用来标记或者分离图像的部分进行处理或分析。漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点。

以此填充算法为基础,类似PhotoShop的魔术棒选择工具就很容易实现了。漫水填充(FloodFill)是查找和种子点连通的颜色相同的点,魔术棒选择工具则是查找和种子点连通的颜色相近的点,把和初始种子像素颜色相近的点压进栈做为新种子。在OpenCV中,漫水填充是填充算法中最通用的方法。

且在OpenCV 2.X中,使用C++重写过的FloodFill函数有两个版本:一个不带掩膜mask的版本,和一个带mask的版本。这个掩膜mask,就是用于进一步控制哪些区域将被填充颜色(比如说当对同一图像进行多次填充时)。这两个版本的FloodFill,都必须在图像中选择一个种子点,然后把临近区域所有相似点填充上同样的颜色,不同的是,不一定将所有的邻近像素点都染上同一颜色,漫水填充操作的结果总是某个连续的区域。当邻近像素点位于给定的范围(从loDiff到upDiff)内或在原始seedPoint像素值范围内时, FloodFill函数就会为这个点涂上颜色。

二、实现漫水填充算法: foodFill函数

在OpenCV中,漫水填充算法由floodFill函数实现,其作用是用我们指定的·颜色从种子点开始填充一个连接域。连通性由像素值的接近程度来衡量。OpenCV有两个C++重写版本的floodFill,具体如下。

int floodFill(InputOutputArray image,
              Point seedPoint, Scalar newVal, CV_OUT Rect* rect = 0,
              Scalar loDiff = Scalar(), Scalar upDiff = Scalar(),
              int flags = 4 );
int floodFill(InputOutputArray image, InputOutputArray mask,
              Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
              Scalar loDiff = Scalar(), Scalar upDiff = Scalar(),
              int flags = 4 );

下面是参数详解。这两个版本除了第二个参数外,其他的参数都是共用的。

  • (1)第一个参数, InputOutputArray类型的image,输入/输出1通道或3通道,8位或浮点图像,具体参数由之后的参数指明。
  • (2)第二个参数, InputOutputArray类型的mask,这是第二个版本的floodFill独享的参数,表示操作掩模。它应该为单通道,8位,长和宽上都比输入图像image大两个像素点的图像。第二个版本的floodFill需要使用以及更新掩膜,所以对于这个mask参数,我们一定要将其准备好并填在此处。需要注意的是,漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,掩膜mask会比需填充的图像大,所以mask中与输入图像(x.y)像素点相对应的点的坐标为(x+1,y+1)。
  • (3)第三个参数, Point类型的seedPoint,漫水填充算法的起始点。
  • (4)第四个参数, Scalar类型的newVal,像素点被染色的值,即在重绘区域像素的新值。
  • (5)第五个参数, Rect*类型的rect,有默认值0,一个可选的参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
  • (6)第六个参数, Scalar类型的loDiff,有默认值Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差(lower brightness/color difference)的最大值。
  • (7)第七个参数, Scalar类型的upDiff,有默认值Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差(lower brightness/color difference)的最大值。
  • (8)第八个参数, int类型的flags,操作标志符,此参数包含三个部分,比较复杂,我们一起详细看看。
  • 低八位(第0 ~7位)用于控制算法的连通性,可取4(4为默认值)或者8.如果设为4,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点;如果设为8,除上述相邻点外,还会包含对角线方向的相邻点。
  • 高八位部分(16~23位)可以为0或者如下两种选项标识符的组合。

FLOODFILL_FIXED_RANGE:如果设置为这个标识符,就会考虑当前像素与种子像素之间的差,否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。
FLOODFILL_MASK_ONLY:如果设置为这个标识符,函数不会去填充改变原始图像(也就是忽略第三个参数newVal) ,而是去填充掩模图像(mask)。这个标识符只对第二个版本的floodFill有用,因第一个版本里面压根就没有mask参数。
中间八位部分,上面关于高八位FLOODFILL MASK ONLY标识符中已经说得很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。

而所有flags可以用or操作符连接起来,即"|"。

三、示例

int main()
{
	//载入原始图   
	Mat src = imread("F:\\CV\\LearnCV\\files\\maliao.jpg");
	//创建窗口   
	imshow("【原始图】", src);
	Rect ccomp;
	floodFill(src, Point(1, 1), Scalar(0, 255, 0), &ccomp, Scalar(20, 20, 20), Scalar(20, 20, 20));
	imshow("【漫水填充效果图】", src);
	waitKey(0);
	return 0;
}

在这里插入图片描述
可以看到与(1,1)像素相同的颜色被填充成了自定义的颜色。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值