【问题标题】:How to detect the horizontal and vertical lines of a table and eliminate the noise?如何检测表格的水平和垂直线并消除噪音?
【发布时间】:2020-03-06 05:09:50
【问题描述】:

我正在尝试获取图像中表格的水平线和垂直线,以便提取单元格中的文本。这是我用的一张图:

我使用下面的代码来提取垂直和水平线:

img = cv2.imread(img_for_box_extraction_path, 0)  # Read the image
(thresh, img_bin) = cv2.threshold(img, 200, 255,
                                  cv2.THRESH_BINARY | cv2.THRESH_OTSU)  # Thresholding the image
img_bin = 255-img_bin  # Invert the image
cv2.imwrite("Image_bin_2.jpg",img_bin)

# Defining a kernel length
kernel_length = np.array(img).shape[1]//140

# A verticle kernel of (1 X kernel_length), which will detect all the verticle lines from the image.
verticle_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_length))

# A horizontal kernel of (kernel_length X 1), which will help to detect all the horizontal line from the image.
hori_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_length, 1))

# A kernel of (3 X 3) ones.
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# Morphological operation to detect verticle lines from an image
img_temp1 = cv2.erode(img_bin, verticle_kernel, iterations=3)
verticle_lines_img = cv2.dilate(img_temp1, verticle_kernel, iterations=3)
cv2.imwrite("verticle_lines_2.jpg",verticle_lines_img)

# Morphological operation to detect horizontal lines from an image
img_temp2 = cv2.erode(img_bin, hori_kernel, iterations=3)
horizontal_lines_img = cv2.dilate(img_temp2, hori_kernel, iterations=3)
cv2.imwrite("horizontal_lines_2.jpg",horizontal_lines_img)

下图是横线和竖线:

我用下面的代码把两张图片加在一起

# Weighting parameters, this will decide the quantity of an image to be added to make a new image.
alpha = 0.5
beta = 1.0 - alpha

# This function helps to add two image with specific weight parameter to get a third image as summation of two image.
img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0)
img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2)
(thresh, img_final_bin) = cv2.threshold(img_final_bin, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# For Debugging
# Enable this line to see verticle and horizontal lines in the image which is used to find boxes
cv2.imwrite("img_final_bin_2.jpg",img_final_bin)

但是,我得到这样的图片: 如何消除噪音并获得更好的结果?提前致谢。

【问题讨论】:

  • houghline 不能正常工作吗?
  • 增加内核的长度,使其长于文本的宽度和高度。

标签: python image opencv image-processing computer-vision


【解决方案1】:

这里有一个简单的方法:

二值图像

检测到水平

检测到的垂直

组合蒙版

要删除的绿色行

结果

import cv2
import numpy as np

# Load image, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
horizontal_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)

# Detect vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
vertical_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=1)

# Combine masks and remove lines
table_mask = cv2.bitwise_or(horizontal_mask, vertical_mask)
image[np.where(table_mask==255)] = [255,255,255]

cv2.imshow('thresh', thresh)
cv2.imshow('horizontal_mask', horizontal_mask)
cv2.imshow('vertical_mask', vertical_mask)
cv2.imshow('table_mask', table_mask)
cv2.imshow('image', image)
cv2.waitKey()

【讨论】:

  • 感谢您的回答。我将如何将垂直蒙版提取到单独的图像中。即在您的示例中,我希望每列有 4 个单独的图像。有没有办法做到这一点?
  • 是他们将这些信息写入word文档的任何方法吗?
  • @user1014691 cv2.findContours,遍历每个轮廓并用cv2.imwrite保存每个轮廓
  • @SybghatallahMarwat 是的,一旦您处理并提取了轮廓,您就可以执行 OCR。以我过去的答案为例。您应该为此打开一个新问题
【解决方案2】:

尝试reduce CV_REDUCE_AVG 标志沿水平方向为您的第一个二进制图像,然后沿垂直方向为您的第二个图像。你会得到阈值直方图。并使用它们来过滤您的线路。

作为替代方案,您可以尝试使用霍夫线检测器并按长度和算法过滤线。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    相关资源
    最近更新 更多