für ein Skript zur Erkennung von Handschrift und automatischem Ubenennen einer PDF-Datei habe ich mir mit ChatGPT ein bisschen was zusammengebastelt.
Im Grunde funktioniert das Skript, aber ich bin leider nicht in der Lage, weitere Anpassungen vorzunehmen. Meine Programmierkenntnisse streben nämlich leider gegen Null.
Meine Idee ist, dass sich ein GUI mit Drag&Drop Unterstütung (Tkinter mit TkinterDnD) öffnet, ich mehrere PDF-Dateien droppen kann, welche dann nacheinander das Skript durchlaufen.
Im Skript sollen dann folgende Schritte abgearbeitet werden:
1. Eine einseitige PDF-Datei soll geladen und in eine PNG-Datei konvertiert werden, die den gleichen Namen und den gleichen Pfad besitzt, wie die geladene PDF-Datei. Zum Konvertieren soll pdf2image genutzt werden und die konvertierte PNG-Datei soll schwarz-weiß sein.
2. Die erstellte PNG-Datei soll mit Hilfe der Google Vision API auf Text und Handschrift untersucht werden (die JSON-Datei zur Authentifizierung gebe ich direkt im Skript an).
3. Der erkannte Text soll mit bestimmten Keywords aus einer separaten keywords.txt verglichen werden und gefundene Übereinstimmungen ausgegeben werden. Die keywords.txt-Datei befindet sich im gleichen Ordner wie das Skript. Außerdem sollen Daten extrahiert werden in verschiedenen Formaten (z.B. 10.08.2023, 10.8.2023, 10.08.23 etc.).
4. Wenn es Übereinstimmungen gibt, sollen diese mit dem Inhalt einer Datenbank im CSV-Format (daten.csv) abgeglichen werden. Die Datenbank beinhaltet die Keywords, Vorname, Nachname und Personalnummer
5. Die PNG-Datei soll umbenannt werden und den Dateinamen im Format „Nachname, Vorname.PNG“ erhalten. Nachname und Vorname werden aus der daten.csv entnommen
6. Anschließend soll die Datei in eine PDF-Datei konvertiert werden. Der Name soll von der PNG-Datei übernommen werden
7. Die erstellte PNG-Datei soll nach der Konvertierung wieder gelöscht werden. Ebenso die ursprüngliche PDF-Datei, so dass nur die neue PDF-Datei mir dem Namen "Nachname, Vorname.pdf" existiert.
Den Schritt von PDF-->PNG-->PDF gehe ich, da Google Vision nur Schrift in Bildern erkennt.
Ich hänge hier gerne mal ein Skript an, welches soweit funktioniert, aber nicht alle meine Bedingungen erfüllt (z.B. kein Drag&Drop und keine automatische Verarbeitung mehrer Dateien nacheinander):
Code: Alles auswählen
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
from google.cloud import vision
from pdf2image import convert_from_path
import os
import re
import csv
# Setzen Sie hier den Pfad zu Ihrer JSON-Anmeldeinformation ein
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "C:/Users/***/Desktop/HTR/GoogleCloudVision.json"
# Pfad zur Textdatei mit den Schlagwörtern
schlagwoerter_datei = "C:/Users/***/Desktop/HTR/keywords.txt"
# Pfad zur CSV-Datei mit den Datensätzen
datensatz_datei = "C:/Users/***/Desktop/HTR/daten.csv"
# Definieren Sie hier die Koordinaten für den begrenzten Bereich
x1, y1, x2, y2 = 0, 1000, 1654, 1500
# Erstellen Sie hier eine globale Variable für image_label
image_label = None
# Erstellen Sie hier eine globale Variable für result_text
result_text = None
def load_keywords():
with open(schlagwoerter_datei, "r") as f:
keywords = f.read().splitlines()
return keywords
def extract_dates(text):
date_pattern = r"\b(?:\d{1,2}\.\d{1,2}\.\d{2,4}|d{1,2}\.d{1,2}\.\d{2,4}|\d{1,2}\.\d{1,2}\.\d{2,4}|\d{1,2}\.\d{1,2}\.\d{2,4})\b"
dates = re.findall(date_pattern, text)
return dates
def load_dataset():
dataset = {}
with open(datensatz_datei, "r", newline="") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
keywords = row["Keyword"].split(",")
dataset_keywords = [keyword.strip() for keyword in keywords]
dataset[tuple(dataset_keywords)] = {
"vorname": row["Vorname"],
"nachname": row["Nachname"],
"personalnummer": row["Personalnummer"]
}
return dataset
def rename_image(image_path, dataset):
extracted_text = detect_handwritten_text(image_path)
keywords = load_keywords()
found_keywords = [keyword for keyword in keywords if keyword.lower() in extracted_text.lower()]
extracted_dates = extract_dates(extracted_text)
for keywords_tuple, data in dataset.items():
if all(keyword.lower() in extracted_text.lower() for keyword in keywords_tuple):
new_basename = f"{data['nachname']}, {data['vorname']}.png"
dirname, _ = os.path.split(image_path)
new_path = os.path.join(dirname, new_basename)
os.rename(image_path, new_path)
return new_path
return None
def detect_handwritten_text(image_path):
client = vision.ImageAnnotatorClient()
with open(image_path, 'rb') as image_file:
content = image_file.read()
image = vision.Image(content=content)
response = client.document_text_detection(image=image)
texts = []
for page in response.full_text_annotation.pages:
for block in page.blocks:
for paragraph in block.paragraphs:
for word in paragraph.words:
word_text = ''.join(symbol.text for symbol in word.symbols)
texts.append(word_text)
return ' '.join(texts)
def open_image():
global image_label
global result_text
file_path = filedialog.askopenfilename()
if file_path:
# Check if the file is a PDF and convert it if necessary
if file_path.lower().endswith('.pdf'):
pdf_images = convert_from_path(file_path)
if pdf_images:
pdf_image = pdf_images[0]
pdf_image_path = "C:/Users/RGoebel/Desktop/Scan/temporary_image.png"
pdf_image.save(pdf_image_path, 'PNG')
original_file_path = file_path
file_path = pdf_image_path
img = Image.open(file_path)
img_cropped = img.crop((x1, y1, x2, y2))
img_cropped.thumbnail((300, 300))
img_tk = ImageTk.PhotoImage(img_cropped)
image_label.config(image=img_tk)
image_label.image = img_tk
extracted_text = detect_handwritten_text(file_path)
keywords = load_keywords()
found_keywords = [keyword for keyword in keywords if keyword.lower() in extracted_text.lower()]
extracted_dates = extract_dates(extracted_text)
dataset = load_dataset()
new_image_path = rename_image(file_path, dataset)
result_text.delete("1.0", tk.END)
result_text.insert(tk.END, "Found Keywords:\n" + ", ".join(found_keywords))
result_text.insert(tk.END, "\n\nExtracted Dates:\n" + ", ".join(extracted_dates))
if new_image_path:
result_text.insert(tk.END, f"\n\nImage Renamed to:\n{new_image_path}")
else:
result_text.insert(tk.END, "\n\nMatching entry not found in dataset.")
#result_text.insert(tk.END, "\n\nExtracted Text:\n" + "".join(extracted_text))
# Convert the newly created PNG image to PDF
if new_image_path and new_image_path.lower().endswith('.png'):
pdf_path = new_image_path.replace('.png', '.pdf')
img = Image.open(new_image_path)
img.save(pdf_path, 'PDF', resolution=100.0, save_all=True)
result_text.insert(tk.END, f"\n\nPNG Image Converted to PDF:\n{pdf_path}")
# Remove the PNG file
os.remove(new_image_path)
result_text.insert(tk.END, f"\n\nPNG Image Deleted:\n{new_image_path}")
os.remove(original_file_path)
result_text.insert(tk.END, f"\n\nOriginal Input File Deleted:\n{original_file_path}")
def main():
global image_label # Zugriff auf die globale Variable image_label
global result_text # Zugriff auf die globale Variable result_text
root = tk.Tk()
root.title("HTR to rename")
image_label = tk.Label(root)
image_label.pack(pady=10)
load_button = tk.Button(root, text="Load File", command=open_image)
load_button.pack(pady=5)
result_text = tk.Text(root, height=15, width=50)
result_text.pack(padx=10, pady=10)
root.mainloop()
if __name__ == "__main__":
main()
Der begrenzte Bereich wurde ursprünglich angegeben, um die Handschrifterkennung auf eben diesen Bereich zu beschränken. Aber Google Cloud Vision bearbeitet anscheinend immer das gesamte Bild.
Vielleicht ist ja jemand bereit mal über den Code zu schauen und mir ein paar detaillierte Tipps zu geben

Liebe Grüße
Fisatec