简体   繁体   中英

How to remove all the detected lines from the original image using Python?

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

  • Convert image to grayscale
  • Otsu's threshold to obtain binary image
  • Remove horizontal lines
  • Remove vertical lines

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM