填充图像中的空封闭部分

时间:2018-12-28 22:59:26

标签: python image-processing python-imaging-library

Before

After

我正在寻找一种算法,该算法可以产生上面显示的结果。到目前为止,我已经尝试过从PIL进行一些扩张和侵蚀,但结果并不是我想要的结果,因为我正在丢失字母的一些基本细节。此外,之后它们往往会变得非常大胆,并且侵蚀也无济于事。我的第二次尝试是某种类型的泛洪算法,但我想不出任何有用的方法,因为某些字母之间存在间隙,并且我不知道该如何处理。如果您能指导我提出一些解决该问题的算法思想,我将不胜感激。

1 个答案:

答案 0 :(得分:3)

正如Mark Setchell所述,您可以使用cv2.findContours,然后使用层次结构来查找字母的空洞。

首先,我找到图像中的所有轮廓。

要查找字母的孔,我使用层次结构来获取没有子级的轮廓(大多数内部轮廓),然后用黑色填充白色(称为蒙版图像)。我还设置了面积阈值,以消除字母内的小黑点并仅保留孔。阈值为area>int(w*h/200),其中w为图片的长度和宽度。

我用黑色填充灰色图像中的轮廓。然后我只需将灰色图像和蒙版图像相加即可得到最终结果。

这是代码。

import cv2
import numpy as np

img = cv2.imread("1.png")

print(img.shape)
w = img.shape[0]
h = img.shape[1]

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY_INV)

im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours,-1,(0,0,255),1)

mask = np.zeros(gray.shape, dtype="uint8")

for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    print(hierarchy[0][i][2])
    if(hierarchy[0][i][2]==-1 and area>int(w*h/200)): #contour has no child
        cv2.fillPoly(mask, pts =[contours[i]], color=255)
    cv2.fillPoly(gray, pts =[contours[i]], color=0)

res = mask + gray

cv2.imshow("img", img)    
cv2.imshow("gray", gray)      
cv2.imshow("mask", mask)
cv2.imshow("res", res)

cv2.waitKey()
cv2.destroyAllWindows() 

enter image description here