在进行计算机视觉任务时,经常需要将PDF文件转换成图片格式,如JPEG或PNG。本文将探讨使用shell脚本或Python代码将PDF页面光栅化的方法。选择合适的分辨率对于提高训练和推理速度至关重要,应选择尽可能低的分辨率以减小文件大小,同时不影响准确性。命令行工具如ImageMagick和Python库pdf2image允许指定每英寸点数(DPI),直接调整用于检测特征的图像质量。
在将PDF转换为图片时,选择最佳分辨率可以提高训练和推理速度。理想情况下,选择尽可能低的分辨率以减少文件大小,同时不影响准确性。例如,对于边界框检测(例如定位页面上的文本块或数学公式),150-300 DPI通常就足够了。对于分类整个页面(例如识别包含图表或图形的整个页面),50-150 DPI的较低分辨率通常就足够了。
ImageMagick是一个强大的命令行图像处理工具。以下是如何在shell脚本中使用它将目录中的PDF转换为图片的方法:
#!/bin/bash
# 将当前目录中的所有PDF转换为PNG图片
for file in *.pdf; do
magick -density 300 "$file" "${file%.pdf}.png"
done
以上配置值的信息如下:
结合选项的例子:
#!/bin/bash
for file in *.pdf; do
magick -density 150 -resize 1000x -colorspace GRAY -depth 8 -background white -flatten "$file" "${file%.pdf}.png"
done
此命令将执行以下操作:
对于JPEG输出,可能会使用:
#!/bin/bash
for file in *.pdf; do
magick -density 150 -resize 1000x -colorspace sRGB -quality 90 "$file" "${file%.pdf}.jpg"
done
一旦准备好了训练集,通常需要为推理执行相同的任务:用户将有PDF文档,而训练模型需要光栅图像作为输入。pdf2image是一个Python库,用于处理PDF文件,与Roboflow的推理SDK配合得很好。需要使用选择的包管理器安装该包:
pip install pdf2image
以下是一个简单的脚本,它将当前工作目录中的所有PDF文件转换为每个页面的单独PNG文件:
import os
from pdf2image import convert_from_path
def convert_pdfs_to_pngs(directory, dpi=150):
pdf_files = [f for f in os.listdir(directory) if f.lower().endswith('.pdf')]
for pdf_file in pdf_files:
pdf_path = os.path.join(directory, pdf_file)
pdf_name = os.path.splitext(pdf_file)[0]
pages = convert_from_path(pdf_path, dpi=dpi)
for page_num, page in enumerate(pages, start=1):
image_name = f"{pdf_name}_page_{page_num:03d}.png"
image_path = os.path.join(directory, image_name)
page.save(image_path, 'PNG')
print(f"Saved: {image_name}")
if __name__ == "__main__":
current_directory = os.getcwd()
convert_pdfs_to_pngs(current_directory)
此脚本适用于许多用例,但请注意,转换的吞吐量可能会受到输入/输出操作速度的限制。
对于HTTP请求处理程序中的PDF处理或更大规模的批处理过程,可以利用asyncio来优化IO绑定操作。以下是一个使用pdf2image和asyncio提高吞吐量的例子:
#!/usr/bin/env python
import os
import asyncio
from pdf2image import convert_from_path
from concurrent.futures import ProcessPoolExecutor
async def convert_pdf_to_pngs(pdf_path, dpi=150):
pdf_name = os.path.splitext(os.path.basename(pdf_path))[0]
loop = asyncio.get_event_loop()
with ProcessPoolExecutor() as pool:
pages = await loop.run_in_executor(pool, convert_from_path, pdf_path, dpi)
tasks = []
for page_num, page in enumerate(pages, start=1):
image_name = f"{pdf_name}_page_{page_num:03d}.png"
image_path = os.path.join(os.path.dirname(pdf_path), image_name)
task = asyncio.create_task(save_image(page, image_path))
tasks.append(task)
await asyncio.gather(*tasks)
print(f"Converted: {pdf_name}")
async def save_image(page, image_path):
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, page.save, image_path, 'PNG')
async def convert_pdfs_to_pngs(directory, dpi=150):
pdf_files = [f for f in os.listdir(directory) if f.lower().endswith('.pdf')]
tasks = []
for pdf_file in pdf_files:
pdf_path = os.path.join(directory, pdf_file)
task = asyncio.create_task(convert_pdf_to_pngs(pdf_path, dpi))
tasks.append(task)
await asyncio.gather(*tasks)
if __name__ == "__main__":
current_directory = os.getcwd()
asyncio.run(convert_pdfs_to_pngs(current_directory))
这种基于asyncio的方法显著提高了性能,通过并发处理多个PDF和页面,非常适合服务器进程和更大的数据集。