【问题标题】:Removing slant horizontal lines in image去除图像中的倾斜水平线
【发布时间】:2019-09-10 04:59:41
【问题描述】:

我有一张图片,文字下方有一条水平线;通过各种技术按顺序应用后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)

我能够做到这一点

在这个阶段之后;我正在应用腐蚀和膨胀

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)

我的问题是;去除水平线虽然去除了但单词有像素损失;并不是所有的水平线都被删除了。是否有一种新颖的方法可以最小化这种损失并删除所有水平线(这里 AGE 上方的水平线仍然存在)。

【问题讨论】:

  • 降低 avg > 0.25 中的 0.25,以便 t 过滤掉较小长度的行。或过滤实际线长。删除线条后,您可以尝试打开形态学以填补文本中的空白。
  • 是 OP detect_words.jpg 中的顶部图像还是其中的一部分?您绘制的白线的线条粗细似乎不足以完全擦除底线。遗憾的是线条粗细是一个整数,因此增加到 2 可能太多了。因此,您可能需要缩放整个图像,以使厚度 2 恰到好处。

标签: python image opencv image-processing line


【解决方案1】:

这是一种方法:

  • 将图像转换为灰度
  • Otsu 获取二值图像的阈值
  • 创建水平内核并打开变形以检测线条
  • 查找轮廓并绘制检测到的线条

转换成灰度后,我们用Otsu的阈值得到二值图像

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.MORPH_CLOSEcv2.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()

【讨论】:

  • 非常感谢您的回复。我如何连接缺失 A 的点,就像我在做侵蚀和扩张一样,但是要通过什么矩阵来平滑它。
  • 您可以使用cv2.morphologyEx() 并尝试使用these matrixes 和各种内核大小
猜你喜欢
  • 2020-08-10
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2018-02-26
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多