OpenCV入门(九)快速学会OpenCV8漫水填充floodFill&ROI
OpenCV入门(九)快速学会OpenCV8漫水填充floodFill&ROI
作者:Xiou
1.漫水填充floodFill
floodFill漫水填充算法是在很多图形绘制软件中常用的填充算法,通常来说是自动选中与种子像素相连的区域,利用指定颜色进行区域颜色填充,常用于标记或分离图像的部分,以便做进一步分析和处理。Windows画图工具中的油漆桶功能和Photoshop的魔术棒选择工具都是floodFill漫水填充方法的改进和延伸。
漫水填充法是一种用特定的颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。漫水填充经常被用来标记或分离图像的一部分,以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域。
漫水填充法的原理很简单,就是从一个点开始遍历附近的像素点,填充成新的颜色,直到封闭区域内所有像素点都被填充成新颜色为止。floodFill填充的实现方法常见的有4邻域像素填充法、8邻域像素填充法、基于扫描线的像素填充法等。
在OpenCV中,漫水填充是填充算法中最通用的方法。使用C++重写过的floodFill函数有两个版本:一个不带mask(掩膜)的版本和一个带有mask的版本。这个mask用于进一步控制哪些区域将被填充颜色(比如说当对同一图像进行多次填充时)。
这两个版本的floodFill都必须在图像中选择一个种子点,然后把临近区域所有相似点填充上同样的颜色,不同的是不一定将所有的邻近像素点都染上同一颜色。漫水填充操作的结果总是某个连续的区域。当邻近像素点位于给定的范围(从loDiff到upDiff)内,或在原始seedPoint像素值范围内时,floodFill函数就会为这个点涂上颜色。
在OpenCV中,漫水填充算法由floodFill函数实现,其作用是用我们指定的颜色从种子点开始填充一个连接域,连通性由像素值的接近程度来衡量。在OpenCV中,有两个C++重写版本的floodFill,函数声明如下:
floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]])
参数:
image: 输入图片
mask: 掩码, 比 image 长宽高 2
seedPoint: 泛洪算法的起始点
newVal: 重绘区域的新值 (颜色)
loDiff: seePoint - loDiff 下限
upDiff: seePoint - upDiff 上限
flags: 操作标志符
LOODFILL_FIXED_RANGE: 改变图像, 泛洪填充
FLOODFILL_MASK_ONLY: 不改变图像, 只填充 mask 本身, 忽略新的颜色值参数。
原图:
代码实例1:
import numpy as np
import cv2
def flood_fill(image):
"""泛洪"""
# 深拷贝
image_copy = image.copy()
# 获取高宽
h, w = image.shape[:2]
# 获取mask
mask = np.zeros([h + 2, w + 2], np.uint8)
# 泛洪
cv2.floodFill(image_copy, mask, (175, 20), (0, 25, 0), (30, 30, 30), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)
# 图片展示
cv2.imshow("flood_fill", image_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 返回
return image_copy
if __name__ == "__main__":
# 读取图片
img = cv2.imread("test.jpg")
# 获取泛洪图像
flood_fill = flood_fill(img)
# 保存图片
cv2.imwrite("flood_fill.jpg", flood_fill)
输出结果:
代码实例2:
import numpy as np
import cv2
def flood_fill():
"""泛洪"""
# 获取图片
image = np.zeros([400, 400, 3], np.uint8)
# 获取mask
mask = np.ones([400 + 2, 400 + 2, 1], np.uint8)
mask[101:301, 101:301] = 0
# 泛洪
cv2.floodFill(image, mask, (200, 200), (100, 2, 255), cv2.FLOODFILL_MASK_ONLY)
# 图片展示
cv2.imshow("flood_fill", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 返回
return image
if __name__ == "__main__":
# 读取图片
#img = cv2.imread("girl3.jpg")
# 获取泛洪图像
flood_fill = flood_fill()
# 保存图片
cv2.imwrite("flood_fill.jpg", flood_fill)
输出结果:
2. ROI(感兴趣区域)
ROI (Region of Interest) 即感兴趣区域, 就是在图像中分析的重点。
在图像处理过程中,我们可能会对图像的某一个特定区域感兴趣,该区域被称为感兴趣区域(Region of Interest, ROI)。在设定感兴趣区域ROI后,就可以对该区域进行整体操作。例如,将一个感兴趣区域A赋值给变量B后,可以将该变量B赋值给另外一个区域C,从而达到在区域C内复制区域A的目的。
例如,在下图中,假设当前图像的名称为img,图中的数字分别表示行号和列号。那么,图像中的黑色ROI可以表示为img[200:400, 200:400]。
通过以下语句,能够将图中的黑色ROI复制到该区域右侧:
a=img[200:400,200:400]
img[200:400,600:800]=a
上述语句对图的处理结果如图所示,在该区域右侧得到了复制的ROI。
用灰度遮住小姐姐的脸部。
代码实例:
import cv2
# 读取图片
img = cv2.imread("girl1.jpg")
# ROI
face = img[100:750, 1000:1600]
# 获取灰度图
face_gray = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
face_gray = cv2.cvtColor(face_gray, cv2.COLOR_GRAY2BGR)
# 用灰度图替换
img[100:750, 1000:1600] = face_gray
# 图片展示
cv2.imshow("ROI", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图片
cv2.imwrite("ROI.jpg", img)
输出结果: