You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV如何通过识别表格网格线提取非均等尺寸单元格?

网格线识别法提取表格单元格实现方案

核心思路

不需要假设单元格尺寸均等,通过识别表格的水平、垂直网格线获得准确的分割坐标,再按坐标切割得到单个单元格。

具体实现步骤

  • 图像预处理
    先将原图转为灰度图,做高斯模糊过滤噪声,再用自适应阈值二值化后反色,让网格线变为白色前景,背景为黑色,提升后续线条检测的准确率。
  • 网格线提取
    使用形态学开运算分别分离水平和垂直网格线:
    • 水平线条:创建宽度远大于高度的水平矩形结构元,做开运算过滤掉垂直方向的文字、噪点,仅保留水平网格线
    • 垂直线条:创建高度远大于宽度的垂直矩形结构元,同理做开运算提取垂直网格线
  • 分割坐标计算
    对提取到的水平线条图像,按行统计像素和,和大于阈值的行即为水平网格线的y轴坐标,排序后去重相邻的重复坐标;同理按列统计垂直线条图像的像素和,得到垂直网格线的x轴坐标,排序去重。
  • 单元格切割
    遍历相邻的x、y坐标,两两组合截取对应图像区域,即为单个单元格。

示例代码(基于OpenCV+Python)

import cv2
import numpy as np

def get_table_cells(img):
    # 预处理:灰度、去噪、二值化反色
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (3, 3), 0)
    thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                  cv2.THRESH_BINARY_INV, 11, 2)
    
    # 提取水平网格线
    h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (img.shape[1]//9, 1))
    h_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, h_kernel, iterations=2)
    # 提取垂直网格线
    v_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, img.shape[0]//9))
    v_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, v_kernel, iterations=2)
    
    # 计算水平网格线y坐标,去重相邻重复值
    h_proj = np.sum(h_lines, axis=1)
    y_coords = np.where(h_proj > np.max(h_proj)*0.6)[0]
    y_list = []
    last_y = -10
    for y in sorted(y_coords):
        if y - last_y > 3:
            y_list.append(y)
        last_y = y
    
    # 计算垂直网格线x坐标,去重相邻重复值
    v_proj = np.sum(v_lines, axis=0)
    x_coords = np.where(v_proj > np.max(v_proj)*0.6)[0]
    x_list = []
    last_x = -10
    for x in sorted(x_coords):
        if x - last_x > 3:
            x_list.append(x)
        last_x = x
    
    # 切割所有单元格
    cells = []
    for i in range(len(y_list)-1):
        row_cells = []
        for j in range(len(x_list)-1):
            cell = img[y_list[i]:y_list[i+1], x_list[j]:x_list[j+1]]
            row_cells.append(cell)
        cells.append(row_cells)
    return cells

# 调用示例
# img = cv2.imread("你的表格路径.jpg")
# cells = get_table_cells(img)

可调优方向

  • 如果输入表格存在倾斜,可以先通过霍夫线变换检测表格边缘,做透视变换校正表格角度后再提取网格线
  • 阈值、结构元尺寸、相邻坐标去重的差值参数,可以根据你的图像实际分辨率和线条粗细调整,避免漏检或多检网格线
  • 提取到的单元格如果带多余的边框,可以向内裁剪1-3个像素,消除边框对后续内容识别的干扰

内容的提问来源于stack exchange,提问作者Сalendula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:06:01