如何将pdfminer.six提取的文本Bounding Box可视化到PDF图像?
问题描述
我有一份PDF格式的图表,已用pdfminer.six成功提取出图表中的文本及其边界框(Bounding Box)。
系统环境:Windows 10、Python 3.9.13
现在想使用OpenCV的rectangle()函数,把这些边界框绘制到PDF转换后的图像上实现可视化,但用pdf2image转换PDF为图像时需要设置DPI,不确定具体实现方法,请问如何利用pdfminer返回的边界框数据完成这个可视化?
提取边界框的示例代码
from pdfminer.high_level import extract_pages from pdfminer.layout import LTTextBox, LAParams import cv2 as cv import os import numpy as np path = r"sample.pdf" assert os.path.exists(path), "image path is wrong" laparams = LAParams(detect_vertical=True) for page_layout in extract_pages(path, laparams=laparams): for element in page_layout: if isinstance(element, LTTextBox): print(element.bbox)
边界框输出示例
.... (64.46833119999998, 758.4685649600001, 143.16671221999994, 763.35576496) (399.3279, 797.7414805999999, 464.28060816000004, 812.3556692000001) (520.1078, 797.7414805999999, 631.1472937599999, 812.3556692000001) (676.9479, 797.7414805999999, 762.4986252799999, 812.3556692000001) (709.8279, 787.0014805999999, 729.9863304, 792.5868806) ....
解决方案
核心要解决两个问题:坐标单位转换(点→像素)和坐标原点对齐(PDF左下角→图像左上角),以下是完整实现步骤:
1. 安装依赖
确保已安装所需库,若未安装执行:
pip install pdfminer.six opencv-python pdf2image
Windows用户需额外下载poppler工具包,解压后将其bin目录添加到系统环境变量PATH中,或在代码中直接指定poppler路径。
2. 完整实现代码
from pdfminer.high_level import extract_pages from pdfminer.layout import LTTextBox, LAParams import cv2 as cv import os import numpy as np from pdf2image import convert_from_path # 配置参数 PDF_PATH = r"sample.pdf" DPI = 300 # 常用DPI值,越高图像越清晰,坐标精度越高 OUTPUT_DIR = r"./output" os.makedirs(OUTPUT_DIR, exist_ok=True) # 1. 转换PDF为图像 # Windows用户若未配置poppler环境变量,需指定poppler_path参数,示例:r"C:\poppler-23.08.0\Library\bin" pages_images = convert_from_path(PDF_PATH, dpi=DPI) # 2. 提取边界框并绘制 laparams = LAParams(detect_vertical=True) for page_idx, (page_layout, page_img) in enumerate(zip(extract_pages(PDF_PATH, laparams=laparams), pages_images)): # 将PIL图像转为OpenCV格式(BGR) img = cv.cvtColor(np.array(page_img), cv.COLOR_RGB2BGR) img_height, img_width = img.shape[:2] # 获取PDF页面的原始尺寸(单位:点,1英寸=72点) page_width_pt, page_height_pt = page_layout.bbox[2], page_layout.bbox[3] # 计算缩放因子:点转像素 scale_x = img_width / page_width_pt scale_y = img_height / page_height_pt # 遍历所有文本框,绘制边界框 for element in page_layout: if isinstance(element, LTTextBox): # PDF边界框格式:(x0, y0, x1, y1),坐标原点在左下角 x0_pt, y0_pt, x1_pt, y1_pt = element.bbox # 转换为图像像素坐标 x0 = int(x0_pt * scale_x) # 翻转Y轴,对齐图像左上角原点 y0 = int(img_height - y0_pt * scale_y) x1 = int(x1_pt * scale_x) y1 = int(img_height - y1_pt * scale_y) # 绘制绿色矩形,线宽2 cv.rectangle(img, (x0, y1), (x1, y0), (0, 255, 0), 2) # 保存可视化结果 output_path = os.path.join(OUTPUT_DIR, f"page_{page_idx+1}_boxed.jpg") cv.imwrite(output_path, img) print(f"已保存结果:{output_path}")
关键说明
- DPI选择:300是兼顾清晰度和性能的常用值,若需要更高精度可设为600,但图像体积会相应增大。
- 坐标转换逻辑:
- PDF坐标原点在页面左下角,Y轴向上;OpenCV图像原点在左上角,Y轴向下,因此需要用
图像高度 - 转换后的Y坐标完成翻转。 - 缩放因子通过
图像实际尺寸/PDF页面点尺寸计算,无需手动换算DPI与点的关系,更精准。
- PDF坐标原点在页面左下角,Y轴向上;OpenCV图像原点在左上角,Y轴向下,因此需要用
- poppler路径:Windows用户如果未将poppler加入环境变量,必须在
convert_from_path中指定poppler_path参数,指向poppler解压后的bin目录。
内容的提问来源于stack exchange,提问作者tintin98
相关产品推荐
相关产品推荐

