1

I want to remove the horizontal and vertical lines from application forms, similar to the attached one. I am following the steps shown in the OpenCV's 'Extract horizontal and vertical lines by using morphological operations' feature.

The code:

import numpy as np
import sys
import cv2 as cv

src = cv.imread('image.jpg') 

if src is None:
    print ('Error opening image: ' + src)

# Transform source image to gray if it is not already
if len(src.shape) != 2:
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
else:
    gray = src
    
# Show gray image
cv.imwrite('image_gray.jpg',gray)
    
# Apply adaptiveThreshold at the bitwise_not of gray, notice the ~ symbol
gray = cv.bitwise_not(gray)
bw = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 15, -2)

# Show binary image
cv.imwrite('image_binary.jpg',bw)

# Create the images that will use to extract the horizontal and vertical lines
horizontal = np.copy(bw)
vertical = np.copy(bw)

# Specify size on horizontal axis
cols = horizontal.shape[1]
horizontal_size = cols / 20
horizontal_size=int(horizontal_size)

# Create structure element for extracting horizontal lines through morphology operations
horizontalStructure = cv.getStructuringElement(cv.MORPH_RECT, (horizontal_size, 1))

# Apply morphology operations
horizontal = cv.erode(horizontal, horizontalStructure)
horizontal = cv.dilate(horizontal, horizontalStructure) 

# Show extracted horizontal lines
cv.imwrite('image_horizontal.jpg',horizontal)
 
# Specify size on vertical axis
rows = vertical.shape[0]
verticalsize = rows / 20
verticalsize = int(verticalsize)

# Create structure element for extracting vertical lines through morphology operations
verticalStructure = cv.getStructuringElement(cv.MORPH_RECT, (1, verticalsize))

# Apply morphology operations
vertical = cv.erode(vertical, verticalStructure)
vertical = cv.dilate(vertical, verticalStructure)

# Show extracted vertical lines
cv.imwrite('image_vertical.jpg',vertical)
    
# Inverse vertical image
vertical = cv.bitwise_not(vertical)
cv.imwrite('image_vertInverse.jpg',vertical)

# Step 1
edges = cv.adaptiveThreshold(vertical, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 3, -2)
cv.imwrite('image_edges.jpg',edges)

# Step 2
kernel = np.ones((2, 2), np.uint8)
edges = cv.dilate(edges, kernel)
cv.imwrite('image_dilate.jpg',edges)

# Step 3
smooth = np.copy(vertical)
    
# Step 4
smooth = cv.blur(smooth, (2, 2))

# Step 5
(rows, cols) = np.where(edges != 0)
vertical[rows, cols] = smooth[rows, cols]

# Show final result
cv.imwrite('image_final.jpg',vertical)

Here is what I get:

Original Image:

Original Image

Transformed to Gray:

Transforming source image to gray

Binary Image:

Binary Image

Horizontal Lines:

Horizontal Lines

Vertical Lines:

Vertical Lines

Edges:

Edges

Dilate:

Dilate

Final Result:

Final Result

I have tried answers to already asked related questions, but that don't solve this particular case of application form.

halfer
  • 19,824
  • 17
  • 99
  • 186
Pardeep Kumar
  • 133
  • 2
  • 10

1 Answers1

0

Seems like you got all of the parts in there. You can either use the horizontal and vertical binary images (white on black) as masks and set to white all the pixels that match that mask.

Alternatively, use only erode (as many times needed) with the structuring element, this will remove all points that match the element.

Eran W
  • 1,696
  • 15
  • 20
  • Glad to help :) You can update your question with the results you got, so it would be helpful for others. – Eran W May 09 '19 at 11:08