Maison >développement back-end >Tutoriel Python >Déverrouillage du texte à partir de PDF à polices intégrées : un didacticiel OCR pytesseract

Déverrouillage du texte à partir de PDF à polices intégrées : un didacticiel OCR pytesseract

Patricia Arquette
Patricia Arquetteoriginal
2024-12-01 18:47:09859parcourir

Unlocking Text from Embedded-Font PDFs: A pytesseract OCR Tutorial

Extraire du texte d'un PDF est généralement simple lorsqu'il est en anglais et qu'il n'a pas de polices intégrées. Cependant, une fois ces hypothèses supprimées, il devient difficile d'utiliser des bibliothèques Python de base comme pdfminer ou pdfplumber. Le mois dernier, j'ai été chargé d'extraire le texte d'un PDF en langue gujarati et d'importer des champs de données tels que le nom, l'adresse, la ville, etc. au format JSON.

Si la police est intégrée dans le PDF lui-même, un simple copier-coller ne fonctionnera pas et l'utilisation de pdfplumber renverra un texte indésirable illisible. Par conséquent, j'ai dû convertir chaque page PDF en image, puis appliquer l'OCR à l'aide de la bibliothèque pytesseract pour "scanner" la page au lieu de simplement la lire. Ce tutoriel va vous montrer comment faire exactement cela.

Choses dont vous aurez besoin

  • pdfplombier (bibliothèque Python)
  • pdf2image (bibliothèque Python)
  • pytesseract (bibliothèque Python)
  • tesseract-ocr

Vous pouvez installer les bibliothèques Python à l'aide des commandes pip comme indiqué ci-dessous. Pour Tesseract-OCR, téléchargez et installez le logiciel depuis le site officiel. pytesseract n'est qu'un wrapper autour du logiciel tesseract.

pip install pdfplumber
pip install pdf2image
pip install pytesseract

Conversion de la page PDF en image

La première étape consiste à convertir votre page PDF en image. Cette fonction extract_text_from_pdf() fait exactement cela : vous transmettez le chemin du PDF et le numéro de page (indexé à zéro) comme paramètres. Notez que je convertis d'abord la page en noir et blanc pour plus de clarté, c'est facultatif.

# Extract text from a specific page of a PDF
def extract_text_from_pdf(pdf_path, page_num):
    # Use pdfplumber to open the PDF
    pdf = pdfplumber.open(pdf_path)
    print(f"extracting page {page_num}..")
    page = pdf.pages[page_num]
    images = convert_from_path(pdf_path, first_page=page_num+1, last_page=page_num+1)
    image = images[0]
    # Convert to black and white
    bw_image = convert_to_bw(image)
    # Save the B&W image for debugging (optional)
    #bw_image.save("bw_page.png")
    # Perform OCR on the B&W image
    e_text = ocr_image(bw_image)
    open('out.txt', 'w', encoding='utf-8').write(e_text)
    #print("output written to file.")
    try:
        process_text(page_num, e_text)
    except Exception as e:
        print("Error occurred:", e)
    print("done..")

# Convert image to black and white
def convert_to_bw(image):
    # Convert to grayscale
    gray = image.convert('L')
    # Apply threshold to convert to pure black and white
    bw = gray.point(lambda x: 0 if x < 128 else 255, '1')
    return bw

# Perform OCR using Tesseract on a given image
def ocr_image(image_path):
    try:
        # Perform OCR
        custom_config = r'--oem 3 --psm 6 -l guj+eng'
        text = pytesseract.image_to_string(image_path, config=custom_config)  # --psm 6 treats the image as a block of text
        return text
    except Exception as e:
        print(f"Error during OCR: {e}")
        return None

La fonction ocr_image() utilise pytesseract pour extraire le texte de l'image via OCR. Les paramètres techniques tels que --oem et --psm contrôlent la façon dont l'image est traitée, et le paramètre -l guj eng définit les langues à lire. Étant donné que ce PDF contenait occasionnellement du texte anglais, j'ai utilisé guj eng.

Traitement du texte

Une fois que vous avez importé le texte à l'aide de l'OCR, vous pouvez l'analyser dans le format souhaité. Cela fonctionne de manière similaire à d'autres bibliothèques PDF comme pdfplumber ou pypdf2.

nums = ['0', '૧', '૨', '૩', '૪', '૫', '૬', '૭', '૮', '૯']

def process_text(page_num, e_text):
    obj = None
    last_surname = None
    last_kramank = None
    print(f"processing page {page_num}..")
    for line in e_text.splitlines():
        line = line.replace('|', '').replace('[', '').replace(']', '')
        parts = [word for word in line.split(' ') if word]
        if len(parts) == 0: continue
        new_rec = True
        for char in parts[0]:
            if char not in nums:
                new_rec = False
                break
        if len(parts) < 2: continue

        if new_rec and len(parts[0]) >= 2: # numbered line
            if len(parts) < 9: continue
            if obj: records.append(obj)
            obj = {}
            last_surname = parts[1]
            obj['kramank'] = parts[0]
            last_kramank = parts[0]
            obj['full_name'] = ' '.join(parts[1:4])
            obj['surname'] = parts[1]
            obj['pdf_page_num'] = page_num + 1
            obj['registered_by'] = parts[4]
            obj['village_vatan'] = parts[5]
            obj['village_mosal'] = parts[6]
            if parts[8] == 'વર્ષ':
                idx = 7
                obj['dob'] = parts[idx] + ' વર્ષ'
                idx += 1
            elif len(parts[7]) == 8 and parts[7][2] == '-':
                idx = 7
                obj['dob'] = parts[idx]
            else:
                print("warning: no date")
                idx = 6
            obj['marital_status'] = parts[idx+1]
            obj['extra_fields'] = '::'.join(parts[idx+2:-2])
            obj['blood_group'] = parts[-1]
        elif parts[0] == last_surname: # new member in existing family
            if obj: records.append(obj)
            obj = {}
            obj['kramank'] = last_kramank
            obj['surname'] = last_surname
            obj['full_name'] = ' '.join(parts[0:3])
            obj['pdf_page_num'] = page_num + 1
            obj['registered_by'] = parts[3]
            obj['village_vatan'] = parts[4]
            obj['village_mosal'] = parts[5]
            if len(parts) <= 6: continue
            if parts[7] == 'વર્ષ': # date exists
                idx = 6
                obj['dob'] = parts[idx] + ' વર્ષ'
                idx += 1
            elif len(parts[6]) == 8 and parts[6][2] == '-':
                idx = 6
                obj['dob'] = parts[idx]
            else:
                print("warning: no date")
                idx = 5
            obj['marital_status'] = parts[idx+1]
            obj['extra_fields'] = '::'.join(parts[idx+2:-2])
            obj['blood_group'] = parts[-1]
        elif obj: # continuation lines
            if ("(" in line and ")" in line) or "મો.ઃ" in line:
                obj['extra_fields'] += ' ' + '::'.join(parts[0:])
    if obj: records.append(obj)        
    jstr = json.dumps(records, indent=4)
    open("guj.json", 'w', encoding='utf-8').write(jstr)
    print(f"written page {page_num} to json..")

Chaque PDF a ses propres nuances qui doivent être prises en compte. Dans ce cas, un nouveau numéro de série (comme 0૧ ou 0૨) dans le premier champ signalait un nouveau groupe lorsque le champ suivant (nom de famille) changeait.

pytesseract est un témoignage de l'évolution et des progrès de la technologie informatique. Il y a environ dix ans, lire ou analyser une image PDF à l'aide de l'OCR dans une langue autre que l'anglais sur un PC ou un ordinateur portable modestement configuré aurait été presque impossible. C'est vraiment un progrès ! Bon codage et dites-moi comment ça se passe dans les commentaires ci-dessous.

Références

  • Installation de Tesseract sous Windows
  • Utilisez Pytesseract OCR pour reconnaître le texte d'une image
  • Comment configurer pytesseract pour prendre en charge la détection de texte pour les langues autres que l'anglais dans Windows 10 ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn