去除图像中的倾斜水平线

时间:2019-09-07 14:35:11

标签: python image opencv image-processing line

original image

我有一幅图像,其中在文本下方有一条水平线;通过各种技术申请后HoughLineP和HoughLine以及此代码

 image = cv2.imread('D:\\detect_words.jpg')
 gray = 255 - cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 for row in range(gray.shape[0]):
    avg = np.average(gray[row, :] > 16)
    if avg > 0.25:
        cv2.line(image, (0, row), (gray.shape[1]-1, row), (0, 0, 255))
        cv2.line(gray, (0, row), (gray.shape[1]-1, row), (0, 0, 0), 1)
  cv2.imwrite('D:\\words\\final_removed.jpg',image)

我能够做到这一点 after processing

此阶段之后;我正在应用侵蚀和扩张

kernel = np.ones((3,3), np.uint8) 
img_erosion = cv2.erode(255-gray, kernel, iterations=1) 
img_dilation = cv2.dilate(img_erosion, kernel, iterations=1) 
cv2.imwrite('D:\\words\\final_removed4.jpg',255-img_dilation)

final image after dilation and erosion

我的问题是;尽管去除了水平线,但是去除了,但是单词有像素损失;并没有删除所有水平线。是否有一种新颖的方法可以将这种损失降到最低,并消除所有水平线(此处仍然存在AGE以上的水平线)。

1 个答案:

答案 0 :(得分:1)

这是一种方法:

  • 将图像转换为灰度
  • 大津获取二进制图像的阈值
  • 创建水平核并将其变形以检测线
  • 找到轮廓并绘制检测到的线

转换为灰度后,我们以Otsu的阈值获取二进制图像

enter image description here

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

现在,我们创建一个特殊的水平核以检测水平线,然后变形打开以获取检测到的线的蒙版

enter image description here

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (45,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

这是在原始图像上绘制的检测到的线条

enter image description here

从这里我们在此蒙版上找到轮廓,然后将其绘制以有效去除水平线以获得结果

enter image description here

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 3)

现在除去水平线,以修复文本,您可以使用cv2.MORPH_CLOSE内核尝试cv2.MORPH_CROSS并尝试各种内核大小。在过度扩张以闭合孔之间存在折衷,因为文本中的细节将丢失。另一种方法是使用image inpainting填补漏洞。我会把这一步留给你

完整代码

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (45,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 3)

cv2.imshow('thresh', thresh)
cv2.imshow('detected_lines', detected_lines)
cv2.imshow('image', image)
cv2.waitKey()