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

时间:2017-11-06 08:57:49

标签: image pdf

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

我通过在tiff文件中转换它来准备我的扫描pdf for tesseract。但我无法找到任何命令行工具来从中提取图像,因为pdfimages会为" text" PDF。

任何可以帮助我完成工作的工具(或工具组合)的想法?

3 个答案:

答案 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)

1。使用pdfimages

提取图像
pdfimages mydoc.pdf

2。使用以下提取脚本:

./extractImages.py images*

在新的图像文件夹中找到裁剪的图像。 查看跟踪文件夹中的操作,以确保没有丢失任何图像。

操作

它将处理所有图像并在图像内部寻找形状。如果找到了形状并且形状大于可配置的大小,则它将填充以找出最大边界框,剪切图像并将其保存在新图像中,此外还将创建一个名为traces的文件夹,其中将显示所有边界框。 / p>

如果要查找较小的图像,只需减小 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为该问题提供了基本算法:

Extract all bounding boxes using OpenCV Python