目录
一 漫水填充算法--FloodFill
二 涉及的函数
三 实践
一 漫水填充算法--FloodFill
FloodFill漫水填充算法就是选中与种子点相连接的区域,利用指定颜色进行区域颜色填充。可以通过设置连通方式或像素的范围控制填充的效果。通常是用来标记或者分离图像的一部分,以便做进一步分析和处理。
二 涉及的函数
cv2.floodFill()函数原型如下:
cv2.floodFill(image, mask, seedPoint, newVal, loDiff=None, upDiff=None, flags=None)
输入:
①image:【输入/输出】1或者3通道、 8bit或者浮点图像。仅当参数flags的FLOODFILL_MASK_ONLY标志位被设置时image不会被修改,否则的话,image会被修改。
②mask:【输入/输出】 操作掩码,必须为单通道、8bit,且比原图image宽、高多2个像素。使用前必须先初始化。只有对于掩码层上对应为0的位置才能泛洪,所以掩码层初始化为0矩阵。
③seedPoint:漫水填充的种子点,起始像素点。根据该点的像素判断决定和其相近颜色的像素点,是否被泛洪处理。
④newVal:被填充的像素点的新像素值(B,G,R)。
⑤loDiff:(loDiff1,loDiff2,loDiff3),添加进种子点区域条件的下界差值。例如,seed(B0,G0,R0),泛洪区域下界为(B0-loDiff1,G0-loDiff2,R0-loDiff3)。
⑥upDiff:(upDiff1,upDiff2,upDiff3),添加进种子点区域条件的上界差值。例如,seed(B0,G0,R0),泛洪区域上界为(B0+upDiff1,G0+upDiff2,R0+upDiff3)。
⑦flag:为泛洪算法的处理模式。
当为CV_FLOODFILL_FIXED_RANGE时,待处理的像素点与种子点作比较,在范围之内,则填充此像素 。 改变图像,填充newvalue。
当为CV_FLOODFILL_MASK_ONLY 时,函数不填充原始图像iamge,而是填充掩码图像。不改变原图像,也就是newvalue参数失去作用,而是改变对应区域的掩码。
返回:
①image:【输入/输出】
②mask:【输入/输出】 操作掩码。
三 实践
实践①:不同的seedPoint
- 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):
b, g, r = cv2.split(img)
img_rgb = cv2.merge([r, g, b])
return img_rgb
def dealImageResult(img_path):
im = cv2.imread(img_path)
h, w = im.shape[:2]
im1 = im.copy()
im2 = im.copy()
im3 = im.copy()
im4 = im.copy()
im5 = im.copy()
mask1 = np.zeros([h+2, w+2], np.uint8)
mask2 = np.zeros([h+2, w+2], np.uint8)
mask3 = np.zeros([h+2, w+2], np.uint8)
mask4 = np.zeros([h+2, w+2], np.uint8)
mask5 = np.zeros([h+2, w+2], np.uint8)
cv2.floodFill(im1, mask1, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im2, mask2, (90, 80), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im3, mask3, (100, 150), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im4, mask4, (180, 180), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im5, mask5, (200, 190), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
fig = plt.figure(figsize=(10, 10))
im = dealImg(im)
im1 = dealImg(im1)
im2 = dealImg(im2)
im3 = dealImg(im3)
im4 = dealImg(im4)
im5 = dealImg(im5)
titles = ["img", "seedPoint=(20, 20)", "seedPoint=(40, 40)", "seedPoint=(60, 70)", "seedPoint=(100, 150)", "seedPoint=(200, 190)"]
images = [im, im1, im2, im3, im4, im5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], "gray")
plt.title("{}".format(titles[i]), fontsize=20, ha='center')
plt.xticks([]), plt.yticks([])
# plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)
# plt.tight_layout()
plt.show()
fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':
dealImageResult("4.jpeg")
pass
- 效果图
实践②:指定位置的填充
- 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):
b, g, r = cv2.split(img)
img_rgb = cv2.merge([r, g, b])
return img_rgb
def dealImageResult(img_path):
im = cv2.imread(img_path)
h, w = im.shape[:2]
print(h, w)
im1 = im.copy()
im2 = im.copy()
im3 = im.copy()
mask1 = np.ones([h+2, w+2], np.uint8)
mask1[0:100, 0:100] = 0
mask2 = np.ones([h+2, w+2], np.uint8)
mask2[0:200, 0:200] = 0
mask3 = np.ones([h+2, w+2], np.uint8)
mask3[0:w, 0:h] = 0
cv2.floodFill(im1, mask1, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im2, mask2, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
cv2.floodFill(im3, mask3, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
fig = plt.figure(figsize=(10, 10))
im = dealImg(im)
im1 = dealImg(im1)
im2 = dealImg(im2)
im3 = dealImg(im3)
titles = ["img", "mask1_result", "mask2_result", "mask3_result"]
images = [im, im1, im2, im3]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.imshow(images[i], "gray")
plt.title("{}".format(titles[i]), fontsize=20, ha='center')
plt.xticks([]), plt.yticks([])
# plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)
# plt.tight_layout()
plt.show()
fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':
dealImageResult("4.jpeg")
pass
- 效果图
前文回顾
入门篇目录
数字图像处理(入门篇)一 图像的数字化与表示
数字图像处理(入门篇)二 颜色空间
数字图像处理(入门篇)三 灰度化
数字图像处理(入门篇)四 像素关系
数字图像处理(入门篇)五 图像数据预处理之颜色空间转换
数字图像处理(入门篇)六 图像数据预处理之坐标变化
数字图像处理(入门篇)七 图像数据预处理之灰度变化
数字图像处理(入门篇)八 图像数据预处理之直方图
数字图像处理(入门篇)九 图像数据预处理之滤波
数字图像处理(入门篇)十 边缘检测
数字图像处理(入门篇)十一 形态学处理
数字图像处理(入门篇)十二 自适应阈值分割
数字图像处理(入门篇)十三 仿射变换
数字图像处理(入门篇)十四 透视变换
实践篇目录
数字图像处理(实践篇)一 将图像中的指定目标用bBox框起来吧!
数字图像处理(实践篇)二 画出图像中目标的轮廓
数字图像处理(实践篇)三 将两张图像按照指定比例融合
数字图像处理(实践篇)四 图像拼接-基于SIFT特征点和RANSAC方法
数字图像处理(实践篇)五 使用Grabcut算法进行物体分割
数字图像处理(实践篇)六 利用hough变换进行直线检测
数字图像处理(实践篇)七 利用霍夫变换进行圆环检测
数字图像处理(实践篇)八 Harris角点检测
数字图像处理(实践篇)九 基于边缘的模板匹配
数字图像处理(实践篇)十 图像质量检测
数字图像处理(实践篇)十一 图像中的条形码解析
数字图像处理(实践篇)十二 基于小波变换的图像降噪
数字图像处理(实践篇)十三 数据增强之给图像添加噪声!
数字图像处理(实践篇)十四 图像金字塔
数字图像处理(实践篇)十五 基于傅里叶变换的高通滤波和低通滤波
数字图像处理(实践篇)十六 基于分水岭算法的图像分割
数字图像处理(实践篇)十七 Shi-Tomasi 角点检测
数字图像处理(实践篇)十八 人脸检测