如何检查PDF是扫描的图像还是包含文本

时间:2019-04-16 08:54:06

标签: python python-3.x pypdf2 pdfminer pdf-extraction

我有大量文件,其中一些是扫描图像转换为PDF,另一些是全文/部分文本PDF。

有没有一种方法可以检查这些文件以确保我们仅处理扫描图像的文件,而不是已经处理为全文/部分文本PDF文件的文件?

我正在使用PYTHON 3.6。

谢谢

9 个答案:

答案 0 :(得分:10)

Rahul Agarwal's solution的基础上,以及在this link上找到的一些代码片段,这是一种可能可以解决您的问题的算法。

您需要安装UndefinedError: 'user_dict' is undefinedfitz模块。您可以通过PyMuPDF来做到这一点:

pip

这是Python3的实现:

pip3 install fitz PyMuPDF

尽管这可以回答您的问题(即,区分完全扫描的PDF和全文/部分文本的PDF),但该解决方案无法区分全文文本PDF和其中也包含文本的扫描的PDF。

答案 1 :(得分:5)

我创建了一个脚本来检测PDF是否为OCRd。主要思想是:在OCRd PDF中,文本是不可见的。

测试给定PDF(f1)是否为OCRd的算法:

  1. 创建标记为f1的{​​{1}}的副本
  2. 删除f2上的所有文本
  3. f2f1的所有(或仅几个)页面创建图像(PNG)
  4. 如果f2f1的所有图像都相同,则
  5. f1为OCRd。

https://github.com/jfilter/pdf-scripts/blob/master/is_ocrd_pdf.sh

f2

答案 2 :(得分:3)

您可以使用 pdfplumber。如果以下代码返回“无”,则为扫描的 pdf,否则可搜索。

sage: A3.shape
(27, 27)
sage: A3.todense()[0:15, 0:15]
matrix([[ 0,  1,  2,  1,  0,  0,  2,  0,  0,  1,  1,  2,  2,  1,  2],
        [ 1,  1,  2,  0,  1,  0,  0,  2,  0,  1,  2,  2,  1,  3,  2],
        [ 2,  2,  3,  0,  0,  1,  0,  0,  2,  2,  2,  4,  2,  2,  5],
        [ 1,  0,  0,  1,  1,  2,  2,  0,  0,  2,  1,  2,  3,  2,  4],
        [ 0,  1,  0,  1,  2,  2,  0,  2,  0,  1,  3,  2,  2,  5,  4],
        [ 0,  0,  1,  2,  2,  4,  0,  0,  2,  2,  2,  5,  4,  4,  9],
        [ 2,  0,  0,  2,  0,  0,  3,  1,  2,  4,  2,  4,  4,  2,  4],
        [ 0,  2,  0,  0,  2,  0,  1,  4,  2,  2,  6,  4,  2,  6,  4],
        [ 0,  0,  2,  0,  0,  2,  2,  2,  6,  4,  4, 10,  4,  4, 10],
        [ 1,  1,  2,  2,  1,  2,  4,  2,  4,  1,  2,  4,  3,  1,  2],
        [ 1,  2,  2,  1,  3,  2,  2,  6,  4,  2,  3,  4,  1,  4,  2],
        [ 2,  2,  4,  2,  2,  5,  4,  4, 10,  4,  4,  7,  2,  2,  6],
        [ 2,  1,  2,  3,  2,  4,  4,  2,  4,  3,  1,  2,  4,  3,  6],
        [ 1,  3,  2,  2,  5,  4,  2,  6,  4,  1,  4,  2,  3,  7,  6],
        [ 2,  2,  5,  4,  4,  9,  4,  4, 10,  2,  2,  6,  6,  6, 13]])
sage: 

要从扫描的 pdf 中提取文本,您可以使用 OCRmyPDF。简易包装

答案 3 :(得分:1)

你可以使用ocrmypdf,它有一个跳过文本的参数

更多信息在这里:https://ocrmypdf.readthedocs.io/en/latest/advanced.html

ocrmypdf.ocr(file_path, save_path, rotate_pages=True, remove_background=False, language=language, deskew=False, force_ocr=False, skip_text=True)

答案 4 :(得分:1)

我只是重新修改了@Vikas Goel 的代码

def get_pdf_searchable_pages(fname):
    """ intentifying a digitally created pdf or a scanned pdf"""    

    searchable_pages = []
    non_searchable_pages = []
    page_num = 0
    with open(fname, 'rb') as infile:

        for page in PDFPage.get_pages(infile):
            page_num += 1
            if 'Font' in page.resources.keys():
                searchable_pages.append(page_num)
            else:
                non_searchable_pages.append(page_num)
    if page_num == len(searchable_pages):
        return("searchable_pages")
    elif page_num != len(searchable_pages):
        return("non_searchable_pages")
    else:
        return("Not a valid document")

答案 5 :(得分:0)

以下代码将起作用,以从可搜索和不可搜索的PDF提取数据文本数据。

import fitz
text=""
path = ("Your_scanned_or_partial_scanned.pdf")

doc = fitz.open(path)
for page in doc:                            
    text+=(page.getText())

如果您没有fitz模块,则需要执行以下操作:

pip install --upgrade pymupdf

答案 6 :(得分:0)

如何在'/Resources'上检查PDF元数据?

我相信,对于PDF(电子文档)中的任何文本,都有更多的机会拥有字体,尤其是PDF,其目标是制作便携式文件,因此,它可以保持字体定义。

如果您是PyPDF2用户,请尝试

pdf_reader = PyPDF2.PdfFileReader(input_file_location)
page_data = pdf_reader.getPage(page_num)

if '/Font' in page_data['/Resources']:
    print("[Info]: Looks like there is text in the PDF, contains:", page_data['/Resources'].keys())
elif len(page_data1['/Resources'].get('/XObject', {})) != 1:
    print("[Info]: PDF Contains:", page_data['/Resources'].keys())

for obj in x_object:
    obj_ = x_object[obj]
    if obj_['/Subtype'] == '/Image':
        print("[Info]: PDF is image only")

答案 7 :(得分:0)

尝试OCRmyPDF。 您可以使用此命令将扫描的pdf转换为数字pdf。

ocrmypdf input_scanned.pdf output_digital.pdf

如果输入的pdf是数字格式,则命令将引发错误“ PriorOcrFoundError:页面已包含文本!”。

import subprocess as sp
import re

output = sp.getoutput("ocrmypdf input.pdf output.pdf")
if not re.search("PriorOcrFoundError: page already has text!",output):
   print("Uploaded scanned pdf")
else:
   print("Uploaded digital pdf")

答案 8 :(得分:0)

def get_pdf_searchable_pages(fname):
    # pip install pdfminer
    from pdfminer.pdfpage import PDFPage
    searchable_pages = []
    non_searchable_pages = []
    page_num = 0
    with open(fname, 'rb') as infile:

        for page in PDFPage.get_pages(infile):
            page_num += 1
            if 'Font' in page.resources.keys():
                searchable_pages.append(page_num)
            else:
                non_searchable_pages.append(page_num)
    if page_num > 0:
        if len(searchable_pages) == 0:
            print(f"Document '{fname}' has {page_num} page(s). "
                  f"Complete document is non-searchable")
        elif len(non_searchable_pages) == 0:
            print(f"Document '{fname}' has {page_num} page(s). "
                  f"Complete document is searchable")
        else:
            print(f"searchable_pages : {searchable_pages}")
            print(f"non_searchable_pages : {non_searchable_pages}")
    else:
        print(f"Not a valid document")


if __name__ == '__main__':
    get_pdf_searchable_pages("1.pdf")
    get_pdf_searchable_pages("1Scanned.pdf")

输出:

Document '1.pdf' has 1 page(s). Complete document is searchable
Document '1Scanned.pdf' has 1 page(s). Complete document is non-searchable