如何使用Python从原始图像中删除所有检测到的行?

时间:2019-09-16 16:39:07

标签: python opencv image-processing computer-vision straight-line-detection

我正在尝试删除图像中存在的所有行。 我能够检测到线条,但是当我尝试删除线条时,最终图像中仍然很少出现细线。我使用cv2.getStructuringElement来获取水平和垂直线。在某些情况下,最终图像会完全失真,我无法前进

图片取自Google

Original Image Lines detected

    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)

请帮助!谢谢

1 个答案:

答案 0 :(得分:2)

这是一种方法

  • 将图像转换为灰度
  • 大津获取二进制图像的阈值
  • 删除水平线
  • 删除垂直线

转换为灰度后,我们以Otsu的阈值获取二进制图像

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)

此处检测到的行为绿色

结果

您可以通过调整内核大小来微调结果。例如,将(10,1)更改为(15,1)会拉紧行检测,而将其降低到(5,1)则会使检测松动

完整代码

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