How do I remove a line in an image with OpenCV without ruining the rest of the image?

I have an image such as the following:

Original Image

I need to remove the line that the characters are written on, so I use the following code:

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

# Remove horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20,1))
remove_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

cnts = cv2.findContours(remove_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, (255,255,255), 5)
plt.imshow(result)

The resulting image looks like this:

Image With Line Removed

As you can see, the portions of the characters that were also touching the line were removed, which I need to preserve.

I attempted to solve this by using the following code:

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

# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,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), 2)

# Repair image
repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,6))
result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=2)

plt.imshow(result)

This appears to solve the issue (sort of), but the image appears grainy, and you can still tell where the line is:

Repaired Image

Does anyone know of a better way of repairing the image / removing the line?

Upvotes: 0

Views: 477

Answers (1)

user1196549
user1196549

Reputation:

For what it is worth, you can erase the horizontal line with a purely vertical closing, and replace just that part in the original image. A little better than erasing.

enter image description here

enter image description here

enter image description here

Upvotes: 2

Related Questions