Spaces:
Running
Running
File size: 3,797 Bytes
07d0354 814c19e 061d5cb b1d3718 b82e672 10213d3 3e4d13c b82e672 814c19e bf3bfc2 3e4d13c 4b30cd0 99ddfcc 814c19e 4b30cd0 07d0354 b82e672 a5152aa b82e672 4b30cd0 b82e672 4b30cd0 ce4e81b b82e672 a5152aa ce4e81b b82e672 ce4e81b 4b30cd0 ce4e81b 4b30cd0 ce4e81b 4b30cd0 ce4e81b 4b30cd0 ce4e81b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
import gradio as gr
import pdfplumber
import re
from transformers import LayoutLMForTokenClassification, AutoTokenizer
import torch
# Wczytanie modelu LayoutLMv3
model_name = "kryman27/layoutlmv3-finetuned"
model = LayoutLMForTokenClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name) # Automatyczne wykrycie tokenizatora
# Reguły do wykrywania NIP, kwot, dat
nip_pattern = re.compile(r'\bPL\s?\d{10}\b|\b\d{10}\b')
kwota_pattern = re.compile(r'\b\d+[\.,]?\d*\s?(PLN|zł|EUR|USD)?\b') # Rozpoznawanie walut
data_pattern = re.compile(r'\b\d{2}\.\d{2}\.\d{4}\b') # Format DD.MM.YYYY
payment_keywords = ["data płatności", "termin płatności", "zapłata", "zapłacono", "płatność"]
seller_keywords = ["sprzedawca", "faktura wystawiona przez", "wystawca", "nazwa firmy"]
def extract_invoice_data(pdf_file):
with pdfplumber.open(pdf_file) as pdf:
words, boxes, full_text = [], [], []
for page in pdf.pages:
extracted_words = page.extract_words()
for word in extracted_words:
words.append(word['text']) # Pobieramy tekst słowa
bbox = [int(word['x0']), int(word['top']), int(word['x1']), int(word['bottom'])] # Zaokrąglamy wartości
boxes.append(bbox) # Pobieramy bounding box (pozycję słowa na stronie)
page_text = page.extract_text()
if page_text:
full_text.append(page_text.lower())
full_text = "\n".join(full_text) # Łączymy cały tekst dokumentu
# Tokenizacja tekstu + dodanie bounding boxes
encoding = tokenizer.encode_plus(words, boxes=boxes, return_tensors="pt", truncation=True)
# Predykcja modelu
with torch.no_grad():
outputs = model(**encoding)
predictions = outputs.logits.argmax(-1).squeeze().tolist()
# Przetwarzanie wyników
entities = []
for token, pred in zip(words, predictions):
if pred > 0: # Pomijamy tło
entities.append((token, model.config.id2label[pred]))
# 🏢 Wyszukiwanie nazwy sprzedawcy
seller_name = [token for token, label in entities if "ORG" in label]
# Jeśli model nie znalazł, szukamy w tekście
if not seller_name:
for line in full_text.split("\n"):
if any(keyword in line for keyword in seller_keywords):
seller_name = line.split(":")[-1].strip()
break
# 🔢 Wyszukiwanie NIP
seller_nip = nip_pattern.search(full_text)
# 💰 Wyszukiwanie kwoty całkowitej (największa kwota z walutą)
kwoty = kwota_pattern.findall(full_text)
kwoty = [k[0].replace(",", ".") for k in kwoty if k[0].replace(",", ".").replace(".", "").isdigit()]
total_amount = max(map(float, kwoty), default=None) if kwoty else None
# 📆 Wyszukiwanie daty płatności
payment_date = None
for line in full_text.split("\n"):
if any(keyword in line for keyword in payment_keywords):
date_match = data_pattern.search(line)
if date_match:
payment_date = date_match.group()
break
return {
"Sprzedawca": " ".join(seller_name) if seller_name else "Nie znaleziono",
"NIP": seller_nip.group() if seller_nip else "Nie znaleziono",
"Kwota całkowita": total_amount if total_amount else "Nie znaleziono",
"Data płatności": payment_date if payment_date else "Nie znaleziono"
}
# Interfejs użytkownika
iface = gr.Interface(
fn=extract_invoice_data,
inputs=gr.File(label="Wybierz plik PDF"),
outputs="json",
title="Ekstrakcja danych z faktury",
description="Prześlij plik PDF, a model zwróci dane sprzedawcy, NIP, kwotę i datę płatności."
)
if __name__ == "__main__":
iface.launch()
|