如何从扫描的pdf文件中提取图像

6

我使用Tesseract从扫描的PDF中提取文本。其中一些文件还包含图像。有没有办法获取这些图片?

我通过将扫描的pdf转换为tiff文件来为Tesseract做准备。但是,我找不到任何命令行工具来从中提取图像,就像pdfimages对于“文本”pdf所做的那样。

有没有任何工具(或工具组合)可以帮助我完成这项工作呢?


2
Poppler 软件包中查找 pdfimages - Mark Setchell
当我使用pdfimages提取扫描PDF时,它会提取完整的页面,而不仅仅是图像。我认为这只是针对“文本”PDF而非扫描PDF的工具。 - Plouf
1
一个扫描的PDF通常每页包含一张位图图像,这个位图图像上有该页所有扫描内容。通常不会将类似文本的内容与其他内容分开。因此,当您从PDF中提取图像资源时,您将获得整个页面内容的位图。 - mkl
@MarkSetchell 确实。但是使用Tesseract,我可以将位图图像中的文本转换为tiff格式。我正在寻找一种可以对图像执行相同操作的工具。 - Plouf
3个回答

3
你将无法使用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
谢谢@Mitchell,但我怀疑我的问题不够清楚 :) 让我尝试澄清一下:当然我知道你不能用Tesseract做到这一点,这就是为什么我要求一个可能不存在的命令行工具。我尝试了你的解决方案,但如前所述,它无法检测PDF(或tiff)中的图像,而是将整个页面提取为图像,这不是我要找的。 - Plouf
啊,抱歉我不能提供更多的帮助。 - user5509289

3

1. 使用 pdfimages 提取图片

pdfimages mydoc.pdf

2. 使用以下提取脚本:

./extractImages.py images*

在新的images文件夹中找到您剪切出来的图像。 查看在tracing文件夹中所做的工作,以确保没有遗漏的图像。

操作

它将处理所有图像并查找图像内的形状。如果发现一个形状,并且它比可配置大小大,它将找到最大边界框,剪切图像并将其保存在新的images文件夹中,此外,它还将创建名为traces的文件夹,其中显示所有边界框。
如果要查找更小的图像,只需减小minimumWidth和minimumHeight,但是如果设置得太低,它将找到每个字符。
在我的测试中,它的表现非常好,只是找到了太多的图像。

extractImages.py

#!/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提供的,作为对这个问题的回答:

使用OpenCV Python提取所有边界框


这个可以用于扫描的PDF文件吗? - undefined

1
在许多情况下,当有人拥有PDF文件并希望“获取”图像时,将页面本身呈现为图像通常是令人满意的。但是,如果您确实想提取图像,则需要小心使用的工具,并调查其声誉和输出质量。
第一件重要的事情是要意识到,如果一个工具声称“从PDF中提取TIFF”或“从PDF中提取JPG”,那么他们会误导您,因为PDF不包含JPEG或TIFF图像。混淆之处在于,可以使用这两种光栅图像格式的压缩技术来压缩图像数据,但这与简单地将JPG文件与PDF“共存”并不相同。
有许多工具可用,但您会发现其质量差异很大。一些工具可以处理简单的PDF文件,但存在大小限制或复杂的PDF文件会使其崩溃或挂起。有些可以很好地处理RGB数据,但它会简单地跳过或处理其他颜色空间。有些不会让您对数据进行细粒度控制,而只会提取所有内容并重新压缩为JPEG。最重要的是,图像数据通常以某种方式损坏,您使用的技术必须能够优雅地处理这些情况。
如果您计划将其部署为企业解决方案的一部分,您需要一个能够处理几乎任何野外发现的PDF的工具。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接