如何从图像中删除所有行?(水平、垂直、对角线)

4

我需要去除一张图片中的线条,该图片实际上是一张表格。我已经找到了一种去除水平和垂直线条的方法:

convert 1.jpg -type Grayscale -negate -define morphology:compose=darken -morphology Thinning 'Rectangle:1x80+0+0<' -negate out.jpg

以下图片:

enter image description here

已转换为以下图像:

enter image description here

可以看到,对角线仍然存在。我尝试将图像旋转45度,然后再尝试移除它,但也不成功。如何完成这个任务?欢迎任何建议。我选择了ImageMagick,但也接受其他选项。

我猜你可以使用霍夫变换来找到线条,然后在黑色背景上用白色画出该线条,并使用“加亮”模式合成到原图上。 - Mark Setchell
2个回答

4
这里是另一种方法。我使用Imagemagick,因为我不熟练OpenCV。基本上,我将图像二值化。然后进行连通组件处理以隔离最大的连续黑色区域,这将是您想要排除的黑线。然后使用它作为掩模,在线条上填充白色。这是带有Imagemagick的Unix语法。
请注意,如果某些文本字符接触到黑线,则会丢失它们。
输入:

enter image description here

获取最大黑色区域的id编号:
id=`convert Arkey.jpg -threshold 50% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-connected-components 4 null: |\
grep "gray(0)" | head -n 1 | sed -n 's/^ *\(.*\):.*$/\1/p'`

孤立黑色线条并进行膨胀处理
convert Arkey.jpg -threshold 50% -type bilevel \
-define connected-components:mean-color=true \
-define connected-components:keep=$id \
-connected-components 4 \
-alpha extract \
-morphology dilate octagon:2 \
mask.png


enter image description here

使用掩码控制,在图像线条上涂白色:
convert Arkey.jpg \( -clone 0 -fill white -colorize 100 \) mask.png -compose over -composite result.png


enter image description here

请查看https://imagemagick.org/script/connected-components.php上的-connected-components以了解其工作原理。


3

您可以尝试使用 cv2.HoughLinesP() 来检测对角线,然后使用掩膜来填充轮廓。

import cv2
import numpy as np

image = cv2.imread('1.jpg')
mask = np.zeros(image.shape, np.uint8)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray,100,200)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
minLineLength = 10
maxLineGap = 350
lines = cv2.HoughLinesP(close,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(mask,(x1,y1),(x2,y2),(255,255,255),3)

mask = cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(mask, 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), -1)

cv2.imshow('mask', mask)
cv2.imshow('image', image)
cv2.imwrite('image.png', image)
cv2.waitKey()

1
好的回答。在找到这些线之后,您可以考虑使用修复算法来填充它们,而不仅仅是用白色填充:https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_photo/py_inpainting/py_inpainting.html - L. Scott Johnson
但这对我没用。这个遮罩只是从中间移除了一个矩形区域。有人真的运行和测试过这段代码吗? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接