Remove noisy lines from an image

Detecting lines like these is what the path opening was invented for. DIPlib has an implementation (disclosure: I implemented it there). As an alternative, you can try using the implementation by the authors of the paper that I linked above. That implementation does not have the "constrained" mode that I use below.

Here is a quick demo for how you can use it:

import diplib as dip
import matplotlib.pyplot as pp

img = 1 - pp.imread('/home/cris/tmp/DWRTF.png')
lines = dip.PathOpening(img, length=300, mode={'constrained'})

Here we first inverted the image because that makes other things later easier. If not inverting, use a path closing instead. The lines image:

lines

Next we subtract the lines. A small area opening removes the few isolated pixels of the line that were filtered out by the path opening:

text = img - lines
text = dip.AreaOpening(text, filterSize=5)

text

However, we've now made gaps in the text. Filling these up is not trivial. Here is a quick-and-dirty attempt, which you can use as a starting point:

lines = lines > 0.5
text = text > 0.5
lines -= dip.BinaryPropagation(text, lines, connectivity=-1, iterations=3)
img[lines] = 0

final result


You can do that using createLineSegmentDetector(), a function from opencv

import cv2

#Read gray image
img = cv2.imread("lines.png",0)

#Create default parametrization LSD
lsd = cv2.createLineSegmentDetector(0)

#Detect lines in the image
lines = lsd.detect(img)[0] #Position 0 of the returned tuple are the detected lines

#Draw the detected lines
drawn_img = lsd.drawSegments(img,lines)

#Save the image with the detected lines
cv2.imwrite('lsdsaved.png', drawn_img)

enter image description here
The next part of the code will delete only the lines which their length is more than 50 pixels:

for element in lines:

  #If the length of the line is more than 50, then draw a white line on it
  if (abs(int(element[0][0]) - int(element[0][2])) > 50 or abs(int(element[0][1]) - int(element[0][3])) > 50): 

    #Draw the white line
    cv2.line(img, (int(element[0][0]), int(element[0][1])), (int(element[0][2]), int(element[0][3])), (255, 255, 255), 12)

#Save the final image
cv2.imwrite('removedzz.png', img)

enter image description here

Well, it didn't work perfectly with the current image, but it may give better results with different images. You can adjust the length of the lines to remove and the thickness of the white lines to draw insteaad of the removed lines.
I hope it helps.