Rumah >pembangunan bahagian belakang >Tutorial Python >Membuka Kunci Teks daripada PDF Fon Terbenam: Tutorial OCR pytesseract

Membuka Kunci Teks daripada PDF Fon Terbenam: Tutorial OCR pytesseract

Patricia Arquette
Patricia Arquetteasal
2024-12-01 18:47:09859semak imbas

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

Mengekstrak teks daripada PDF biasanya mudah apabila ia dalam bahasa Inggeris dan tidak mempunyai fon terbenam. Walau bagaimanapun, sebaik sahaja andaian tersebut dialih keluar, ia menjadi mencabar untuk menggunakan perpustakaan python asas seperti pdfminer atau pdfplumber. Bulan lalu, saya ditugaskan untuk mengekstrak teks daripada PDF bahasa Gujarati dan mengimport medan data seperti nama, alamat, bandar, dll., ke dalam format JSON.

Jika fon dibenamkan dalam PDF itu sendiri, penyalinan tampal mudah tidak akan berfungsi dan menggunakan pdfplumber akan mengembalikan teks sampah yang tidak boleh dibaca. Oleh itu, saya terpaksa menukar setiap halaman PDF kepada imej dan kemudian menggunakan OCR menggunakan perpustakaan pytesseract untuk "mengimbas" halaman dan bukannya hanya membacanya. Tutorial ini akan menunjukkan kepada anda cara untuk melakukannya.

Perkara yang anda perlukan

  • pdfplumber (Python library)
  • pdf2image (Python library)
  • pytesseract (perpustakaan Python)
  • tesseract-ocr

Anda boleh memasang perpustakaan Python menggunakan arahan pip seperti yang ditunjukkan di bawah. Untuk Tesseract-OCR, muat turun dan pasang perisian dari tapak rasmi. pytesseract hanyalah pembalut di sekeliling perisian tesseract.

pip install pdfplumber
pip install pdf2image
pip install pytesseract

Menukar halaman PDF kepada imej

Langkah pertama ialah menukar halaman PDF anda kepada imej. Fungsi extract_text_from_pdf() ini betul-betul-anda melepasi laluan PDF dan page_num (sifar diindeks) sebagai parameter. Harap maklum bahawa saya menukar halaman kepada hitam putih terlebih dahulu untuk kejelasan, ini adalah pilihan.

# 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

Fungsi ocr_image() menggunakan pytesseract untuk mengekstrak teks daripada imej melalui OCR. Parameter teknikal seperti --oem dan --psm mengawal cara imej diproses dan parameter -l guj eng menetapkan bahasa untuk dibaca. Memandangkan PDF ini mengandungi teks Inggeris sekali-sekala, saya menggunakan guj eng.

Memproses teks

Setelah anda mengimport teks menggunakan OCR, anda boleh menghuraikannya dalam format yang anda mahukan. Ini berfungsi sama seperti perpustakaan PDF lain seperti pdfplumber atau 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..")

Setiap PDF mempunyai nuansa tersendiri yang mesti diambil kira. Dalam kes ini, nombor siri baharu (seperti 0૧ atau 0૨) dalam medan pertama menandakan kumpulan baharu apabila medan seterusnya (nama keluarga) bertukar.

pytesseract ialah bukti evolusi dan kemajuan dalam teknologi IT. Kira-kira sedekad yang lalu, membaca atau menghuraikan imej PDF menggunakan OCR dalam bahasa bukan bahasa Inggeris pada PC atau komputer riba yang dikonfigurasikan sederhana adalah hampir mustahil. Ini benar-benar kemajuan! Selamat mengekod, dan beritahu saya bagaimana ia berlaku dalam ulasan di bawah.

Rujukan

  • Pemasangan Tesseract dalam tingkap
  • Gunakan pytesseract OCR untuk mengecam teks daripada imej
  • Bagaimana untuk mengkonfigurasi pytesseract untuk menyokong pengesanan teks untuk bahasa bukan Inggeris dalam windows 10?

Atas ialah kandungan terperinci Membuka Kunci Teks daripada PDF Fon Terbenam: Tutorial OCR pytesseract. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn