我使用Tesseract从扫描的PDF中提取文本。其中一些文件还包含图像。有没有办法获得这些图像?
我通过在tiff文件中转换它来准备我的扫描pdf for tesseract。但我无法找到任何命令行工具来从中提取图像,因为pdfimages会为" text" PDF。
任何可以帮助我完成工作的工具(或工具组合)的想法?
答案 0 :(得分:1)
您无法将Tesseract OCR用于图像,因为这不是它的设计目的。最好使用工具预先提取图像,然后使用Tesseract获取文本。
xPDF可能会对PDFimages有所帮助。
http://www.xpdfreader.com/pdfimages-man.html
您需要下载R,Rstudio,xPDFreader和PDFtools才能完成此任务。确保您的程序文件能够在"环境变量"中找到。 (如果使用Windows),以便R可以找到程序。
然后做这样的事情来转换它。有关PDFimages的帮助,请参阅文档中的选项。这就是语法的方式(特别是在paste0之后)。请注意选项的位置。它们必须位于文件输入名称之前:
#("PDF to PPM")
files <- tools::file_path_sans_ext(list.files(path = dest, pattern =
"pdf", full.names = TRUE))
lapply(files, function(i){
shell(shQuote(paste0("pdftoppm -f 1 -l 10 -r 300 ", i,".pdf", " ",i)))
})
您也可以使用CMD提示并输入
pdftoppm -f 1 -l 10 -r 300 stuff.pdf stuff.ppm
答案 1 :(得分:1)
在许多情况下,当有人拥有PDF并且他们想要获得&#39;将图像输出,将页面本身呈现给图像通常是令人满意的。但是,如果您确实想要提取图像,则需要注意使用哪种工具并调查其声誉和输出质量。
要实现的第一件重要事情是,工具是否声称&#34;从PDF中提取TIFF&#34;或者&#34;从PDF中提取JPG&#34;然后他们误导你,因为PDF并不包含每个说法的JPEG或TIFF图像。产生这种混淆的原因是,这两种光栅图像格式可以使用的压缩技术在PDF中用于压缩图像数据,但它与JPG文件不同,只是简单地生活着#&;用PDF。
有许多工具,但你会发现质量会有很大差异。有些可以很好地处理简单的PDF,但是有大小限制或复杂的PDF只会让它崩溃或挂起。有些人可以很好地处理RGB数据,但它只是跳过或错误处理其他颜色空间。有些人不会让您对数据进行精细控制,只需提取所有内容并将其重新压缩为JPEG格式。最重要的是,图像数据通常会以某种方式损坏,而您使用的技术必须能够优雅地处理这些场景。
如果您计划将其部署为企业解决方案的一部分,则需要一个能够处理大部分PDF的工具,您可以在野外找到它。
答案 2 :(得分:0)
pdfimages mydoc.pdf
./extractImages.py images*
在新的图像文件夹中找到裁剪的图像。 查看跟踪文件夹中的操作,以确保没有丢失任何图像。
它将处理所有图像并在图像内部寻找形状。如果找到了形状并且形状大于可配置的大小,则它将填充以找出最大边界框,剪切图像并将其保存在新图像中,此外还将创建一个名为traces的文件夹,其中将显示所有边界框。 / p>
如果要查找较小的图像,只需减小 minimumWidth 和 minimumHeight ,但是如果将其设置得太低,则会找到每个字符。
在我的测试中,它工作得非常好,它发现的图像太多了。
#!/bin/env python
import cv2
import numpy as np
import os
from pathlib import Path
def extractImagesFromFile(inputFilename, outputDirectory, tracing=False, tracingDirectory=""):
# Settings:
minimumWidth = 100
minimumHeight = 100
greenColor = (36, 255, 12)
traceWidth = 2
# Load image, grayscale, Otsu's threshold
image = cv2.imread(inputFilename)
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Find contours, obtain bounding box, extract and save ROI
ROI_number = 1
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x, y, w, h = cv2.boundingRect(c)
if w >= minimumWidth and h >= minimumHeight:
cv2.rectangle(image, (x, y), (x + w, y + h), greenColor, traceWidth)
ROI = original[y:y+h, x:x+w]
outImage = os.path.join(outputDirectory, '{}_{}.png'.format(Path(inputFilename).stem, ROI_number))
cv2.imwrite(outImage, ROI)
ROI_number += 1
if tracing:
outImage = os.path.join(tracingDirectory, Path(inputFilename).stem + '_trace.png')
cv2.imwrite(outImage, image)
def main(files):
tracingEnabled = True
outputDirectory = 'images'
tracingDirectory = 'tracing'
# Create the output directory if it does not exist
outputPath = Path.cwd() / outputDirectory
outputPath.mkdir(exist_ok=True)
if tracingEnabled:
tracingPath = Path.cwd() / tracingDirectory
tracingPath.mkdir(exist_ok=True)
for f in files:
print("Prcessing {}".format(f))
if Path(f).is_file():
extractImagesFromFile(f, outputDirectory, tracingEnabled, tracingDirectory)
else:
print("Invalid file: {}".format(f))
if __name__ == "__main__":
import argparse
from glob import glob
parser = argparse.ArgumentParser()
parser.add_argument("fileNames", nargs='*')
args = parser.parse_args()
fileNames = list()
for arg in args.fileNames:
fileNames += glob(arg)
main(fileNames)
nathancy为该问题提供了基本算法: