利用img2table库实现对表格图像进行识别,将结果保存到dataframe中
时间: 2024-12-14 17:16:10 浏览: 293
利用img2table库可以方便地实现表格图像的识别,这个Python库通常用于从图片中提取结构化的数据,将其转化为DataFrame形式,以便于后续的数据处理和分析。以下是基本步骤:
1. 首先,你需要安装`img2table`库,你可以通过pip来安装:
```
pip install img2table
```
2. 然后,导入所需的库并加载图像文件:
```python
import img2table as itb
from PIL import Image
table_image = Image.open('your_table_image_path.jpg')
```
3. 调用`img2table`函数并将图像转换为DataFrame:
```python
df = itb.read_img2table(table_image)
```
这里,`df`就是包含表格数据的DataFrame,每一行代表表格的一行,列则对应单元格的内容。
4. 对生成的DataFrame进行清洗、整理,可能需要进一步的格式化或数据分析工作。
注意:img2table并不是万能的,对于复杂的表格,特别是那些包含公式、合并单元格或者高度自定义设计的表格,识别效果可能会有局限性。
相关问题
使用python 和opencv 识别图片中的表格,将结果转化成excel 文件
要实现这个任务,需要使用Python中的OpenCV和Pandas库。具体步骤如下:
1. 首先,使用OpenCV读取图片,将其转换为灰度图像并进行阈值处理,以便于检测表格线。
```python
import cv2
import numpy as np
# 读取图片并转换为灰度图像
img = cv2.imread('image.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 应用阈值处理,以便于检测表格线
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
```
2. 检测表格线。我们可以使用HoughLinesP函数来检测直线,然后筛选出水平和垂直线。
```python
# 检测表格线
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 1))
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 25))
horizontal_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel)
vertical_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel)
# 筛选出水平和垂直线
lines = cv2.HoughLinesP(horizontal_lines + vertical_lines, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)
```
3. 将检测到的表格线画出来,并将表格线的坐标存储在列表中。
```python
# 画出检测到的表格线
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 存储表格线的坐标
horizontal_points = []
vertical_points = []
for line in lines:
x1, y1, x2, y2 = line[0]
if abs(x1 - x2) < 10:
vertical_points.append((x1, y1))
elif abs(y1 - y2) < 10:
horizontal_points.append((x1, y1))
```
4. 根据表格线的坐标,将表格分割成单元格。
```python
# 对表格线的坐标进行排序
horizontal_points = sorted(horizontal_points, key=lambda x: x[1])
vertical_points = sorted(vertical_points, key=lambda x: x[0])
# 将表格分割成单元格
cells = []
for i in range(len(horizontal_points) - 1):
for j in range(len(vertical_points) - 1):
x1, y1 = vertical_points[j]
x2, y2 = vertical_points[j+1]
x3, y3 = horizontal_points[i]
x4, y4 = horizontal_points[i+1]
cell = img[y3:y4, x1:x2]
cells.append(cell)
```
5. 使用Pandas库将单元格数据转换为Excel文件。
```python
import pandas as pd
# 将单元格数据转换为DataFrame
data = []
for cell in cells:
gray_cell = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY)
text = pytesseract.image_to_string(gray_cell, lang='eng', config='--psm 6')
data.append(text.strip())
df = pd.DataFrame(np.array(data).reshape(len(horizontal_points) - 1, len(vertical_points) - 1))
# 将DataFrame写入Excel文件
df.to_excel('table.xlsx', index=False, header=False)
```
完整代码如下:
import cv2 import pytesseract import pandas as pd # 根据你的实际安装路径修改,这里假设安装在D盘/ort pytesseract.pytesseract.tesseract_cmd = r'D:\ort\tesseract.exe' def extract_text_from_image(image_path): """从图片中提取文字""" image = cv2.imread(image_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) text = pytesseract.image_to_string(gray) return text def process_text_to_dataframe(text): """将提取的文字处理成DataFrame""" lines = text.split('\n') data = [] for line in lines: parts = line.split() if parts: data.append(parts) df = pd.DataFrame(data) return df def extract_unpaid_info(df): """从DataFrame中提取未付信息""" unpaid_mask = df.apply(lambda row: '未付' in row.values, axis=1) unpaid_df = df[unpaid_mask] return unpaid_df # 修改这里的图片路径为你实际的图片路径 image_path = 'C:/images/table_image.jpg' extracted_text = extract_text_from_image(image_path) df = process_text_to_dataframe(extracted_text) unpaid_info = extract_unpaid_info(df) print(unpaid_info)这个代码运行不了
该段代码是一个利用Python结合OpenCV、Tesseract OCR以及Pandas库,从图像文件中识别并提取文本内容,并尝试筛选出包含“未付”关键词的数据行的示例。如果遇到无法正常运行的问题,则可能是由以下几个原因导致:
1. **依赖环境配置问题**:确保`cv2`(即opencv-python)、`pytesseract`及`tesseract-ocr`已正确安装并且路径设置准确无误;对于Windows用户来说,默认情况下需要单独下载[Tesseract-OCR](https://github.com/tesseract-ocr/tesseract),并将它的可执行文件位置指派给变量`pytesseract.pytesseract.tesseract_cmd`。
2. **图片读取失败**:确认提供的`image_path`是否指向了一个有效的图像资源。可以添加检查点验证图像加载成功与否:
```python
if image is None:
raise ValueError("未能正确加载指定路径下的图像")
```
3. **字符编码问题**:当源图像是中文或其他非ASCII字符集构成时,在某些操作系统环境下可能会面临字符编码错误。你可以通过调整`tesseract`命令参数来优化这一状况:
- 使用简体中文语言包(假设已经安装):`text = pytesseract.image_to_string(gray, lang='chi_sim')`
4. **数据预处理不足**:原始图像质量差(如模糊不清)、存在干扰元素或是表格线等问题都可能导致OCR结果不佳。考虑加入额外步骤对输入图片进行增强处理(例如二值化阈值操作),以提高转换精度。
5. **pandas DataFrame构造逻辑需改进**:当前直接按空格分隔每行生成列的方式过于简单粗暴,容易造成数据错位或丢失有效信息的情况发生。针对结构化的表格文档建议采用更智能的方法解析字段边界,比如借助正则表达式匹配特定模式,或者基于表单设计特点自定义分割规则等手段完善函数`process_text_to_dataframe()`的功能实现。
下面提供一段经过上述优化后的参考版本供您测试:
```python
import cv2
import pytesseract
from pathlib import Path
# 指定 Tesseract 可执行程序的位置 (请根据实际情况修改)
TESSERACT_CMD_PATH = r'D:\ort\tesseract.exe'
if not Path(TESSERACT_CMD_PATH).exists():
raise FileNotFoundError(f"找不到Tesseract位于{TESSERACT_CMD_PATH}")
def extract_text_from_image(image_path):
"""
加载图像 -> 转换灰度空间 -> 文字检测与识别
参数说明:
@param str image_path 图像存储绝对地址
返回值:
string 提取出的所有可见字符串序列
"""
try:
img_array = cv2.imread(image_path)
# 验证是否能够获取到合法矩阵表示形式
if img_array is None:
raise IOError('无效目标文件')
processed_img = preprocess(img_array)
detected_texts = pytesseract.image_to_string(processed_img,
config=f'-l chi_sim --psm 6',
timeout=10)
return detected_texts.strip()
except Exception as excepiton_msg:
print(str(excepiton_msg))
return ''
def preprocess(image_matrix):
"""图像预处理流程"""
grayscale_version = cv2.cvtColor(image_matrix,cv2.COLOR_BGR2GRAY)
_, binary_result=cv2.threshold(grayscale_version,thresh=180,maxval=255,type=cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
denoised_image=cv2.fastNlMeansDenoising(binary_result,h=7)
return denoised_image
def process_text_to_dataframe(raw_content):
from io import StringIO
import pandas as pd
modified_raw_lines = []
for raw_line in raw_content.splitlines():
trimmed_item = ' '.join([word for word in raw_line.split()])
if len(trimmed_item)>0:modified_raw_lines.append(trimmed_item + '\n')
sio_obj =StringIO(''.join(modified_raw_lines))
dataframe_representation=pd.read_csv(sio_obj,names=['rawdata'],header=None,error_bad_lines=False,warn_bad_lines=True,dtype=str)
split_into_columns=dataframe_representation['rawdata'].str.extractall(r'\s*(?P<column>\S+)\s*', expand=False)[0].groupby(level=0).apply(list).reset
阅读全文
相关推荐
















