基于TensorFlow目标检测的发票数据提取:非裁剪方案问询
解决方案:直接在原图针对检测区域提取文本(无需裁剪保存)
完全可以直接在整张图像中针对TensorFlow检测出的区域执行文本提取,这样能避免裁剪后图像压缩、尺寸过小导致的Tesseract识别精度下降。核心思路是跳过裁剪图像并保存的步骤,直接在内存中处理原图的ROI区域,或者让Tesseract直接限定识别范围。
方法一:内存中处理ROI区域(推荐,匹配你的现有预处理流程)
这种方式避免了JPEG压缩带来的图像质量损失,直接对原图的目标区域执行预处理和识别,和你原本的文本提取流程完全兼容。
整合后的代码示例:
import cv2 import pytesseract import tensorflow as tf import numpy as np import os # 配置Tesseract路径 pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" # 替换为你的发票图像路径 image_path = "your_invoice.jpg" im = cv2.imread(image_path) im_height, im_width = im.shape[:2] Threshold = 0.5 # 你的置信度阈值 class_labels = [] bbox_results = [] # 目标检测结果循环(替换你原有的TF检测逻辑) for idx in range(len(bboxes)): if bscores[idx] >= Threshold: # 计算检测区域坐标 y_min = int(bboxes[idx][0] * im_height) x_min = int(bboxes[idx][1] * im_width) y_max = int(bboxes[idx][2] * im_height) x_max = int(bboxes[idx][3] * im_width) class_label = category_index[int(bclasses[idx])]['name'] score = bscores[idx] * 100 # 保存bbox信息(可选) class_labels.append(class_label) bbox_results.append([x_min, y_min, x_max, y_max, class_label, float(score)]) # 直接提取原图的ROI区域(内存中操作,不保存文件) roi = im[y_min:y_max, x_min:x_max] # 执行你原有的预处理流程 gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3,3), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1) invert = 255 - opening # 提取文本 text = pytesseract.image_to_string(invert, lang='eng', config='--psm 6') # 输出结果 print(f"区域{idx} | 类型:{class_label} | 置信度:{round(score)}%") print("提取文本:") print(text) print("-"*60)
方法二:让Tesseract直接限定识别区域
如果希望对整张图做预处理后再提取指定区域的文本,可以通过Tesseract的--clip参数直接限定识别范围,无需裁剪图像:
# 在目标检测循环中,拿到bbox坐标后: clip_config = f"--psm 6 --clip {x_min} {y_min} {x_max} {y_max}" # 先对整张图做预处理 gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3,3), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1) invert = 255 - opening # 仅提取指定区域的文本 text = pytesseract.image_to_string(invert, lang='eng', config=clip_config)
为什么之前裁剪后识别质量差?
你遇到的问题大概率是因为:
- 裁剪后的图像保存为JPEG时产生压缩损失,导致文本边缘模糊;
- 小尺寸图像的分辨率不足,Tesseract难以识别细小字符。
上述两种方法都跳过了图像保存/读取的步骤,直接处理原始像素,能有效解决这些问题。
内容的提问来源于stack exchange,提问作者ZKS
相关产品推荐
相关产品推荐

