从图像中删除带有删除线的文本

时间:2020-07-01 04:13:55

标签: python opencv image-processing underline strikethrough

这是示例图片->

enter image description here 我想提取具有删除线样式的文本装饰/样式的文本。 因此,对于上面的图片,我想提取-de location

我该怎么做?

这是我到目前为止使用OpenCV和python的内容:

import cv2
import numpy as np
import matplotlib.pyplot as plt
im = cv2.imread(<image>)
kernel = np.ones((1,44), np.uint8)
morphed = cv2.morphologyEx(im, cv2.MORPH_CLOSE, kernel)
plt.imshow(morphed)

这给了我水平线-> enter image description here

我是图像处理的新手,因此很难隔离具有删除线的文本。

奖金->与删除线文本一起,我还要提取邻近的文本,以便可以正确地将删除线文本信息与其他文本一起样式化/标记。

更新1: 根据第一个答案,我做了以下工作:-

import cv2
# Load image, convert to grayscale, Otsu's threshold
image = cv2.imread('image.png')
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + 
cv2.THRESH_OTSU)[1]
# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(40,1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, 
horizontal_kernel, iterations=10)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, 
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(result, [c], -1, (36,255,12), 2)
plt.imshow(result)

我能够得到这张图片- enter image description here

我尝试使用水平内核的值,但是没有运气。

更新2: 我进一步修改了上面的代码片段,并得到了它-

import cv2
import numpy as np
import matplotlib.pyplot as plt
# Load image, convert to grayscale, Otsu's threshold
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

kernel = np.ones((4,2),np.uint8)
erosion = cv2.erode(thresh,kernel,iterations = 1)
dilation = cv2.dilate(thresh,kernel,iterations = 1)

trans = dilation
# plt.imshow(erosion)

# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (8,1))
detect_horizontal = cv2.morphologyEx(trans, cv2.MORPH_OPEN, horizontal_kernel, iterations=10)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(result, [c], -1, (36,255,12), 2)
plt.imshow(result)

我能够得到这张图片- enter image description here 这个解决方案也适用于我的其他图像类型- enter image description here enter image description here

这不是100%准确度的解决方案(无法获得de删除线文字),但到目前为止,我还是很满意的。

现在,我正在努力检查相邻像素是黑色还是白色以隔离删除线。

2 个答案:

答案 0 :(得分:0)

可以实现这一目标的一种方法是:

  1. 使图像(https://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html)相匹配
  2. 查找水平线(Horizontal Line detection with OpenCV
  3. 对于每行,检查顶部和底部像素是否为白色
  4. 如果顶部和底部像素没有白色,则该区域对应于删除线
  5. 执行图像的已连接部分(connected component labeling in python
  6. 检查与先前检测到的行相对应的标签,并屏蔽该标签以获取删除线文本。

答案 1 :(得分:0)

您可以使用删除线属性,例如厚度。删除线的厚度小于下划线。可以通过形态学进行选择,并通过形态重建来恢复连接的成分。

import cv2
img = cv2.imread('juFpe.png', cv2.IMREAD_GRAYSCALE)
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV )[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,5))
kernel2=cv2.getStructuringElement(cv2.MORPH_RECT,(8,8))
detect_thin = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
detect_thin = cv2.morphologyEx(detect_thin, cv2.MORPH_DILATE, kernel2)
marker=cv2.compare(detect_thin, thresh,cv2.CMP_LT) # thin lines
while True: #morphological reconstruction
    tmp=marker.copy()
    marker=cv2.dilate(marker, kernel2)
    marker=cv2.min(thresh, marker)
    difference = cv2.subtract(marker, tmp)
    if cv2.countNonZero(difference) == 0:
        break

cv2.imwrite('lines.png', marker)

结果: enter image description here