3

I want to remove all horizontal and vertical lines. I am able to remove horizontal lines, but while removing small vertical lines the original text is also getting impacted. This is the code I'm using:

image = cv2.imread('opt/doc/uploads/img1.png')
result = image.copy()
blur = image.copy()
gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0,255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

rows,cols = thresh.shape
horizontalsize = int(cols // 30)
verticalsize = int(rows // 30)

# Remove horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontalsize,1))
remove_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel)
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), 3)                        


# Remove vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,20))        
remove_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel)
cnts = cv2.findContours(remove_vertical, cv2.RETR_TREE, 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),3)

cv2.imwrite('result.png', result)

PFB 2 the input image:

Input Image Input Image

PFB output Image of above 2 images respectively:

Output output

  • Possible duplicate of [Removing Horizontal Lines in image (OpenCV, Python, Matplotlib)](https://stackoverflow.com/questions/46274961/removing-horizontal-lines-in-image-opencv-python-matplotlib) – Sachin Yadav Sep 25 '19 at 12:25
  • Hi Sachin i am having problem while removing small vertical lines. whenever i am trying to remove the small vertical lines the original text is also getting impacted, there is no issue while removing horizontal lines. – Manoj Jadhav Sep 26 '19 at 06:47

1 Answers1

0

Instead of trying to detect horizontal/vertical lines, another approach is to filter using contour area to "ignore" the lines and just take the desired text characters. One limitation is it will not detect text that is connected to the horizontal/vertical lines

enter image description here

import cv2
import numpy as np

image = cv2.imread('1.png')
mask = np.ones(image.shape, dtype=np.uint8) * 255
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 1000:
        x,y,w,h = cv2.boundingRect(c)
        mask[y:y+h, x:x+w] = image[y:y+h, x:x+w]

cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.waitKey()
nathancy
  • 42,661
  • 14
  • 115
  • 137
  • Hi @nathancy your solution is working fine if there is horizontal line but in some scenarios i will have images which will have only vertical lines no horizontal. then how i can remove those vertical lines. can you please help. – Manoj Jadhav Sep 26 '19 at 06:38
  • You can create a special vertical kernel to remove the lines, another filter would be to filter using contour area – nathancy Sep 26 '19 at 19:42
  • I have already tried with vertical kernel to remove vertical lines but in that approach it also tampers the character (it removes the vertical lines from character too) like D,F,H,I,M etc which has vertical lines (PFA image above). And if i use contour area filter for vertical lines then it also remove the character whose contour area less than the vertical line or same as vertical line. – Manoj Jadhav Oct 03 '19 at 06:53
  • Try using morphological operations such as `cv2.MORPH_CLOSE` to fill in the broken characters – nathancy Oct 03 '19 at 19:51