我们在进行图像分割后,分割结果有时会有一些小孔洞,如图1所示,其中黑白两色表示两种不同的类别。一般情况下,这些孔洞属于错分情况,为了优化结果,我们通常对这些孔洞进行填充。今天我们就用python语言基于OpenCV实现孔洞填充。图1 有孔洞的分割图像
我们要用到的函数是OpenCV里的floodFill函数。使用floodFill函数可以得到只标记孔洞的像素矩阵(孔洞值为0,非孔洞值为指定值)。有了孔洞的位置填充孔洞就容易多了。python代码如下。
import cv2
import numpy as np
'''图像说明:图像为二值化图像,255白色为目标物,0黑色为背景要填充白色目标物中的黑色空洞'''
def FillHole(imgPath,SavePath):
im_in = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE);
cv2.imwrite("im_in.png",im_in)
# 复制 im_in 图像
im_floodfill = im_in.copy()
# Mask 用于 floodFill,官方要求长宽+2
h, w = im_in.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
# floodFill函数中的seedPoint对应像素必须是背景
isbreak = False
for i in range(im_floodfill.shape[0]):
for j in range(im_floodfill.shape[1]):
if(im_floodfill[i][j]==0):
seedPoint=(i,j)
isbreak = True
break
if(isbreak):
break
# 得到im_floodfill 255填充非孔洞值
cv2.floodFill(im_floodfill, mask,seedPoint, 255)
# 得到im_floodfill的逆im_floodfill_inv
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
# 把im_in、im_floodfill_inv这两幅图像结合起来得到前景
im_out = im_in | im_floodfill_inv
# 保存结果
cv2.imwrite(SavePath, im_out)
填充结果如图2所示,三个孔洞均被填充。图2 填充结果