如何从含表格的图像中提取线条,生成仅含表格线的黑白图像
表格线条提取优化方案
问题背景
我有一张包含表格的图像:
我使用如下代码提取表格横竖线条,生成仅含表格线的图像:
import cv2 as cv import numpy as np img = cv.imread('1.jpg') cv.imshow('Original', img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) gray = cv.bitwise_not(gray) bw = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 15, -2) # 创建用于提取竖线的图像 vertical = np.copy(bw) horizontal = np.copy(bw) # 指定水平轴尺寸 cols = horizontal.shape[1] horizontal_size = cols / 10 horizontal_size=int(horizontal_size) # 创建形态学操作的结构元素,用于提取水平线 horizontalStructure = cv.getStructuringElement(cv.MORPH_RECT, (horizontal_size, 1)) horizontal = cv.erode(horizontal, horizontalStructure) horizontal = cv.dilate(horizontal, horizontalStructure) # horizontal = cv.dilate(horizontal, (3, 3), iterations=1) # 指定垂直轴尺寸 rows = vertical.shape[0] verticalsize = rows / 10 verticalsize = int(verticalsize) # 创建形态学操作的结构元素,用于提取竖直线 verticalStructure = cv.getStructuringElement(cv.MORPH_RECT, (1, verticalsize)) # 执行形态学操作 vertical = cv.erode(vertical, verticalStructure) vertical = cv.dilate(vertical, verticalStructure) # vertical = cv.dilate(vertical, (3, 3), iterations=1) ret, thresh_v = cv.threshold(vertical, 127, 255, cv.THRESH_BINARY) # cv.imshow('thresh vertical', thresh_v) ret, thresh_h = cv.threshold(horizontal, 127, 255, cv.THRESH_BINARY) # cv.imshow('thresh horizontal', thresh_h) table_lines = cv.bitwise_or(thresh_h, thresh_v) cv.imshow('table lines', table_lines) cv.waitKey(0)
输出结果如下:
优化处理方案
当前输出杂乱是因为没有做噪点过滤、形态学核尺寸不合理导致文字笔画被误识别为表格线,按以下步骤调整即可得到和原图一致的完整表格线:
- 先加噪声过滤步骤,避免文字边缘噪点被误判为线条,在自适应阈值处理前增加高斯模糊操作
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) gray = cv.bitwise_not(gray) # 新增高斯模糊 gray = cv.GaussianBlur(gray, (3,3), 0) bw = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 15, -2) - 调整形态学核尺寸规则,原代码用图像宽高的1/10作为核长度,容易漏检短线条或者误判文字笔画,改为适配常规表格单元格尺寸的固定值即可
# 替换原水平核长度计算逻辑,适配多数表格的单元格宽度 horizontal_size = 25 # 替换原垂直核长度计算逻辑 verticalsize = 15 - 增加小噪点过滤步骤,合并横竖线后过滤掉面积过小的非表格线噪点
table_lines = cv.bitwise_or(thresh_h, thresh_v) # 新增噪点过滤逻辑 contours, _ = cv.findContours(table_lines, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for cnt in contours: if cv.contourArea(cnt) < 20: cv.drawContours(table_lines, [cnt], -1, 0, -1) - 如有表格线断裂的情况,可增加一次闭运算补全缝隙
kernel = cv.getStructuringElement(cv.MORPH_RECT, (2,2)) table_lines = cv.morphologyEx(table_lines, cv.MORPH_CLOSE, kernel, iterations=1)
内容的提问来源于stack exchange,提问作者Meet Gondaliya
相关产品推荐
相关产品推荐

