填充二值图像的孔洞是一个非常常见的方法,因为某些原因我不得不用python来写我的程序,当我想要使用类似于MATLAB 中的imfill 方法时, 我最初发现的是opencv 中的cv2.floodFill 的方法,其实现的过程有点麻烦,而且实现的效果不尽人意。在意外中发现scipy库已经实现了填充孔洞的方法,而且实现的过程如同MATLAB那样的简洁。
1、使用Matlab 的imfill 进行填充图像
imfill是matlab的一个函数,在http://www.mathworks.cn/cn/help/images/ref/imfill.html 中有详细的讲解。
简单的举例:
clc;
clear;
BW = im2bw( imread('imfilltest.tif'));
imshow(BW);
holes = imfill(BW, 'holes');
BW(~holes) = 1;
figure,imshow(holes);
2、使用python-opencv实现孔洞的填充
这个方法也不多fei话,直接上实现的代码
im_floodfill = mask.copy()
maskS = np.zeros((imgClean.shape[0] + 2, imgClean.shape[1] + 2), dtype=np.uint8)
cv2.floodFill(im_floodfill, maskS, (0, 0), 255) # 核心代码
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
im_out = mask | im_floodfill_inv
3、使用python(scipy)中的scipy.ndimage.binary_fill_holes来填充孔洞
这个方法跟MATLAB的imfill一样简洁方便。官网见链接
语法:
scipy.ndimage.binary_fill_holes(
input,
structure=None,
output=None,
origin=0
)
参数说明:
- input:待填充的二值图像
- structure:用于计算的结构元素。大尺寸的元素可以使计算速度更快,但可能会漏掉与背景被薄区域隔开的洞。默认元素(具有等于1的方形连通性)会产生直观的结果,其中输入中的所有孔都已填充。
- output:已经填充的输出结果
- origin:结构元素的位置。
举例说明:
from scipy import ndimage
a = np.zeros((5, 5), dtype=int)
a[1:4, 1:4] = 1
a[2,2] = 0
a
# array([[0, 0, 0, 0, 0],
# [0, 1, 1, 1, 0],
# [0, 1, 0, 1, 0],
# [0, 1, 1, 1, 0],
# [0, 0, 0, 0, 0]])
ndimage.binary_fill_holes(a).astype(int)
# array([[0, 0, 0, 0, 0],
# [0, 1, 1, 1, 0],
# [0, 1, 1, 1, 0],
# [0, 1, 1, 1, 0],
# [0, 0, 0, 0, 0]])
# Too big structuring element
ndimage.binary_fill_holes(a, structure=np.ones((5,5))).astype(int)
# array([[0, 0, 0, 0, 0],
# [0, 1, 1, 1, 0],
# [0, 1, 0, 1, 0],
# [0, 1, 1, 1, 0],
# [0, 0, 0, 0, 0]])