08 泛洪填充 Opencv泛洪填充floodFill详细讲解

算法的原理很简单,就是从一个点开始,将附近满足像素要求的点全部填充成指定的颜色,直到封闭区域内的所有像素点都被填充新颜色为止。
我们以这张图片为例
08 泛洪填充 Opencv泛洪填充floodFill详细讲解_第1张图片
代码如下

import cv2 as cv
import numpy as np


def fill_color_demo(image):
    copyimg = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros([h+2, w+2], np.uint8)
    cv.floodFill(copyimg, mask, (40, 30), (0, 255, 255), (100,100, 100), (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("floodfill", copyimg)
    cv.imwrite("D:/opencv/copyimg.jpg", copyimg)


print("--------- Hello Python ---------")
src = cv.imread("D:/opencv/color.jpg")
print(src.shape)
cv.namedWindow("color", cv.WINDOW_AUTOSIZE)
cv.imshow("color", src)
fill_color_demo(src)
print(src.shape)


cv.waitKey(0)
cv.destroyAllWindows()

floodFill共包含7个参数:
1.操作的图像
2.掩模
3.起始的像素点
4.填充的颜色
5.loDiff:填充颜色的低值(起始像素点处颜色减去该值)
6.upDiff:填充颜色的高值 (起始像素点处颜色加上该值)
7.填充的方法,彩色图像一般是FLOODFILL_FIXED_RANGE 指定颜色填充

下面是我个人的理解:
运行该函数时,首先找到图像上的起始像素点,从该点开始,将其附近满足填充颜色范围(起始像素点处颜色减加低高值)的像素点填充上指定颜色,直至整个封闭区域都填充完毕。
此处的封闭区域是指满足填充范围的区域,如果碰到不满足范围的区域,则会停止填充

运行代码后,结果如下:
08 泛洪填充 Opencv泛洪填充floodFill详细讲解_第2张图片
根据代码内容,填充过程如下:
首先找到(40,30)点,以该点为起始点,该点BGR值为(0, 0, 255),减去低值为(0, 0, 155), 加上高值为(50, 50, 255),因此在该范围的像素点将被填充为红色,但白色的BGR值为(255,255,255),黑色的BGR值为(0,0,0),不在该范围内,因此在碰到黑白区域时,填充停止。所以这就解释了为什么右下角的红色没有被填充

改变填充的高低值,将颜色范围变成整个BGR区域:

cv.floodFill(copyimg, mask, (40, 30), (0, 255, 255), (100,100, 255), (255, 255, 255), cv.FLOODFILL_FIXED_RANGE)

此时得到的结果为:
08 泛洪填充 Opencv泛洪填充floodFill详细讲解_第3张图片
这就验证了我们上一步的猜想

注意

print(src.shape)得到的是图像的垂直尺寸、水平尺寸以及通道数目,但在设置起始像素点的坐标时,却是按照(水平位置, 垂直位置)来定义的

在设置mask时,需注意要设置为h+2, w+2

填充方法

除了FLOODFILL_FIXED_RANGE外,还有一种填充方法:
FLOODFILL_MASK_ONLY,mask的指定的位置为零时才填充,不为零不填充

def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300, :] = 255
    cv.imshow("image", image)

    mask = np.ones([402, 402, 1], np.uint8)
    mask[101:301, 101:301] = 0
    cv.floodFill(image, mask, (200, 200), (0, 0, 255), cv.FLOODFILL_MASK_ONLY)
    cv.imshow("fill_binary", image)

首先定义一张图片,颜色为黑色,类型为uint8,然后将中间区域颜色设为白色
再设置mask,将整个mask区域的值设为1,中间区域的值设为0(FLOODFILL_MASK_ONLY只对0进行填充),此处仍要注意h+2!

你可能感兴趣的:(opencv)