Как конвертировать PDF с изображениями, которые меня не интересуют, в текст?

#pdf #text #converters #pdftotext

#PDF #текст #конвертеры #pdftotext

Вопрос:

Я пытаюсь конвертировать pdf в текстовые файлы. Проблема в том, что эти PDF содержат изображения, которые меня не волнуют (это тип файла, который я хочу извлечь (https://www.sia.aviation-civile.gouv.fr/pub/media/store/documents/file/l/f/lf_sup_2020_213_fr.pdf ). Обратите внимание, что если я копирую / вставляю с помощью мыши, это работает довольно хорошо (за исключением разрыва строки), поэтому я предполагаю, что это возможно. Большинство ответов, которые я нашел в Интернете, довольно хорошо работают с фиктивным PDF только с текстом, но дают особенно плохой результат на карте. Например, что-то вроде этого

 from tika import parser # pip install tika
raw = parser.from_file('test2.pdf')
print(raw['content']) 
 

хорошо работает для извлечения текста, но у меня много такого мусора :

ОЧЕНЬ

CTR

3

CH

A

которые появляются из-за карты.

Что-то вроде этого, которое работает путем преобразования pdf в изображения, а затем чтения изображений, сталкивается с той же проблемой (я нашел это в очень похожей теме в stackoverflow, но ответа нет) :

 import pytesseract as pt
from PIL import Image
import sys 

def convert(name):
    pages = convert_from_path(name, dpi=200)
    for idx,page in enumerate(pages):
        page.save('page' str(idx) '.jpg', 'JPEG')
        quote = Image.open('page' str(idx) '.jpg')
        text = pt.image_to_string(quote, lang="fra")
        file_ex = open('page' str(idx) '.text',"w")
        file_ex.write(text)
        file_ex.close()



if __name__ == '__main__':
    convert(sys.argv[1])
 

Наконец, я попытался сначала удалить изображение, а затем использовать одно из приведенных выше решений, но это не сработало лучше :

 from tika import parser # pip install tika
from PyPDF2 import PdfFileWriter, PdfFileReader

# Remove the images
inputStream = open("lf_sup_2020_213_fr.pdf", "rb")
outputStream = open("test3.pdf", "wb")

 
src = PdfFileReader(inputStream)
output = PdfFileWriter()
 

[output.addPage(src.getPage(i)) for i in range(src.getNumPages())]
output.removeImages()
 

output.write(outputStream)
outputStream.close()

# Read from pdf without images
raw = parser.from_file('test2.pdf')
print(raw['content'])
 

Вы знаете, как это решить? Это может быть на любом языке.
Спасибо

Ответ №1:

Один из подходов, который вы могли бы попробовать, — это использовать инструментарий, способный анализировать текстовые символы в PDF, а затем использовать свойства объекта, чтобы попытаться удалить ненужные метки карты, сохраняя при этом требуемые текстовые символы.

Например, метод ParsePages из LEADTOOLS PDF toolkit (с которым я знаком, поскольку работаю у поставщика этого инструментария) можно использовать для получения текста из PDF:

 using (PDFDocument document = new PDFDocument(pdfFileName))
{
   PDFParsePagesOptions options = PDFParsePagesOptions.All;
   document.ParsePages(options, 1, -1);

   using (StreamWriter writer = File.CreateText(txtFileName))
   {
      IList<PDFObject> objects = document.Pages[0].Objects;
      writer.WriteLine("Objects: {0}", objects.Count);
      foreach (PDFObject obj in objects)
      {
         if (obj.TextProperties.IsEndOfLine)
            writer.WriteLine(obj.Code);
         else
            writer.Write(obj.Code);
      }
      writer.WriteLine("---------------------");
   }
}
 

Это приведет к получению всего текста в формате PDF для первой страницы с нежелательными результатами, как вы упомянули. Вот выдержка ниже:

 Objects: 3918
5
91L
F5
4
1 LF
N
OY
L2
1AM
TService
8
26
1de l’Information 
0
B09SUP AIP 213/20 
7 
Aéronautique
 
Date de publication : 05 NOV 
e-mail  : sia.qualite@aviation-civile.gouv.fr 
Internet  : www.sia.aviation-civile.gouv.fr 
141
 
17˚
82
N20 
9Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry 
En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020 
 

Для проверки свойств каждого анализируемого символа можно использовать дополнительный код:

 writer.WriteLine("  ObjectType: {0}", obj.ObjectType.ToString());
writer.WriteLine("  Bounds: {0}, {1}, {2}, {3}", obj.Bounds.Left, obj.Bounds.Top, obj.Bounds.Right, obj.Bounds.Bottom);
writer.WriteLine("  TextProperties.FontHeight: {0}", obj.TextProperties.FontHeight.ToString());
writer.WriteLine("  TextProperties.FontIndex: {0}", obj.TextProperties.FontIndex.ToString());
writer.WriteLine("  Code: {0}", obj.Code);
writer.WriteLine("------");
 

Это даст свойства для каждого символа:

   Objects: 3918
  ObjectType: Text
  Bounds: -60.952693939209, 1017.25231933594, -51.8431816101074, 1023.71826171875
  TextProperties.FontHeight: 7.10454273223877
  TextProperties.FontIndex: 48
  Code: 5
------
 

Используя эти свойства, нежелательный текст может быть отфильтрован с использованием их свойств. Например, я заметил, что высота шрифта для значительной части нежелательного текста составляет около 7 единиц формата PDF, поэтому первый код может быть изменен, чтобы избежать извлечения любого текста размером менее 7,25 единиц формата PDF:

 foreach (PDFObject obj in objects)
{
   if (obj.TextProperties.FontHeight > 7.25)
   {
      if (obj.TextProperties.IsEndOfLine)
         writer.WriteLine(obj.Code);
      else
         writer.Write(obj.Code);
   }
}
 

Извлеченный результат даст лучший результат, ниже приводится выдержка:

 Objects: 3918
Service
de l’Information 
SUP AIP 213/20 
 
Aéronautique
Date de publication : 05 NOV 
e-mail  : sia.qualite@aviation-civile.gouv.fr 
Internet  : www.sia.aviation-civile.gouv.fr 
 
Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry 
En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020 
 
Lieu : FIR : Marseille LFMM - AD : Chambéry Aix-Les-Bains LFLB, Chambéry Challes les Eaux LFLE 
 
ZRT LE SIRE, MOTTE CASTRALE, ALLEVARD 
*
C
D
E
 

В конце концов, вам нужно будет попытаться найти хорошие критерии для фильтрации нежелательного текста, не удаляя текст, который вам нужно сохранить, используя этот подход.