从PDF提取印地语文本并转为DataFrame的技术求助
如何精准提取印地语PDF文本并转换为指定结构的DataFrame?
我正在处理从PDF文件提取印地语文本并转换为DataFrame的任务,先后尝试了easyOCR、PaddleOCR等库,也参考了相关技术文章,但始终无法得到正确输出。
当前使用的代码(基于OpenCV和Tesseract)无法精准识别文本轮廓生成边界框,OCR输出效果不符合预期。我的核心需求是将提取到的信息整理成包含以下列的DataFrame:
नाम:(姓名)पति का नाम / पिता का नाम:(丈夫/父亲姓名)मकान संख्याः(房屋编号)
另外还有一个疑问:如果文档页面的布局或信息位置发生变更,是否需要为每个文档编写单独的代码,还是可以使用通用脚本处理?
以下是我当前使用的代码:
import cv2 import pytesseract import numpy as np from pytesseract import Output image = cv2.imread('pages_new/page3.jpg') img = image.copy() mask = np.zeros(image.shape, dtype=np.uint8) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] # Filter for ROI using contour area and aspect ratio countour = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) countour = countour[0] if len(countour) == 2 else countour[1] for c in countour: area = cv2.contourArea(c) peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.05 * peri, True) x,y,w,h = cv2.boundingRect(approx) aspect_ratio = w / float(h) if area > 10000 and aspect_ratio > .5: mask[y:y+h, x:x+w] = image[y:y+h, x:x+w] h, w, c = img.shape boxes = pytesseract.image_to_boxes(img) for b in boxes.splitlines(): b = b.split(' ') img = cv2.rectangle(img, (int(b[1]), h - int(b[2])), (int(b[3]), h - int(b[4])), (0, 255, 0), 2) d = pytesseract.image_to_data(img, output_type=Output.DICT) n_boxes = len(d['text']) for i in range(n_boxes): if int(d['conf'][i]) > 60: (x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i]) img2 = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) # cv2.imshow('img', img) # cv2.imshow('img2', img2) # Perfrom OCR with Pytesseract data = pytesseract.image_to_string(mask, lang='Devanagari', config='--psm 6') print(data) # cv2.imshow('thresh', thresh) # cv2.imshow('mask', mask)
解决方案
一、优化OCR与轮廓识别逻辑
你的代码中轮廓过滤规则过于宽泛,容易误选或漏选目标区域,可从以下几点调整:
精细化轮廓筛选
- 增加矩形度判断:计算轮廓面积与边界框面积的比值,接近1的为规则矩形,过滤不规则区域
- 调整面积阈值:根据实际表单元素大小,将
area > 10000改为area > 2000 and area < 50000,缩小筛选范围 - 提升轮廓近似精度:将
approxPolyDP的参数从0.05 * peri改为0.02 * peri,更精准识别矩形轮廓
优化Tesseract配置
- 使用官方支持的印地语语言包:将
lang='Devanagari'改为lang='hin' - 调整PSM模式:针对表单字段,使用
--psm 7(单文本行)或--psm 4(单列文本),比--psm 6更适配字段提取场景 - 限制识别字符集:添加配置
-c tessedit_char_whitelist=अआइईउऊएऐओऔकखगघचछजझटठडढतथदधनपफबभमयरलवशषसहक्षत्रज्ञ0123456789: /,减少无关字符干扰
- 使用官方支持的印地语语言包:将
图像预处理增强
- 添加去噪操作:
kernel = np.ones((2,2), np.uint8); thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) - 高斯模糊去噪:
gray = cv2.GaussianBlur(gray, (3,3), 0),提升文本清晰度
- 添加去噪操作:
二、构建指定结构的DataFrame
提取文本后,通过正则匹配目标字段,生成DataFrame:
import re import pandas as pd # 假设OCR提取的文本存储在data变量中 field_patterns = { 'नाम:': r'नाम:\s*(.*?)(?=\n|\Z|पति का नाम / पिता का नाम:|मकान संख्याः)', 'पति का नाम / पिता का नाम:': r'पति का नाम / पिता का नाम:\s*(.*?)(?=\n|\Z|नाम:|मकान संख्याः)', 'मकान संख्याः': r'मकान संख्याः\s*(.*?)(?=\n|\Z|नाम:|पति का नाम / पिता का नाम:)' } extracted_info = {} for field, pattern in field_patterns.items(): match_result = re.search(pattern, data, re.DOTALL) extracted_info[field] = match_result.group(1).strip() if match_result else None result_df = pd.DataFrame([extracted_info]) print(result_df)
三、文档变更的通用脚本可行性
- 同类型表单微调:无需重写代码,可基于字段标签(如
नाम:)的位置定位文本区域,通过OCR识别标签坐标后,提取其右侧/下方的内容,避免依赖固定轮廓参数 - 完全不同的文档结构:需要调整字段匹配规则、轮廓筛选逻辑,但核心的OCR预处理、DataFrame生成代码可复用,仅需修改配置部分(如
field_patterns)
优先采用关键字定位的方案,能大幅提升脚本对不同布局的适应性,减少重复开发。
内容的提问来源于stack exchange,提问作者Lalit Joshi
相关产品推荐
相关产品推荐

