I am trying to remove all the lines present in the image.
I am able to detect the lines but when I am trying to remove the lines, I am still getting few small lines in the final image. I have used cv2.getStructuringElement
to get both the horizontal and vertical lines. In some cases, the final image is getting completely distorted and I am not able to move forward
The image is taken from google
res = verticle_lines_img + horizontal_lines_img
res = cv2.bitwise_not(res)
fin=cv2.bitwise_or(img_bin, res,mask =cv2.bitwise_not(res))
fin= cv2.bitwise_not(fin)
exp =255-res
final = cv2.bitwise_and(exp,img_bin)
final = cv2.bitwise_not(final)
exp = ~exp
finalised = cv2.bitwise_and(img_bin,final)
finalised = cv2.bitwise_not(finalised)
Please help! Thanks
Here's an approach
After converting to grayscale, we Otsu's threshold to get a binary image
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
From here we construct a special horizontal kernel to detect horizontal lines. Once the lines are detected, we fill in the lines to effectively remove the line
# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10,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)
Similarly, to remove vertical lines, we construct a special vertical kernel
# Remove vertical
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_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)
Here's the detected lines in green
Result
You can fine tune the results by adjusting the kernel size. For instance, changing (10,1)
to say (15,1)
will tighten the line detection while lowering it to (5,1)
will loosen the detection
Full Code
import cv2
image = cv2.imread('1.jpg')
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, (10,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)
# Remove vertical
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_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)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()