Python 识别图片表格:从图像到结构化数据
1. 引言
在日常工作中,经常遇到需要从扫描件、截图或照片中提取表格数据的情况。手动输入效率低且易出错。借助 Python 的强大生态,我们可以自动化识别图片中的表格,并将数据转换为可用的电子表格格式。
2. 技术栈概览
- OpenCV:图像预处理,如灰度化、二值化、去噪、边缘检测等。
- Pytesseract:Tesseract OCR 的 Python 封装,用于文字识别。
- Tabula-py:封装了 Tabula,专用于 PDF 中表格提取,但对清晰图片也有一定效果。
- Pandas:数据处理和最终输出。
3. 核心步骤
3.1 图像预处理
首先,将图片转换为灰度图,使用阈值或自适应阈值进行二值化,去除噪声。例如:
import cv2
img = cv2.imread('table.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
3.2 表格线检测
通过霍夫变换或形态学操作检测水平和垂直线,从而定位单元格。常用方法:先腐蚀膨胀提取直线,再找到交点。例如:
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,1))
horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel)
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,40))
vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel)
3.3 OCR 识别单元格内容
根据检测到的表格线,提取每个单元格的子图像,然后使用 Pytesseract 识别文字。注意配置语言和 PSM 模式:
import pytesseract
from PIL import Image
cell_text = pytesseract.image_to_string(cell_img, lang='eng+chi_sim', config='--psm 6')
3.4 组合结构化数据
将识别的文本按行列位置填入 Pandas DataFrame,最后导出为 CSV 或 Excel 文件。
4. 示例代码框架
import cv2
import numpy as np
import pandas as pd
import pytesseract
def extract_table_from_image(image_path):
# 读取并预处理
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# 检测表格线(简化)
# ... 实际需复杂处理
# 假设已得到表格单元格坐标列表 cells = [(x1,y1,x2,y2), ...]
data = []
for (x1,y1,x2,y2) in cells:
cell_img = img[y1:y2, x1:x2]
text = pytesseract.image_to_string(cell_img, config='--psm 6').strip()
data.append(text)
# 按行列重新组织,假设已知行数和列数
df = pd.DataFrame(np.array(data).reshape(rows, cols))
df.to_csv('output.csv', index=False)
return df
5. 进阶技巧
- 多页表格:使用
tabula-py处理 PDF 中的表格更为直接。 - 复杂表格(合并单元格):需要更复杂的线检测与逻辑判断。
- 深度学习:使用 CNN 或专用模型(如 TableNet)提高准确率。
6. 总结
使用 Python 识别图片表格虽有一定挑战,但通过图像处理、OCR 和表格结构分析,可以实现较高的自动化程度。根据图片质量,可能需要反复调整预处理参数。建议从简单清晰的图片开始尝试,逐步优化。
更多资源:Tesseract OCR,Tabula。