如何用pytesseract提取采购订单SHIP TO区域文本及处理bounding box?
问题描述
我有两张采购订单图片(一张带 bounding box,一张不带),目标是提取图片中“SHIP TO”标题下的所有数据。目前我用 pytesseract 生成了每个单词的 bounding box,代码如下,但有几个疑问:
- 能否为“SHIP TO”下的所有内容生成单个 bounding box?
- 能否指定特定 bounding box 提取文本?
- 如何从 bounding box 中提取文本?
import pytesseract from pytesseract import Output import cv2 img_path=r"C:\Users\mihir\settls\PO\POs\images\img-1.jpeg" img=cv2.imread(img_path) d=pytesseract.image_to_data(img,output_type=Output.DICT) n_boxes= len(d['level']) for i in range(n_boxes): x,y,w,h=d['left'][i],d['top'][i],d['width'][i],d['height'][i] cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2) cv2.imshow('image',img) cv2.waitKey(0)
解决方案
1. 为“SHIP TO”下的内容生成单个 bounding box
可以通过定位“SHIP TO”文本位置,合并其下方同区块文本的 bounding box 实现:
- 先遍历
image_to_data返回的字典,找到“SHIP TO”对应的条目,记录它的底部坐标(y + h)和所属区块编号(block_num)。 - 筛选出同区块、顶部坐标大于“SHIP TO”底部且非空的文本条目。
- 计算这些条目的最小
x、最小y、最大x+w、最大y+h,合并成一个大的 bounding box。
示例代码片段:
# 定位SHIP TO的位置 ship_to_idx = None for i, text in enumerate(d['text']): if text.strip().upper() == 'SHIP TO': ship_to_idx = i break if ship_to_idx is not None: ship_to_bottom = d['top'][ship_to_idx] + d['height'][ship_to_idx] ship_to_block = d['block_num'][ship_to_idx] # 合并同区块下的文本框 min_x = float('inf') min_y = float('inf') max_x = 0 max_y = 0 for i in range(n_boxes): if d['block_num'][i] == ship_to_block and d['top'][i] > ship_to_bottom and d['text'][i].strip() != '': x = d['left'][i] y = d['top'][i] x2 = x + d['width'][i] y2 = y + d['height'][i] min_x = min(min_x, x) min_y = min(min_y, y) max_x = max(max_x, x2) max_y = max(max_y, y2) # 绘制合并后的bounding box cv2.rectangle(img, (min_x, min_y), (max_x, max_y), (0, 255, 0), 2)
2. 指定特定 bounding box 提取文本
通过裁剪图片对应区域,再调用OCR提取文本即可:
- 确定目标 bounding box 的坐标(比如上面得到的
min_x, min_y, max_x, max_y)。 - 用OpenCV裁剪图片区域:
roi = img[min_y:max_y, min_x:max_x]。 - 对裁剪后的区域调用
image_to_string提取文本。
示例代码:
# 裁剪SHIP TO下方的区域 roi = img[min_y:max_y, min_x:max_x] # 提取文本 ship_to_text = pytesseract.image_to_string(roi) print("SHIP TO 内容:\n", ship_to_text)
3. 从 bounding box 提取文本的通用方法
除了裁剪提取,也可以直接从image_to_data的结果中筛选:
- 遍历所有条目,判断坐标是否在目标框范围内,或者直接匹配目标条目索引,提取对应的
text值。
比如提取单个单词的文本:
# 提取第i个bounding box的文本 text = d['text'][i].strip() if text: print(text)
内容的提问来源于stack exchange,提问作者Mihir Sanjay
相关产品推荐
相关产品推荐

