前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV-泛洪填充

OpenCV-泛洪填充

作者头像
触摸壹缕阳光
发布2019-11-13 19:50:30
1.1K0
发布2019-11-13 19:50:30
举报

泛洪填充简单理解就是将指定颜色从指定位置开始填充一个连通区域,此时的连通性由像素值的接近程度来衡量。OpenCV中提供两种泛洪填充方式:

  1. 填充彩色图像;
  2. 填充掩码图像。

下面先来看看在OpenCV中泛洪填充的函数。

01

OpenCV中泛洪填充函数

OpenCV提供了floodFill函数进行泛洪填充,函数的完整定义:

floodFill(image, mask, seedPoint, newVal, loDiff, upDiff, flags)具体参数如下:

1. image,需要进行泛洪填充的原始图像;

2. msak,一个二值矩阵也就是说里面元素值要不为0要不为1;

3. seedPoint,种子像素,填充的起始点像素

4. newVal,要填充的颜色;

5. loDiff,规定像素值的下限;

6. upDiff,规定像素值的上限;

7. flags,填充的方法。

这里需要说明一点,在图像上会被填充的像素值的范围是[seedPoind.BGR - lowDiff, seedPoint.BGR + upDiff]。

有了函数定义,接下来就看一看这两种泛洪填充方式吧。

02

填充彩色图像

对于填充彩色图像,我们需要使用像素值的接近程度来决定是否进行填充,此时需要指定一个起始点,规定像素值的上下限,只要与起始点连接并且其像素值在定义的范围之内,则会被填充,然后这个被填充的点连接的点,哪一个点的像素值在上面定义的范围之内,也会被填充,如此往复,由此可以看出位置被填充的条件:

  1. 与起始点或者其他被填充的点相连接;
  2. 此位置的像素在指定范围之内。

使用"my_love.jpg"的图片:

具体代码如下:

效果如下:

此时需要注意两点:

  1. mask只能取0,1值,此时0,1起到一个锁定图像,
    1. 当mask对应位置为0的区域会被填充;
    2. 当mask对应位置为1的区域会被锁定,也就是不能被填充。

而且必须要比原始图像的宽高上加两个像素,这是OpenCV强制的,如果不这样指定会抛出异常;

  1. cv.FLOODFILL_FIXED_RANGE,这也是使用填充图片的方式参数,也就是设定起始点,通过设置像素区间来进行填充,这种方式直接在图像自身上进行填充,此时的掩码mask只起到锁定不被填充的区域
  2. seedPoint参数需要特别注意,seedPoint表示的是起始点,在前面获取ROI的时候,通过对像素ndarray数组,通过切片的方式获取ROI区域,我们当时将像素矩阵看成是一个高*宽维度的矩阵,想获取图像中的某一区域直接获取相应矩阵的区域即可。但是seedPoint是将图片放在一个二维的坐标系中,即(x, y),通过(x, y)来选择指定位置。具体如下图所示:

前面说到在此模式下,mask二值掩码(只能取0或1)能够锁定被图片不被填充,比如在上面的填充图片中,我们想保留头部分不被填充,在提取ROI的时候我们已经提取过这一范围了,具体的只需要将这一区域mask值设置为1即可:

代码语言:javascript
复制
# 锁定不被填充的区域mask[151:501, 161:551] = 1

此时需要注意mask掩码的比原始图片长宽都大了两个像素,因此如果选择指定范围,需要加上1即可。具体效果如下:

从上图也可以看出,阻断了像素的连通性,也是不会被填充的。

03

填充掩码图像

掩码就是前面所说的mask二值,前面说的填充图像,mask只起到锁定图像的作用,而在填充掩码图像的模式下,不直接对图像进行填充,而是对掩码进行填充。当设置这种填充掩码图像的模式的时候(cv.FLOODFILL_MASK_ONLY),loDiff,规定像素值的下限,upDiff,规定像素值的上限,自动会失效。此时为了效果明显使用纯色进行试验,因为此时填充没有了像素范围,也就是当设置cv.FLOODFILL_MASK_ONLY的时候,原始图片起始点周边只能是完全相同的像素值才能被填充。

执行效果如下:

下面来具体分析,原始图像如下图所示:

此时mask二值掩码都为0,也就是说整张图片都可以进行填充。此时seedPoint值为(0, 0),也就是左上角,因为左上角对于原始图像来说,有一个范围都是白色,因此就会把这些具有相同像素值的白色进行填充。接下来再来看一个例子:

执行效果如下所示:

接下来具体分析一下,原始图像和上面一样:

此时的mask二值掩码就有很大的不同,此时为了表示方便,将可以填充区域,即值为0的区域用绿色进行显示,当然这并不是mask的真实效果,mask是拥有单通道的0,1值,如果将其显示是黑色的图像。

此时将原始图片和mask结合:

此时设置seedPoint为(0, 0),即左上角,左上角相同颜色就是白色,但是此时二值图像只有绿色区域可以被填充,因此最终的效果:

也就是说,如果使用填充掩码的方式,要被填充必须具备两个条件:

  1. 起始点周边相同的像素点;
  2. mask二值掩码值必须为0,而且需要注意,此时颜色是填充在mask二值掩码上,而不改变原始图像。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档